Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6 into fbdev-next
diff --git a/MAINTAINERS b/MAINTAINERS
index 55ca0be..609b12b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -269,7 +269,6 @@
 F:	drivers/platform/x86/wmi.c
 
 AD1889 ALSA SOUND DRIVER
-M:	Kyle McMartin <kyle@mcmartin.ca>
 M:	Thibaut Varene <T-Bone@parisc-linux.org>
 W:	http://wiki.parisc-linux.org/AD1889
 L:	linux-parisc@vger.kernel.org
@@ -2231,6 +2230,15 @@
 F:	fs/quota/
 F:	include/linux/quota*.h
 
+DISPLAYLINK USB 2.0 FRAMEBUFFER DRIVER (UDLFB)
+M:	Bernie Thompson <bernie@plugable.com>
+L:	linux-fbdev@vger.kernel.org
+S:	Maintained
+W:	http://plugable.com/category/projects/udlfb/
+F:	drivers/video/udlfb.c
+F:	include/video/udlfb.h
+F:	Documentation/fb/udlfb.txt
+
 DISTRIBUTED LOCK MANAGER (DLM)
 M:	Christine Caulfield <ccaulfie@redhat.com>
 M:	David Teigland <teigland@redhat.com>
@@ -2632,6 +2640,21 @@
 S:	Supported
 F:	security/integrity/evm/
 
+EXYNOS DP DRIVER
+M:	Jingoo Han <jg1.han@samsung.com>
+L:	linux-fbdev@vger.kernel.org
+S:	Maintained
+F:	drivers/video/exynos/exynos_dp*
+
+EXYNOS MIPI DISPLAY DRIVERS
+M:	Inki Dae <inki.dae@samsung.com>
+M:	Donghwa Lee <dh09.lee@samsung.com>
+M:	Kyungmin Park <kyungmin.park@samsung.com>
+L:	linux-fbdev@vger.kernel.org
+S:	Maintained
+F:	drivers/video/exynos/exynos_mipi*
+F:	include/video/exynos_mipi*
+
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <khali@linux-fr.org>
 L:	lm-sensors@lm-sensors.org
@@ -3047,7 +3070,6 @@
 F:	include/linux/hwspinlock.h
 
 HARMONY SOUND DRIVER
-M:	Kyle McMartin <kyle@mcmartin.ca>
 L:	linux-parisc@vger.kernel.org
 S:	Maintained
 F:	sound/parisc/harmony.*
@@ -3318,6 +3340,12 @@
 F:	net/ieee802154/
 F:	drivers/ieee802154/
 
+IIO SUBSYSTEM AND DRIVERS
+M:	Jonathan Cameron <jic23@cam.ac.uk>
+L:	linux-iio@vger.kernel.org
+S:	Maintained
+F:	drivers/staging/iio/
+
 IKANOS/ADI EAGLE ADSL USB DRIVER
 M:	Matthieu Castet <castet.matthieu@free.fr>
 M:	Stanislaw Gruszka <stf_xl@wp.pl>
@@ -3776,7 +3804,7 @@
 
 KERNEL AUTOMOUNTER v4 (AUTOFS4)
 M:	Ian Kent <raven@themaw.net>
-L:	autofs@linux.kernel.org
+L:	autofs@vger.kernel.org
 S:	Maintained
 F:	fs/autofs4/
 
@@ -4681,7 +4709,7 @@
 M:	Anton Altaparmakov <anton@tuxera.com>
 L:	linux-ntfs-dev@lists.sourceforge.net
 W:	http://www.tuxera.com/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs.git
 S:	Supported
 F:	Documentation/filesystems/ntfs.txt
 F:	fs/ntfs/
@@ -4994,9 +5022,8 @@
 F:	drivers/block/paride/
 
 PARISC ARCHITECTURE
-M:	Kyle McMartin <kyle@mcmartin.ca>
-M:	Helge Deller <deller@gmx.de>
 M:	"James E.J. Bottomley" <jejb@parisc-linux.org>
+M:	Helge Deller <deller@gmx.de>
 L:	linux-parisc@vger.kernel.org
 W:	http://www.parisc-linux.org/
 Q:	http://patchwork.kernel.org/project/linux-parisc/list/
@@ -5855,7 +5882,7 @@
 F:	drivers/mmc/host/sdhci-spear.c
 
 SECURITY SUBSYSTEM
-M:	James Morris <jmorris@namei.org>
+M:	James Morris <james.l.morris@oracle.com>
 L:	linux-security-module@vger.kernel.org (suggested Cc:)
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git
 W:	http://security.wiki.kernel.org/
@@ -5868,7 +5895,7 @@
 
 SELINUX SECURITY MODULE
 M:	Stephen Smalley <sds@tycho.nsa.gov>
-M:	James Morris <jmorris@namei.org>
+M:	James Morris <james.l.morris@oracle.com>
 M:	Eric Paris <eparis@parisplace.org>
 L:	selinux@tycho.nsa.gov (subscribers-only, general discussion)
 W:	http://selinuxproject.org
@@ -7268,7 +7295,7 @@
 M:	Wim Van Sebroeck <wim@iguana.be>
 L:	linux-watchdog@vger.kernel.org
 W:	http://www.linux-watchdog.org/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git
+T:	git git://www.linux-watchdog.org/linux-watchdog.git
 S:	Maintained
 F:	Documentation/watchdog/
 F:	drivers/watchdog/
diff --git a/Makefile b/Makefile
index 7c44b67..66d13c9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 3
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc6
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 63d7578..a1dd2ee 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -29,6 +29,7 @@
 		compatible = "arm,cortex-a9-gic";
 		#interrupt-cells = <3>;
 		interrupt-controller;
+		cpu-offset = <0x8000>;
 		reg = <0x10490000 0x1000>, <0x10480000 0x100>;
 	};
 
diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts
index 1a1d702..825d295 100644
--- a/arch/arm/boot/dts/tegra-paz00.dts
+++ b/arch/arm/boot/dts/tegra-paz00.dts
@@ -46,11 +46,11 @@
 	};
 
 	serial@70006200 {
-		status = "disable";
+		clock-frequency = <216000000>;
 	};
 
 	serial@70006300 {
-		clock-frequency = <216000000>;
+		status = "disable";
 	};
 
 	serial@70006400 {
@@ -60,7 +60,7 @@
 	sdhci@c8000000 {
 		cd-gpios = <&gpio 173 0>; /* gpio PV5 */
 		wp-gpios = <&gpio 57 0>;  /* gpio PH1 */
-		power-gpios = <&gpio 155 0>; /* gpio PT3 */
+		power-gpios = <&gpio 169 0>; /* gpio PV1 */
 	};
 
 	sdhci@c8000200 {
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index d1bcd7b..fb1f1cf 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -320,13 +320,6 @@
 	return -EBUSY;
 }
 
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as we don't have even crappy BIOSes to set it properly.
- * The implementation is from arch/i386/pci/i386.c
- */
-unsigned int pcibios_max_latency = 255;
-
 /* ITE bridge requires setting latency timer to avoid early bus access
    termination by PCI bus master devices
 */
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
index d8e44a4..ff3ad22 100644
--- a/arch/arm/common/pl330.c
+++ b/arch/arm/common/pl330.c
@@ -1502,12 +1502,13 @@
 	struct pl330_thread *thrd = ch_id;
 	struct pl330_dmac *pl330;
 	unsigned long flags;
-	int ret = 0, active = thrd->req_running;
+	int ret = 0, active;
 
 	if (!thrd || thrd->free || thrd->dmac->state == DYING)
 		return -EINVAL;
 
 	pl330 = thrd->dmac;
+	active = thrd->req_running;
 
 	spin_lock_irqsave(&pl330->lock, flags);
 
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 62f8095..23371b1 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -137,6 +137,11 @@
 	disable_irq
 	.endm
 
+	.macro	save_and_disable_irqs_notrace, oldcpsr
+	mrs	\oldcpsr, cpsr
+	disable_irq_notrace
+	.endm
+
 /*
  * Restore interrupt state previously stored in a register.  We don't
  * guarantee that this will preserve the flags.
diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h
index 575fa81..c182138 100644
--- a/arch/arm/include/asm/hardware/pl330.h
+++ b/arch/arm/include/asm/hardware/pl330.h
@@ -41,7 +41,7 @@
 	DCCTRL1, /* Bufferable only */
 	DCCTRL2, /* Cacheable, but do not allocate */
 	DCCTRL3, /* Cacheable and bufferable, but do not allocate */
-	DINVALID1 = 8,
+	DINVALID1,              /* AWCACHE = 0x1000 */
 	DINVALID2,
 	DCCTRL6, /* Cacheable write-through, allocate on writes only */
 	DCCTRL7, /* Cacheable write-back, allocate on writes only */
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index ce280b8..cb8d638 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -22,6 +22,7 @@
 #include <asm/hw_breakpoint.h>
 #include <asm/ptrace.h>
 #include <asm/types.h>
+#include <asm/system.h>
 
 #ifdef __KERNEL__
 #define STACK_TOP	((current->personality & ADDR_LIMIT_32BIT) ? \
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index e33870f..ede6443 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -23,6 +23,7 @@
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/regset.h>
+#include <linux/audit.h>
 
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -904,6 +905,12 @@
 	return ret;
 }
 
+#ifdef __ARMEB__
+#define AUDIT_ARCH_NR AUDIT_ARCH_ARMEB
+#else
+#define AUDIT_ARCH_NR AUDIT_ARCH_ARM
+#endif
+
 asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
 {
 	unsigned long ip;
@@ -918,7 +925,7 @@
 	if (!ip)
 		audit_syscall_exit(regs);
 	else
-		audit_syscall_entry(AUDIT_ARCH_ARMEB, scno, regs->ARM_r0,
+		audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0,
 				    regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
 
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 4285daa..7a79b24 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -129,7 +129,7 @@
 
 static int twd_cpufreq_init(void)
 {
-	if (!IS_ERR(twd_clk))
+	if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
 		return cpufreq_register_notifier(&twd_cpufreq_nb,
 			CPUFREQ_TRANSITION_NOTIFIER);
 
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 99a5727..f84dfe6 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -266,6 +266,7 @@
 {
 	struct thread_info *thread = current_thread_info();
 	int ret;
+	enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE;
 
 	oops_enter();
 
@@ -273,7 +274,9 @@
 	console_verbose();
 	bust_spinlocks(1);
 	if (!user_mode(regs))
-		report_bug(regs->ARM_pc, regs);
+		bug_type = report_bug(regs->ARM_pc, regs);
+	if (bug_type != BUG_TRAP_TYPE_NONE)
+		str = "Oops - BUG";
 	ret = __die(str, err, thread, regs);
 
 	if (regs && kexec_should_crash(thread->task))
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 1e19691..43a31fb 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -10,6 +10,7 @@
 #include <asm/page.h>
 	
 #define PROC_INFO							\
+	. = ALIGN(4);							\
 	VMLINUX_SYMBOL(__proc_info_begin) = .;				\
 	*(.proc.info.init)						\
 	VMLINUX_SYMBOL(__proc_info_end) = .;
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 18bacec..97676bd 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -83,7 +83,7 @@
  *  USB Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#ifdef CONFIG_USB_AT91
+#if defined(CONFIG_USB_AT91) || defined(CONFIG_USB_AT91_MODULE)
 static struct at91_udc_data udc_data;
 
 static struct resource udc_resources[] = {
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 642ccb6..5a24f0b 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -84,7 +84,7 @@
  *  USB Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#ifdef CONFIG_USB_AT91
+#if defined(CONFIG_USB_AT91) || defined(CONFIG_USB_AT91_MODULE)
 static struct at91_udc_data udc_data;
 
 static struct resource udc_resources[] = {
@@ -1215,8 +1215,7 @@
  *  CF/IDE
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \
-	defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \
+#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \
 	defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
 
 static struct at91_cf_data cf0_data;
@@ -1313,10 +1312,8 @@
 	if (data->flags & AT91_CF_TRUE_IDE)
 #if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE)
 		pdev->name = "pata_at91";
-#elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
-		pdev->name = "at91_ide";
 #else
-#warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91"
+#warning "board requires AT91_CF_TRUE_IDE: enable pata_at91"
 #endif
 	else
 		pdev->name = "at91_cf";
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index fc59cbd..1e28bed 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -87,7 +87,7 @@
  *  USB Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#ifdef CONFIG_USB_AT91
+#if defined(CONFIG_USB_AT91) || defined(CONFIG_USB_AT91_MODULE)
 static struct at91_udc_data udc_data;
 
 static struct resource udc_resources[] = {
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 7b46b27..366a776 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -92,7 +92,7 @@
  *  USB Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#ifdef CONFIG_USB_AT91
+#if defined(CONFIG_USB_AT91) || defined(CONFIG_USB_AT91_MODULE)
 static struct at91_udc_data udc_data;
 
 static struct resource udc_resources[] = {
@@ -355,8 +355,8 @@
  *  Compact Flash (PCMCIA or IDE)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \
-    defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
+#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \
+	defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
 
 static struct at91_cf_data cf0_data;
 
@@ -450,7 +450,7 @@
 	at91_set_A_periph(AT91_PIN_PD9, 0);  /* CFCE2 */
 	at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */
 
-	pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf";
+	pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "pata_at91" : "at91_cf";
 	platform_device_register(pdev);
 }
 #else
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
index eb18a70..175e1fd 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_smc.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
@@ -18,6 +18,35 @@
 
 #include <mach/cpu.h>
 
+#ifndef __ASSEMBLY__
+struct sam9_smc_config {
+	/* Setup register */
+	u8 ncs_read_setup;
+	u8 nrd_setup;
+	u8 ncs_write_setup;
+	u8 nwe_setup;
+
+	/* Pulse register */
+	u8 ncs_read_pulse;
+	u8 nrd_pulse;
+	u8 ncs_write_pulse;
+	u8 nwe_pulse;
+
+	/* Cycle register */
+	u16 read_cycle;
+	u16 write_cycle;
+
+	/* Mode register */
+	u32 mode;
+	u8 tdf_cycles:4;
+};
+
+extern void sam9_smc_configure(int id, int cs, struct sam9_smc_config *config);
+extern void sam9_smc_read(int id, int cs, struct sam9_smc_config *config);
+extern void sam9_smc_read_mode(int id, int cs, struct sam9_smc_config *config);
+extern void sam9_smc_write_mode(int id, int cs, struct sam9_smc_config *config);
+#endif
+
 #define AT91_SMC_SETUP		0x00				/* Setup Register for CS n */
 #define		AT91_SMC_NWESETUP	(0x3f << 0)			/* NWE Setup Length */
 #define			AT91_SMC_NWESETUP_(x)	((x) << 0)
diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c
index 8294783..99a0a1d 100644
--- a/arch/arm/mach-at91/sam9_smc.c
+++ b/arch/arm/mach-at91/sam9_smc.c
@@ -2,6 +2,7 @@
  * linux/arch/arm/mach-at91/sam9_smc.c
  *
  * Copyright (C) 2008 Andrew Victor
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
  *
  * 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
@@ -22,7 +23,22 @@
 
 static void __iomem *smc_base_addr[2];
 
-static void __init sam9_smc_cs_configure(void __iomem *base, struct sam9_smc_config* config)
+static void sam9_smc_cs_write_mode(void __iomem *base,
+					struct sam9_smc_config *config)
+{
+	__raw_writel(config->mode
+		   | AT91_SMC_TDF_(config->tdf_cycles),
+		   base + AT91_SMC_MODE);
+}
+
+void sam9_smc_write_mode(int id, int cs,
+					struct sam9_smc_config *config)
+{
+	sam9_smc_cs_write_mode(AT91_SMC_CS(id, cs), config);
+}
+
+static void sam9_smc_cs_configure(void __iomem *base,
+					struct sam9_smc_config *config)
 {
 
 	/* Setup register */
@@ -45,16 +61,66 @@
 		   base + AT91_SMC_CYCLE);
 
 	/* Mode register */
-	__raw_writel(config->mode
-		   | AT91_SMC_TDF_(config->tdf_cycles),
-		   base + AT91_SMC_MODE);
+	sam9_smc_cs_write_mode(base, config);
 }
 
-void __init sam9_smc_configure(int id, int cs, struct sam9_smc_config* config)
+void sam9_smc_configure(int id, int cs,
+					struct sam9_smc_config *config)
 {
 	sam9_smc_cs_configure(AT91_SMC_CS(id, cs), config);
 }
 
+static void sam9_smc_cs_read_mode(void __iomem *base,
+					struct sam9_smc_config *config)
+{
+	u32 val = __raw_readl(base + AT91_SMC_MODE);
+
+	config->mode = (val & ~AT91_SMC_NWECYCLE);
+	config->tdf_cycles = (val & AT91_SMC_NWECYCLE) >> 16 ;
+}
+
+void sam9_smc_read_mode(int id, int cs,
+					struct sam9_smc_config *config)
+{
+	sam9_smc_cs_read_mode(AT91_SMC_CS(id, cs), config);
+}
+
+static void sam9_smc_cs_read(void __iomem *base,
+					struct sam9_smc_config *config)
+{
+	u32 val;
+
+	/* Setup register */
+	val = __raw_readl(base + AT91_SMC_SETUP);
+
+	config->nwe_setup = val & AT91_SMC_NWESETUP;
+	config->ncs_write_setup = (val & AT91_SMC_NCS_WRSETUP) >> 8;
+	config->nrd_setup = (val & AT91_SMC_NRDSETUP) >> 16;
+	config->ncs_read_setup = (val & AT91_SMC_NCS_RDSETUP) >> 24;
+
+	/* Pulse register */
+	val = __raw_readl(base + AT91_SMC_PULSE);
+
+	config->nwe_setup = val & AT91_SMC_NWEPULSE;
+	config->ncs_write_pulse = (val & AT91_SMC_NCS_WRPULSE) >> 8;
+	config->nrd_pulse = (val & AT91_SMC_NRDPULSE) >> 16;
+	config->ncs_read_pulse = (val & AT91_SMC_NCS_RDPULSE) >> 24;
+
+	/* Cycle register */
+	val = __raw_readl(base + AT91_SMC_CYCLE);
+
+	config->write_cycle = val & AT91_SMC_NWECYCLE;
+	config->read_cycle = (val & AT91_SMC_NRDCYCLE) >> 16;
+
+	/* Mode register */
+	sam9_smc_cs_read_mode(base, config);
+}
+
+void sam9_smc_read(int id, int cs, struct sam9_smc_config *config)
+{
+	sam9_smc_cs_read(AT91_SMC_CS(id, cs), config);
+}
+
 void __init at91sam9_ioremap_smc(int id, u32 addr)
 {
 	if (id > 1) {
diff --git a/arch/arm/mach-at91/sam9_smc.h b/arch/arm/mach-at91/sam9_smc.h
index 039c5ce..3e52dcd4 100644
--- a/arch/arm/mach-at91/sam9_smc.h
+++ b/arch/arm/mach-at91/sam9_smc.h
@@ -8,27 +8,4 @@
  * published by the Free Software Foundation.
  */
 
-struct sam9_smc_config {
-	/* Setup register */
-	u8 ncs_read_setup;
-	u8 nrd_setup;
-	u8 ncs_write_setup;
-	u8 nwe_setup;
-
-	/* Pulse register */
-	u8 ncs_read_pulse;
-	u8 nrd_pulse;
-	u8 ncs_write_pulse;
-	u8 nwe_pulse;
-
-	/* Cycle register */
-	u16 read_cycle;
-	u16 write_cycle;
-
-	/* Mode register */
-	u32 mode;
-	u8 tdf_cycles:4;
-};
-
-extern void __init sam9_smc_configure(int id, int cs, struct sam9_smc_config* config);
 extern void __init at91sam9_ioremap_smc(int id, u32 addr);
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index dd1429a..bda7aca 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -28,6 +28,7 @@
 #include <asm/mach/arch.h>
 #include <linux/irq.h>
 #include <plat/time.h>
+#include <plat/ehci-orion.h>
 #include <plat/common.h>
 #include <plat/addr-map.h>
 #include "common.h"
@@ -71,7 +72,7 @@
  ****************************************************************************/
 void __init dove_ehci0_init(void)
 {
-	orion_ehci_init(DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0);
+	orion_ehci_init(DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0, EHCI_PHY_NA);
 }
 
 /*****************************************************************************
diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c
index 03dd401..d5fb44f 100644
--- a/arch/arm/mach-ep93xx/vision_ep9307.c
+++ b/arch/arm/mach-ep93xx/vision_ep9307.c
@@ -32,6 +32,7 @@
 #include <mach/hardware.h>
 #include <mach/fb.h>
 #include <mach/ep93xx_spi.h>
+#include <mach/gpio-ep93xx.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
@@ -153,7 +154,6 @@
 	}, {
 		I2C_BOARD_INFO("pca9539", 0x74),
 		.platform_data	= &pca953x_74_gpio_data,
-		.irq		= gpio_to_irq(EP93XX_GPIO_LINE_F(7)),
 	}, {
 		I2C_BOARD_INFO("pca9539", 0x75),
 		.platform_data	= &pca953x_75_gpio_data,
@@ -348,6 +348,8 @@
 				"pca9539:74"))
 		pr_warn("cannot request interrupt gpio for pca9539:74\n");
 
+	vision_i2c_info[1].irq = gpio_to_irq(EP93XX_GPIO_LINE_F(7));
+
 	ep93xx_register_i2c(&vision_i2c_gpio_data, vision_i2c_info,
 				ARRAY_SIZE(vision_i2c_info));
 	ep93xx_register_spi(&vision_spi_master, vision_spi_board_info,
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
index a5823a7..13312cc 100644
--- a/arch/arm/mach-exynos/clock-exynos4210.c
+++ b/arch/arm/mach-exynos/clock-exynos4210.c
@@ -32,6 +32,7 @@
 
 #include "common.h"
 
+#ifdef CONFIG_PM_SLEEP
 static struct sleep_save exynos4210_clock_save[] = {
 	SAVE_ITEM(S5P_CLKSRC_IMAGE),
 	SAVE_ITEM(S5P_CLKSRC_LCD1),
@@ -42,6 +43,7 @@
 	SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
 	SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4210),
 };
+#endif
 
 static struct clksrc_clk *sysclks[] = {
 	/* nothing here yet */
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
index 26a668b..48af285 100644
--- a/arch/arm/mach-exynos/clock-exynos4212.c
+++ b/arch/arm/mach-exynos/clock-exynos4212.c
@@ -32,12 +32,14 @@
 
 #include "common.h"
 
+#ifdef CONFIG_PM_SLEEP
 static struct sleep_save exynos4212_clock_save[] = {
 	SAVE_ITEM(S5P_CLKSRC_IMAGE),
 	SAVE_ITEM(S5P_CLKDIV_IMAGE),
 	SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4212),
 	SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4212),
 };
+#endif
 
 static struct clk *clk_src_mpll_user_list[] = {
 	[0] = &clk_fin_mpll,
diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c
index 5a8c42e..187287a 100644
--- a/arch/arm/mach-exynos/clock.c
+++ b/arch/arm/mach-exynos/clock.c
@@ -30,6 +30,7 @@
 
 #include "common.h"
 
+#ifdef CONFIG_PM_SLEEP
 static struct sleep_save exynos4_clock_save[] = {
 	SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
 	SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
@@ -93,6 +94,7 @@
 	SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
 	SAVE_ITEM(S5P_CLKGATE_IP_CPU),
 };
+#endif
 
 struct clk clk_sclk_hdmi27m = {
 	.name		= "sclk_hdmi27m",
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 85fa027..e6b02fd 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -15,11 +15,13 @@
 #include <linux/serial_core.h>
 
 #include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
 #include <mach/map.h>
 
 #include <plat/cpu.h>
 #include <plat/regs-serial.h>
-#include <plat/exynos4.h>
+
+#include "common.h"
 
 /*
  * The following lookup table is used to override device names when devices
@@ -60,7 +62,7 @@
 
 static void __init exynos4210_dt_map_io(void)
 {
-	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+	exynos_init_io(NULL, 0);
 	s3c24xx_init_clocks(24000000);
 }
 
@@ -79,7 +81,9 @@
 	/* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
 	.init_irq	= exynos4_init_irq,
 	.map_io		= exynos4210_dt_map_io,
+	.handle_irq	= gic_handle_irq,
 	.init_machine	= exynos4210_dt_machine_init,
 	.timer		= &exynos4_timer,
 	.dt_compat	= exynos4210_dt_compat,
+	.restart        = exynos4_restart,
 MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index b895ec0..435261f 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -220,14 +220,14 @@
 		.lower_margin	= 1,
 		.hsync_len	= 48,
 		.vsync_len	= 3,
-		.xres		= 1280,
-		.yres		= 800,
+		.xres		= 1024,
+		.yres		= 600,
 		.refresh	= 60,
 	},
 	.max_bpp	= 24,
 	.default_bpp	= 16,
-	.virtual_x	= 1280,
-	.virtual_y	= 800,
+	.virtual_x	= 1024,
+	.virtual_y	= 2 * 600,
 };
 
 static struct s3c_fb_platdata nuri_fb_pdata __initdata = {
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 37ac93e..0fc65ff 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -910,7 +910,7 @@
 		.bus_type	= FIMC_MIPI_CSI2,
 		.board_info	= &m5mols_board_info,
 		.i2c_bus_num	= 0,
-		.clk_frequency	= 21600000UL,
+		.clk_frequency	= 24000000UL,
 		.csi_data_align	= 32,
 	},
 };
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index a4f61a4..e190130 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -206,7 +206,7 @@
 
 }
 
-static int exynos4_pm_add(struct device *dev)
+static int exynos4_pm_add(struct device *dev, struct subsys_interface *sif)
 {
 	pm_cpu_prep = exynos4_pm_prepare;
 	pm_cpu_sleep = exynos4_cpu_suspend;
@@ -384,7 +384,9 @@
 
 	exynos4_restore_pll();
 
+#ifdef CONFIG_SMP
 	scu_enable(S5P_VA_SCU);
+#endif
 
 #ifdef CONFIG_CACHE_L2X0
 	s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index cc15426..77d4852 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -27,6 +27,7 @@
 #include <plat/cache-feroceon-l2.h>
 #include <plat/mvsdio.h>
 #include <plat/orion_nand.h>
+#include <plat/ehci-orion.h>
 #include <plat/common.h>
 #include <plat/time.h>
 #include <plat/addr-map.h>
@@ -73,7 +74,7 @@
 void __init kirkwood_ehci_init(void)
 {
 	kirkwood_clk_ctrl |= CGC_USB0;
-	orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB);
+	orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA);
 }
 
 
diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h
index e8fda45..d5a0d1d 100644
--- a/arch/arm/mach-kirkwood/mpp.h
+++ b/arch/arm/mach-kirkwood/mpp.h
@@ -31,314 +31,314 @@
 #define MPP_F6282_MASK		MPP(  0, 0x0, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP0_GPIO		MPP(  0, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP0_NF_IO2		MPP(  0, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP0_SPI_SCn		MPP(  0, 0x2, 0, 1, 1,   1,   1,   1,   1 )
+#define MPP0_NF_IO2		MPP(  0, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP0_SPI_SCn		MPP(  0, 0x2, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP1_GPO		MPP(  1, 0x0, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP1_NF_IO3		MPP(  1, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP1_SPI_MOSI		MPP(  1, 0x2, 0, 1, 1,   1,   1,   1,   1 )
+#define MPP1_NF_IO3		MPP(  1, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP1_SPI_MOSI		MPP(  1, 0x2, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP2_GPO		MPP(  2, 0x0, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP2_NF_IO4		MPP(  2, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP2_SPI_SCK		MPP(  2, 0x2, 0, 1, 1,   1,   1,   1,   1 )
+#define MPP2_NF_IO4		MPP(  2, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP2_SPI_SCK		MPP(  2, 0x2, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP3_GPO		MPP(  3, 0x0, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP3_NF_IO5		MPP(  3, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP3_SPI_MISO		MPP(  3, 0x2, 1, 0, 1,   1,   1,   1,   1 )
+#define MPP3_NF_IO5		MPP(  3, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP3_SPI_MISO		MPP(  3, 0x2, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP4_GPIO		MPP(  4, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP4_NF_IO6		MPP(  4, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP4_UART0_RXD		MPP(  4, 0x2, 1, 0, 1,   1,   1,   1,   1 )
-#define MPP4_SATA1_ACTn		MPP(  4, 0x5, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP4_NF_IO6		MPP(  4, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP4_UART0_RXD		MPP(  4, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP4_SATA1_ACTn		MPP(  4, 0x5, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP4_LCD_VGA_HSYNC	MPP(  4, 0xb, 0, 0, 0,   0,   0,   0,   1 )
-#define MPP4_PTP_CLK		MPP(  4, 0xd, 1, 0, 1,   1,   1,   1,   0 )
+#define MPP4_PTP_CLK		MPP(  4, 0xd, 0, 0, 1,   1,   1,   1,   0 )
 
 #define MPP5_GPO		MPP(  5, 0x0, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP5_NF_IO7		MPP(  5, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP5_UART0_TXD		MPP(  5, 0x2, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP5_PTP_TRIG_GEN	MPP(  5, 0x4, 0, 1, 1,   1,   1,   1,   0 )
-#define MPP5_SATA0_ACTn		MPP(  5, 0x5, 0, 1, 0,   1,   1,   1,   1 )
+#define MPP5_NF_IO7		MPP(  5, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP5_UART0_TXD		MPP(  5, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP5_PTP_TRIG_GEN	MPP(  5, 0x4, 0, 0, 1,   1,   1,   1,   0 )
+#define MPP5_SATA0_ACTn		MPP(  5, 0x5, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP5_LCD_VGA_VSYNC	MPP(  5, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
-#define MPP6_SYSRST_OUTn	MPP(  6, 0x1, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP6_SPI_MOSI		MPP(  6, 0x2, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP6_PTP_TRIG_GEN	MPP(  6, 0x3, 0, 1, 1,   1,   1,   1,   0 )
+#define MPP6_SYSRST_OUTn	MPP(  6, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP6_SPI_MOSI		MPP(  6, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP6_PTP_TRIG_GEN	MPP(  6, 0x3, 0, 0, 1,   1,   1,   1,   0 )
 
 #define MPP7_GPO		MPP(  7, 0x0, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP7_PEX_RST_OUTn	MPP(  7, 0x1, 0, 1, 1,   1,   1,   1,   0 )
-#define MPP7_SPI_SCn		MPP(  7, 0x2, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP7_PTP_TRIG_GEN	MPP(  7, 0x3, 0, 1, 1,   1,   1,   1,   0 )
-#define MPP7_LCD_PWM		MPP(  7, 0xb, 0, 1, 0,   0,   0,   0,   1 )
+#define MPP7_PEX_RST_OUTn	MPP(  7, 0x1, 0, 0, 1,   1,   1,   1,   0 )
+#define MPP7_SPI_SCn		MPP(  7, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP7_PTP_TRIG_GEN	MPP(  7, 0x3, 0, 0, 1,   1,   1,   1,   0 )
+#define MPP7_LCD_PWM		MPP(  7, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP8_GPIO		MPP(  8, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP8_TW0_SDA		MPP(  8, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP8_UART0_RTS		MPP(  8, 0x2, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP8_UART1_RTS		MPP(  8, 0x3, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP8_MII0_RXERR		MPP(  8, 0x4, 1, 0, 0,   1,   1,   1,   1 )
-#define MPP8_SATA1_PRESENTn	MPP(  8, 0x5, 0, 1, 0,   0,   1,   1,   1 )
-#define MPP8_PTP_CLK		MPP(  8, 0xc, 1, 0, 1,   1,   1,   1,   0 )
-#define MPP8_MII0_COL		MPP(  8, 0xd, 1, 0, 1,   1,   1,   1,   1 )
+#define MPP8_TW0_SDA		MPP(  8, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP8_UART0_RTS		MPP(  8, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP8_UART1_RTS		MPP(  8, 0x3, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP8_MII0_RXERR		MPP(  8, 0x4, 0, 0, 0,   1,   1,   1,   1 )
+#define MPP8_SATA1_PRESENTn	MPP(  8, 0x5, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP8_PTP_CLK		MPP(  8, 0xc, 0, 0, 1,   1,   1,   1,   0 )
+#define MPP8_MII0_COL		MPP(  8, 0xd, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP9_GPIO		MPP(  9, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP9_TW0_SCK		MPP(  9, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP9_UART0_CTS		MPP(  9, 0x2, 1, 0, 1,   1,   1,   1,   1 )
-#define MPP9_UART1_CTS		MPP(  9, 0x3, 1, 0, 1,   1,   1,   1,   1 )
-#define MPP9_SATA0_PRESENTn	MPP(  9, 0x5, 0, 1, 0,   1,   1,   1,   1 )
-#define MPP9_PTP_EVENT_REQ	MPP(  9, 0xc, 1, 0, 1,   1,   1,   1,   0 )
-#define MPP9_MII0_CRS		MPP(  9, 0xd, 1, 0, 1,   1,   1,   1,   1 )
+#define MPP9_TW0_SCK		MPP(  9, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP9_UART0_CTS		MPP(  9, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP9_UART1_CTS		MPP(  9, 0x3, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP9_SATA0_PRESENTn	MPP(  9, 0x5, 0, 0, 0,   1,   1,   1,   1 )
+#define MPP9_PTP_EVENT_REQ	MPP(  9, 0xc, 0, 0, 1,   1,   1,   1,   0 )
+#define MPP9_MII0_CRS		MPP(  9, 0xd, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP10_GPO		MPP( 10, 0x0, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP10_SPI_SCK		MPP( 10, 0x2, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP10_UART0_TXD		MPP( 10, 0X3, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP10_SATA1_ACTn	MPP( 10, 0x5, 0, 1, 0,   0,   1,   1,   1 )
-#define MPP10_PTP_TRIG_GEN	MPP( 10, 0xc, 0, 1, 1,   1,   1,   1,   0 )
+#define MPP10_SPI_SCK		MPP( 10, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP10_UART0_TXD		MPP( 10, 0X3, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP10_SATA1_ACTn	MPP( 10, 0x5, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP10_PTP_TRIG_GEN	MPP( 10, 0xc, 0, 0, 1,   1,   1,   1,   0 )
 
 #define MPP11_GPIO		MPP( 11, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP11_SPI_MISO		MPP( 11, 0x2, 1, 0, 1,   1,   1,   1,   1 )
-#define MPP11_UART0_RXD		MPP( 11, 0x3, 1, 0, 1,   1,   1,   1,   1 )
-#define MPP11_PTP_EVENT_REQ	MPP( 11, 0x4, 1, 0, 1,   1,   1,   1,   0 )
-#define MPP11_PTP_TRIG_GEN	MPP( 11, 0xc, 0, 1, 1,   1,   1,   1,   0 )
-#define MPP11_PTP_CLK		MPP( 11, 0xd, 1, 0, 1,   1,   1,   1,   0 )
-#define MPP11_SATA0_ACTn	MPP( 11, 0x5, 0, 1, 0,   1,   1,   1,   1 )
+#define MPP11_SPI_MISO		MPP( 11, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP11_UART0_RXD		MPP( 11, 0x3, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP11_PTP_EVENT_REQ	MPP( 11, 0x4, 0, 0, 1,   1,   1,   1,   0 )
+#define MPP11_PTP_TRIG_GEN	MPP( 11, 0xc, 0, 0, 1,   1,   1,   1,   0 )
+#define MPP11_PTP_CLK		MPP( 11, 0xd, 0, 0, 1,   1,   1,   1,   0 )
+#define MPP11_SATA0_ACTn	MPP( 11, 0x5, 0, 0, 0,   1,   1,   1,   1 )
 
 #define MPP12_GPO		MPP( 12, 0x0, 0, 1, 1,   1,   1,   1,   1 )
 #define MPP12_GPIO		MPP( 12, 0x0, 1, 1, 0,   0,   0,   1,   0 )
-#define MPP12_SD_CLK		MPP( 12, 0x1, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP12_AU_SPDIF0		MPP( 12, 0xa, 0, 1, 0,   0,   0,   0,   1 )
-#define MPP12_SPI_MOSI		MPP( 12, 0xb, 0, 1, 0,   0,   0,   0,   1 )
-#define MPP12_TW1_SDA		MPP( 12, 0xd, 1, 0, 0,   0,   0,   0,   1 )
+#define MPP12_SD_CLK		MPP( 12, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP12_AU_SPDIF0		MPP( 12, 0xa, 0, 0, 0,   0,   0,   0,   1 )
+#define MPP12_SPI_MOSI		MPP( 12, 0xb, 0, 0, 0,   0,   0,   0,   1 )
+#define MPP12_TW1_SDA		MPP( 12, 0xd, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP13_GPIO		MPP( 13, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP13_SD_CMD		MPP( 13, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP13_UART1_TXD		MPP( 13, 0x3, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP13_AU_SPDIFRMCLK	MPP( 13, 0xa, 0, 1, 0,   0,   0,   0,   1 )
-#define MPP13_LCDPWM		MPP( 13, 0xb, 0, 1, 0,   0,   0,   0,   1 )
+#define MPP13_SD_CMD		MPP( 13, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP13_UART1_TXD		MPP( 13, 0x3, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP13_AU_SPDIFRMCLK	MPP( 13, 0xa, 0, 0, 0,   0,   0,   0,   1 )
+#define MPP13_LCDPWM		MPP( 13, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP14_GPIO		MPP( 14, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP14_SD_D0		MPP( 14, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP14_UART1_RXD		MPP( 14, 0x3, 1, 0, 1,   1,   1,   1,   1 )
-#define MPP14_SATA1_PRESENTn	MPP( 14, 0x4, 0, 1, 0,   0,   1,   1,   1 )
-#define MPP14_AU_SPDIFI		MPP( 14, 0xa, 1, 0, 0,   0,   0,   0,   1 )
-#define MPP14_AU_I2SDI		MPP( 14, 0xb, 1, 0, 0,   0,   0,   0,   1 )
-#define MPP14_MII0_COL		MPP( 14, 0xd, 1, 0, 1,   1,   1,   1,   1 )
+#define MPP14_SD_D0		MPP( 14, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP14_UART1_RXD		MPP( 14, 0x3, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP14_SATA1_PRESENTn	MPP( 14, 0x4, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP14_AU_SPDIFI		MPP( 14, 0xa, 0, 0, 0,   0,   0,   0,   1 )
+#define MPP14_AU_I2SDI		MPP( 14, 0xb, 0, 0, 0,   0,   0,   0,   1 )
+#define MPP14_MII0_COL		MPP( 14, 0xd, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP15_GPIO		MPP( 15, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP15_SD_D1		MPP( 15, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP15_UART0_RTS		MPP( 15, 0x2, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP15_UART1_TXD		MPP( 15, 0x3, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP15_SATA0_ACTn	MPP( 15, 0x4, 0, 1, 0,   1,   1,   1,   1 )
-#define MPP15_SPI_CSn		MPP( 15, 0xb, 0, 1, 0,   0,   0,   0,   1 )
+#define MPP15_SD_D1		MPP( 15, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP15_UART0_RTS		MPP( 15, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP15_UART1_TXD		MPP( 15, 0x3, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP15_SATA0_ACTn	MPP( 15, 0x4, 0, 0, 0,   1,   1,   1,   1 )
+#define MPP15_SPI_CSn		MPP( 15, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP16_GPIO		MPP( 16, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP16_SD_D2		MPP( 16, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP16_UART0_CTS		MPP( 16, 0x2, 1, 0, 1,   1,   1,   1,   1 )
-#define MPP16_UART1_RXD		MPP( 16, 0x3, 1, 0, 1,   1,   1,   1,   1 )
-#define MPP16_SATA1_ACTn	MPP( 16, 0x4, 0, 1, 0,   0,   1,   1,   1 )
-#define MPP16_LCD_EXT_REF_CLK	MPP( 16, 0xb, 1, 0, 0,   0,   0,   0,   1 )
-#define MPP16_MII0_CRS		MPP( 16, 0xd, 1, 0, 1,   1,   1,   1,   1 )
+#define MPP16_SD_D2		MPP( 16, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP16_UART0_CTS		MPP( 16, 0x2, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP16_UART1_RXD		MPP( 16, 0x3, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP16_SATA1_ACTn	MPP( 16, 0x4, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP16_LCD_EXT_REF_CLK	MPP( 16, 0xb, 0, 0, 0,   0,   0,   0,   1 )
+#define MPP16_MII0_CRS		MPP( 16, 0xd, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP17_GPIO		MPP( 17, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP17_SD_D3		MPP( 17, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP17_SATA0_PRESENTn	MPP( 17, 0x4, 0, 1, 0,   1,   1,   1,   1 )
-#define MPP17_SATA1_ACTn	MPP( 17, 0xa, 0, 1, 0,   0,   0,   0,   1 )
-#define MPP17_TW1_SCK		MPP( 17, 0xd, 1, 1, 0,   0,   0,   0,   1 )
+#define MPP17_SD_D3		MPP( 17, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP17_SATA0_PRESENTn	MPP( 17, 0x4, 0, 0, 0,   1,   1,   1,   1 )
+#define MPP17_SATA1_ACTn	MPP( 17, 0xa, 0, 0, 0,   0,   0,   0,   1 )
+#define MPP17_TW1_SCK		MPP( 17, 0xd, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP18_GPO		MPP( 18, 0x0, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP18_NF_IO0		MPP( 18, 0x1, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP18_PEX0_CLKREQ	MPP( 18, 0x2, 0, 1, 0,   0,   0,   0,   1 )
+#define MPP18_NF_IO0		MPP( 18, 0x1, 0, 0, 1,   1,   1,   1,   1 )
+#define MPP18_PEX0_CLKREQ	MPP( 18, 0x2, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP19_GPO		MPP( 19, 0x0, 0, 1, 1,   1,   1,   1,   1 )
-#define MPP19_NF_IO1		MPP( 19, 0x1, 1, 1, 1,   1,   1,   1,   1 )
+#define MPP19_NF_IO1		MPP( 19, 0x1, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP20_GPIO		MPP( 20, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP20_TSMP0		MPP( 20, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP20_TDM_CH0_TX_QL	MPP( 20, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP20_TSMP0		MPP( 20, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP20_TDM_CH0_TX_QL	MPP( 20, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP20_GE1_TXD0		MPP( 20, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP20_AU_SPDIFI		MPP( 20, 0x4, 1, 0, 0,   0,   1,   1,   1 )
-#define MPP20_SATA1_ACTn	MPP( 20, 0x5, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP20_AU_SPDIFI		MPP( 20, 0x4, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP20_SATA1_ACTn	MPP( 20, 0x5, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP20_LCD_D0		MPP( 20, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP21_GPIO		MPP( 21, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP21_TSMP1		MPP( 21, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP21_TDM_CH0_RX_QL	MPP( 21, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP21_TSMP1		MPP( 21, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP21_TDM_CH0_RX_QL	MPP( 21, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP21_GE1_TXD1		MPP( 21, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP21_AU_SPDIFO		MPP( 21, 0x4, 0, 1, 0,   0,   1,   1,   1 )
-#define MPP21_SATA0_ACTn	MPP( 21, 0x5, 0, 1, 0,   1,   1,   1,   1 )
+#define MPP21_AU_SPDIFO		MPP( 21, 0x4, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP21_SATA0_ACTn	MPP( 21, 0x5, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP21_LCD_D1		MPP( 21, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP22_GPIO		MPP( 22, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP22_TSMP2		MPP( 22, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP22_TDM_CH2_TX_QL	MPP( 22, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP22_TSMP2		MPP( 22, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP22_TDM_CH2_TX_QL	MPP( 22, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP22_GE1_TXD2		MPP( 22, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP22_AU_SPDIFRMKCLK	MPP( 22, 0x4, 0, 1, 0,   0,   1,   1,   1 )
-#define MPP22_SATA1_PRESENTn	MPP( 22, 0x5, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP22_AU_SPDIFRMKCLK	MPP( 22, 0x4, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP22_SATA1_PRESENTn	MPP( 22, 0x5, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP22_LCD_D2		MPP( 22, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP23_GPIO		MPP( 23, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP23_TSMP3		MPP( 23, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP23_TDM_CH2_RX_QL	MPP( 23, 0x2, 1, 0, 0,   0,   1,   1,   1 )
+#define MPP23_TSMP3		MPP( 23, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP23_TDM_CH2_RX_QL	MPP( 23, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP23_GE1_TXD3		MPP( 23, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP23_AU_I2SBCLK	MPP( 23, 0x4, 0, 1, 0,   0,   1,   1,   1 )
-#define MPP23_SATA0_PRESENTn	MPP( 23, 0x5, 0, 1, 0,   1,   1,   1,   1 )
+#define MPP23_AU_I2SBCLK	MPP( 23, 0x4, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP23_SATA0_PRESENTn	MPP( 23, 0x5, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP23_LCD_D3		MPP( 23, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP24_GPIO		MPP( 24, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP24_TSMP4		MPP( 24, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP24_TDM_SPI_CS0	MPP( 24, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP24_TSMP4		MPP( 24, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP24_TDM_SPI_CS0	MPP( 24, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP24_GE1_RXD0		MPP( 24, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP24_AU_I2SDO		MPP( 24, 0x4, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP24_AU_I2SDO		MPP( 24, 0x4, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP24_LCD_D4		MPP( 24, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP25_GPIO		MPP( 25, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP25_TSMP5		MPP( 25, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP25_TDM_SPI_SCK	MPP( 25, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP25_TSMP5		MPP( 25, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP25_TDM_SPI_SCK	MPP( 25, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP25_GE1_RXD1		MPP( 25, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP25_AU_I2SLRCLK	MPP( 25, 0x4, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP25_AU_I2SLRCLK	MPP( 25, 0x4, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP25_LCD_D5		MPP( 25, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP26_GPIO		MPP( 26, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP26_TSMP6		MPP( 26, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP26_TDM_SPI_MISO	MPP( 26, 0x2, 1, 0, 0,   0,   1,   1,   1 )
+#define MPP26_TSMP6		MPP( 26, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP26_TDM_SPI_MISO	MPP( 26, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP26_GE1_RXD2		MPP( 26, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP26_AU_I2SMCLK	MPP( 26, 0x4, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP26_AU_I2SMCLK	MPP( 26, 0x4, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP26_LCD_D6		MPP( 26, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP27_GPIO		MPP( 27, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP27_TSMP7		MPP( 27, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP27_TDM_SPI_MOSI	MPP( 27, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP27_TSMP7		MPP( 27, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP27_TDM_SPI_MOSI	MPP( 27, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP27_GE1_RXD3		MPP( 27, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP27_AU_I2SDI		MPP( 27, 0x4, 1, 0, 0,   0,   1,   1,   1 )
+#define MPP27_AU_I2SDI		MPP( 27, 0x4, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP27_LCD_D7		MPP( 27, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP28_GPIO		MPP( 28, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP28_TSMP8		MPP( 28, 0x1, 1, 1, 0,   0,   1,   1,   1 )
+#define MPP28_TSMP8		MPP( 28, 0x1, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP28_TDM_CODEC_INTn	MPP( 28, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP28_GE1_COL		MPP( 28, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP28_AU_EXTCLK		MPP( 28, 0x4, 1, 0, 0,   0,   1,   1,   1 )
+#define MPP28_AU_EXTCLK		MPP( 28, 0x4, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP28_LCD_D8		MPP( 28, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP29_GPIO		MPP( 29, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP29_TSMP9		MPP( 29, 0x1, 1, 1, 0,   0,   1,   1,   1 )
+#define MPP29_TSMP9		MPP( 29, 0x1, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP29_TDM_CODEC_RSTn	MPP( 29, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP29_GE1_TCLK		MPP( 29, 0x3, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP29_LCD_D9		MPP( 29, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP30_GPIO		MPP( 30, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP30_TSMP10		MPP( 30, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP30_TDM_PCLK		MPP( 30, 0x2, 1, 1, 0,   0,   1,   1,   1 )
+#define MPP30_TSMP10		MPP( 30, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP30_TDM_PCLK		MPP( 30, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP30_GE1_RXCTL		MPP( 30, 0x3, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP30_LCD_D10		MPP( 30, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP31_GPIO		MPP( 31, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP31_TSMP11		MPP( 31, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP31_TDM_FS		MPP( 31, 0x2, 1, 1, 0,   0,   1,   1,   1 )
+#define MPP31_TSMP11		MPP( 31, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP31_TDM_FS		MPP( 31, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP31_GE1_RXCLK		MPP( 31, 0x3, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP31_LCD_D11		MPP( 31, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP32_GPIO		MPP( 32, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP32_TSMP12		MPP( 32, 0x1, 1, 1, 0,   0,   1,   1,   1 )
-#define MPP32_TDM_DRX		MPP( 32, 0x2, 1, 0, 0,   0,   1,   1,   1 )
+#define MPP32_TSMP12		MPP( 32, 0x1, 0, 0, 0,   0,   1,   1,   1 )
+#define MPP32_TDM_DRX		MPP( 32, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP32_GE1_TCLKOUT	MPP( 32, 0x3, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP32_LCD_D12		MPP( 32, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP33_GPO		MPP( 33, 0x0, 0, 1, 0,   1,   1,   1,   1 )
-#define MPP33_TDM_DTX		MPP( 33, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP33_TDM_DTX		MPP( 33, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP33_GE1_TXCTL		MPP( 33, 0x3, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP33_LCD_D13		MPP( 33, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP34_GPIO		MPP( 34, 0x0, 1, 1, 0,   1,   1,   1,   1 )
-#define MPP34_TDM_SPI_CS1	MPP( 34, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP34_TDM_SPI_CS1	MPP( 34, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP34_GE1_TXEN		MPP( 34, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP34_SATA1_ACTn	MPP( 34, 0x5, 0, 1, 0,   0,   0,   1,   1 )
+#define MPP34_SATA1_ACTn	MPP( 34, 0x5, 0, 0, 0,   0,   0,   1,   1 )
 #define MPP34_LCD_D14		MPP( 34, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP35_GPIO		MPP( 35, 0x0, 1, 1, 1,   1,   1,   1,   1 )
-#define MPP35_TDM_CH0_TX_QL	MPP( 35, 0x2, 0, 1, 0,   0,   1,   1,   1 )
+#define MPP35_TDM_CH0_TX_QL	MPP( 35, 0x2, 0, 0, 0,   0,   1,   1,   1 )
 #define MPP35_GE1_RXERR		MPP( 35, 0x3, 0, 0, 0,   1,   1,   1,   1 )
-#define MPP35_SATA0_ACTn	MPP( 35, 0x5, 0, 1, 0,   1,   1,   1,   1 )
+#define MPP35_SATA0_ACTn	MPP( 35, 0x5, 0, 0, 0,   1,   1,   1,   1 )
 #define MPP35_LCD_D15		MPP( 22, 0xb, 0, 0, 0,   0,   0,   0,   1 )
-#define MPP35_MII0_RXERR	MPP( 35, 0xc, 1, 0, 1,   1,   1,   1,   1 )
+#define MPP35_MII0_RXERR	MPP( 35, 0xc, 0, 0, 1,   1,   1,   1,   1 )
 
 #define MPP36_GPIO		MPP( 36, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP36_TSMP0		MPP( 36, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP36_TDM_SPI_CS1	MPP( 36, 0x2, 0, 1, 0,   0,   0,   1,   1 )
-#define MPP36_AU_SPDIFI		MPP( 36, 0x4, 1, 0, 1,   0,   0,   1,   1 )
-#define MPP36_TW1_SDA		MPP( 36, 0xb, 1, 1, 0,   0,   0,   0,   1 )
+#define MPP36_TSMP0		MPP( 36, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP36_TDM_SPI_CS1	MPP( 36, 0x2, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP36_AU_SPDIFI		MPP( 36, 0x4, 0, 0, 1,   0,   0,   1,   1 )
+#define MPP36_TW1_SDA		MPP( 36, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP37_GPIO		MPP( 37, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP37_TSMP1		MPP( 37, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP37_TDM_CH2_TX_QL	MPP( 37, 0x2, 0, 1, 0,   0,   0,   1,   1 )
-#define MPP37_AU_SPDIFO		MPP( 37, 0x4, 0, 1, 1,   0,   0,   1,   1 )
-#define MPP37_TW1_SCK		MPP( 37, 0xb, 1, 1, 0,   0,   0,   0,   1 )
+#define MPP37_TSMP1		MPP( 37, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP37_TDM_CH2_TX_QL	MPP( 37, 0x2, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP37_AU_SPDIFO		MPP( 37, 0x4, 0, 0, 1,   0,   0,   1,   1 )
+#define MPP37_TW1_SCK		MPP( 37, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP38_GPIO		MPP( 38, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP38_TSMP2		MPP( 38, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP38_TDM_CH2_RX_QL	MPP( 38, 0x2, 0, 1, 0,   0,   0,   1,   1 )
-#define MPP38_AU_SPDIFRMLCLK	MPP( 38, 0x4, 0, 1, 1,   0,   0,   1,   1 )
+#define MPP38_TSMP2		MPP( 38, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP38_TDM_CH2_RX_QL	MPP( 38, 0x2, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP38_AU_SPDIFRMLCLK	MPP( 38, 0x4, 0, 0, 1,   0,   0,   1,   1 )
 #define MPP38_LCD_D18		MPP( 38, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP39_GPIO		MPP( 39, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP39_TSMP3		MPP( 39, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP39_TDM_SPI_CS0	MPP( 39, 0x2, 0, 1, 0,   0,   0,   1,   1 )
-#define MPP39_AU_I2SBCLK	MPP( 39, 0x4, 0, 1, 1,   0,   0,   1,   1 )
+#define MPP39_TSMP3		MPP( 39, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP39_TDM_SPI_CS0	MPP( 39, 0x2, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP39_AU_I2SBCLK	MPP( 39, 0x4, 0, 0, 1,   0,   0,   1,   1 )
 #define MPP39_LCD_D19		MPP( 39, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP40_GPIO		MPP( 40, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP40_TSMP4		MPP( 40, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP40_TDM_SPI_SCK	MPP( 40, 0x2, 0, 1, 0,   0,   0,   1,   1 )
-#define MPP40_AU_I2SDO		MPP( 40, 0x4, 0, 1, 1,   0,   0,   1,   1 )
+#define MPP40_TSMP4		MPP( 40, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP40_TDM_SPI_SCK	MPP( 40, 0x2, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP40_AU_I2SDO		MPP( 40, 0x4, 0, 0, 1,   0,   0,   1,   1 )
 #define MPP40_LCD_D20		MPP( 40, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP41_GPIO		MPP( 41, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP41_TSMP5		MPP( 41, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP41_TDM_SPI_MISO	MPP( 41, 0x2, 1, 0, 0,   0,   0,   1,   1 )
-#define MPP41_AU_I2SLRCLK	MPP( 41, 0x4, 0, 1, 1,   0,   0,   1,   1 )
+#define MPP41_TSMP5		MPP( 41, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP41_TDM_SPI_MISO	MPP( 41, 0x2, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP41_AU_I2SLRCLK	MPP( 41, 0x4, 0, 0, 1,   0,   0,   1,   1 )
 #define MPP41_LCD_D21		MPP( 41, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP42_GPIO		MPP( 42, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP42_TSMP6		MPP( 42, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP42_TDM_SPI_MOSI	MPP( 42, 0x2, 0, 1, 0,   0,   0,   1,   1 )
-#define MPP42_AU_I2SMCLK	MPP( 42, 0x4, 0, 1, 1,   0,   0,   1,   1 )
+#define MPP42_TSMP6		MPP( 42, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP42_TDM_SPI_MOSI	MPP( 42, 0x2, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP42_AU_I2SMCLK	MPP( 42, 0x4, 0, 0, 1,   0,   0,   1,   1 )
 #define MPP42_LCD_D22		MPP( 42, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP43_GPIO		MPP( 43, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP43_TSMP7		MPP( 43, 0x1, 1, 1, 0,   0,   0,   1,   1 )
+#define MPP43_TSMP7		MPP( 43, 0x1, 0, 0, 0,   0,   0,   1,   1 )
 #define MPP43_TDM_CODEC_INTn	MPP( 43, 0x2, 0, 0, 0,   0,   0,   1,   1 )
-#define MPP43_AU_I2SDI		MPP( 43, 0x4, 1, 0, 1,   0,   0,   1,   1 )
+#define MPP43_AU_I2SDI		MPP( 43, 0x4, 0, 0, 1,   0,   0,   1,   1 )
 #define MPP43_LCD_D23		MPP( 22, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP44_GPIO		MPP( 44, 0x0, 1, 1, 1,   0,   0,   1,   1 )
-#define MPP44_TSMP8		MPP( 44, 0x1, 1, 1, 0,   0,   0,   1,   1 )
+#define MPP44_TSMP8		MPP( 44, 0x1, 0, 0, 0,   0,   0,   1,   1 )
 #define MPP44_TDM_CODEC_RSTn	MPP( 44, 0x2, 0, 0, 0,   0,   0,   1,   1 )
-#define MPP44_AU_EXTCLK		MPP( 44, 0x4, 1, 0, 1,   0,   0,   1,   1 )
+#define MPP44_AU_EXTCLK		MPP( 44, 0x4, 0, 0, 1,   0,   0,   1,   1 )
 #define MPP44_LCD_CLK		MPP( 44, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP45_GPIO		MPP( 45, 0x0, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP45_TSMP9		MPP( 45, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP45_TDM_PCLK		MPP( 45, 0x2, 1, 1, 0,   0,   0,   1,   1 )
+#define MPP45_TSMP9		MPP( 45, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP45_TDM_PCLK		MPP( 45, 0x2, 0, 0, 0,   0,   0,   1,   1 )
 #define MPP245_LCD_E		MPP( 45, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP46_GPIO		MPP( 46, 0x0, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP46_TSMP10		MPP( 46, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP46_TDM_FS		MPP( 46, 0x2, 1, 1, 0,   0,   0,   1,   1 )
+#define MPP46_TSMP10		MPP( 46, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP46_TDM_FS		MPP( 46, 0x2, 0, 0, 0,   0,   0,   1,   1 )
 #define MPP46_LCD_HSYNC		MPP( 46, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP47_GPIO		MPP( 47, 0x0, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP47_TSMP11		MPP( 47, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP47_TDM_DRX		MPP( 47, 0x2, 1, 0, 0,   0,   0,   1,   1 )
+#define MPP47_TSMP11		MPP( 47, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP47_TDM_DRX		MPP( 47, 0x2, 0, 0, 0,   0,   0,   1,   1 )
 #define MPP47_LCD_VSYNC		MPP( 47, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP48_GPIO		MPP( 48, 0x0, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP48_TSMP12		MPP( 48, 0x1, 1, 1, 0,   0,   0,   1,   1 )
-#define MPP48_TDM_DTX		MPP( 48, 0x2, 0, 1, 0,   0,   0,   1,   1 )
+#define MPP48_TSMP12		MPP( 48, 0x1, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP48_TDM_DTX		MPP( 48, 0x2, 0, 0, 0,   0,   0,   1,   1 )
 #define MPP48_LCD_D16		MPP( 22, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP49_GPIO		MPP( 49, 0x0, 1, 1, 0,   0,   0,   1,   0 )
 #define MPP49_GPO		MPP( 49, 0x0, 0, 1, 0,   0,   0,   0,   1 )
-#define MPP49_TSMP9		MPP( 49, 0x1, 1, 1, 0,   0,   0,   1,   0 )
-#define MPP49_TDM_CH0_RX_QL	MPP( 49, 0x2, 0, 1, 0,   0,   0,   1,   1 )
-#define MPP49_PTP_CLK		MPP( 49, 0x5, 1, 0, 0,   0,   0,   1,   0 )
-#define MPP49_PEX0_CLKREQ	MPP( 49, 0xa, 0, 1, 0,   0,   0,   0,   1 )
+#define MPP49_TSMP9		MPP( 49, 0x1, 0, 0, 0,   0,   0,   1,   0 )
+#define MPP49_TDM_CH0_RX_QL	MPP( 49, 0x2, 0, 0, 0,   0,   0,   1,   1 )
+#define MPP49_PTP_CLK		MPP( 49, 0x5, 0, 0, 0,   0,   0,   1,   0 )
+#define MPP49_PEX0_CLKREQ	MPP( 49, 0xa, 0, 0, 0,   0,   0,   0,   1 )
 #define MPP49_LCD_D17		MPP( 49, 0xb, 0, 0, 0,   0,   0,   0,   1 )
 
 #define MPP_MAX			49
diff --git a/arch/arm/mach-lpc32xx/include/mach/irqs.h b/arch/arm/mach-lpc32xx/include/mach/irqs.h
index 2667f52..9e3b90d 100644
--- a/arch/arm/mach-lpc32xx/include/mach/irqs.h
+++ b/arch/arm/mach-lpc32xx/include/mach/irqs.h
@@ -61,7 +61,7 @@
  */
 #define IRQ_LPC32XX_JTAG_COMM_TX	LPC32XX_SIC1_IRQ(1)
 #define IRQ_LPC32XX_JTAG_COMM_RX	LPC32XX_SIC1_IRQ(2)
-#define IRQ_LPC32XX_GPI_11		LPC32XX_SIC1_IRQ(4)
+#define IRQ_LPC32XX_GPI_28		LPC32XX_SIC1_IRQ(4)
 #define IRQ_LPC32XX_TS_P		LPC32XX_SIC1_IRQ(6)
 #define IRQ_LPC32XX_TS_IRQ		LPC32XX_SIC1_IRQ(7)
 #define IRQ_LPC32XX_TS_AUX		LPC32XX_SIC1_IRQ(8)
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
index 4eae566..c74de01 100644
--- a/arch/arm/mach-lpc32xx/irq.c
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -118,6 +118,10 @@
 		.event_group = &lpc32xx_event_pin_regs,
 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT,
 	},
+	[IRQ_LPC32XX_GPI_28] = {
+		.event_group = &lpc32xx_event_pin_regs,
+		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT,
+	},
 	[IRQ_LPC32XX_GPIO_00] = {
 		.event_group = &lpc32xx_event_int_regs,
 		.mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT,
@@ -305,9 +309,18 @@
 
 		if (state)
 			eventreg |= lpc32xx_events[d->irq].mask;
-		else
+		else {
 			eventreg &= ~lpc32xx_events[d->irq].mask;
 
+			/*
+			 * When disabling the wakeup, clear the latched
+			 * event
+			 */
+			__raw_writel(lpc32xx_events[d->irq].mask,
+				lpc32xx_events[d->irq].
+				event_group->rawstat_reg);
+		}
+
 		__raw_writel(eventreg,
 			lpc32xx_events[d->irq].event_group->enab_reg);
 
@@ -380,13 +393,15 @@
 
 	/* Setup SIC1 */
 	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
-	__raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE));
-	__raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE));
+	__raw_writel(SIC1_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE));
+	__raw_writel(SIC1_ATR_DEFAULT,
+				LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE));
 
 	/* Setup SIC2 */
 	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
-	__raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE));
-	__raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE));
+	__raw_writel(SIC2_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE));
+	__raw_writel(SIC2_ATR_DEFAULT,
+				LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE));
 
 	/* Configure supported IRQ's */
 	for (i = 0; i < NR_IRQS; i++) {
diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c
index 429cfdb..f273528 100644
--- a/arch/arm/mach-lpc32xx/serial.c
+++ b/arch/arm/mach-lpc32xx/serial.c
@@ -88,6 +88,7 @@
 	char *uart_ck_name;
 	u32 ck_mode_mask;
 	void __iomem *pdiv_clk_reg;
+	resource_size_t mapbase;
 };
 
 static struct uartinit uartinit_data[] __initdata = {
@@ -97,6 +98,7 @@
 		.ck_mode_mask =
 			LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5),
 		.pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL,
+		.mapbase = LPC32XX_UART5_BASE,
 	},
 #endif
 #ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT
@@ -105,6 +107,7 @@
 		.ck_mode_mask =
 			LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3),
 		.pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL,
+		.mapbase = LPC32XX_UART3_BASE,
 	},
 #endif
 #ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT
@@ -113,6 +116,7 @@
 		.ck_mode_mask =
 			LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4),
 		.pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL,
+		.mapbase = LPC32XX_UART4_BASE,
 	},
 #endif
 #ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT
@@ -121,6 +125,7 @@
 		.ck_mode_mask =
 			LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6),
 		.pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL,
+		.mapbase = LPC32XX_UART6_BASE,
 	},
 #endif
 };
@@ -165,11 +170,24 @@
 
 		/* pre-UART clock divider set to 1 */
 		__raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg);
+
+		/*
+		 * Force a flush of the RX FIFOs to work around a
+		 * HW bug
+		 */
+		puart = uartinit_data[i].mapbase;
+		__raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
+		__raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart));
+		j = LPC32XX_SUART_FIFO_SIZE;
+		while (j--)
+			tmp = __raw_readl(
+				LPC32XX_UART_DLL_FIFO(puart));
+		__raw_writel(0, LPC32XX_UART_IIR_FCR(puart));
 	}
 
 	/* This needs to be done after all UART clocks are setup */
 	__raw_writel(clkmodes, LPC32XX_UARTCTL_CLKMODE);
-	for (i = 0; i < ARRAY_SIZE(uartinit_data) - 1; i++) {
+	for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) {
 		/* Force a flush of the RX FIFOs to work around a HW bug */
 		puart = serial_std_platform_data[i].mapbase;
 		__raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 17cb760..3588a55 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -17,7 +17,6 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 7bc17ea..ada1213 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -24,7 +24,6 @@
 #include <mach/dma.h>
 #include <mach/devices.h>
 #include <mach/mfp.h>
-#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <mach/pxa168.h>
 
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index 8e3b5af0..bc97170 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/smc91x.h>
-#include <linux/gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index 0cdd410..a5dcf766 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -19,6 +19,7 @@
 #include <mach/mv78xx0.h>
 #include <mach/bridge-regs.h>
 #include <plat/cache-feroceon-l2.h>
+#include <plat/ehci-orion.h>
 #include <plat/orion_nand.h>
 #include <plat/time.h>
 #include <plat/common.h>
@@ -169,7 +170,7 @@
  ****************************************************************************/
 void __init mv78xx0_ehci0_init(void)
 {
-	orion_ehci_init(USB0_PHYS_BASE, IRQ_MV78XX0_USB_0);
+	orion_ehci_init(USB0_PHYS_BASE, IRQ_MV78XX0_USB_0, EHCI_PHY_NA);
 }
 
 
diff --git a/arch/arm/mach-mv78xx0/mpp.h b/arch/arm/mach-mv78xx0/mpp.h
index b61b509..3752302 100644
--- a/arch/arm/mach-mv78xx0/mpp.h
+++ b/arch/arm/mach-mv78xx0/mpp.h
@@ -24,296 +24,296 @@
 #define MPP_78100_A0_MASK    MPP(0, 0x0, 0, 0, 1)
 
 #define MPP0_GPIO        MPP(0, 0x0, 1, 1, 1)
-#define MPP0_GE0_COL        MPP(0, 0x1, 1, 0, 1)
-#define MPP0_GE1_TXCLK        MPP(0, 0x2, 0, 1, 1)
+#define MPP0_GE0_COL        MPP(0, 0x1, 0, 0, 1)
+#define MPP0_GE1_TXCLK        MPP(0, 0x2, 0, 0, 1)
 #define MPP0_UNUSED        MPP(0, 0x3, 0, 0, 1)
 
 #define MPP1_GPIO        MPP(1, 0x0, 1, 1, 1)
-#define MPP1_GE0_RXERR        MPP(1, 0x1, 1, 0, 1)
-#define MPP1_GE1_TXCTL        MPP(1, 0x2, 0, 1, 1)
+#define MPP1_GE0_RXERR        MPP(1, 0x1, 0, 0, 1)
+#define MPP1_GE1_TXCTL        MPP(1, 0x2, 0, 0, 1)
 #define MPP1_UNUSED        MPP(1, 0x3, 0, 0, 1)
 
 #define MPP2_GPIO        MPP(2, 0x0, 1, 1, 1)
-#define MPP2_GE0_CRS        MPP(2, 0x1, 1, 0, 1)
-#define MPP2_GE1_RXCTL        MPP(2, 0x2, 1, 0, 1)
+#define MPP2_GE0_CRS        MPP(2, 0x1, 0, 0, 1)
+#define MPP2_GE1_RXCTL        MPP(2, 0x2, 0, 0, 1)
 #define MPP2_UNUSED        MPP(2, 0x3, 0, 0, 1)
 
 #define MPP3_GPIO        MPP(3, 0x0, 1, 1, 1)
-#define MPP3_GE0_TXERR        MPP(3, 0x1, 0, 1, 1)
-#define MPP3_GE1_RXCLK        MPP(3, 0x2, 1, 0, 1)
+#define MPP3_GE0_TXERR        MPP(3, 0x1, 0, 0, 1)
+#define MPP3_GE1_RXCLK        MPP(3, 0x2, 0, 0, 1)
 #define MPP3_UNUSED        MPP(3, 0x3, 0, 0, 1)
 
 #define MPP4_GPIO        MPP(4, 0x0, 1, 1, 1)
-#define MPP4_GE0_TXD4        MPP(4, 0x1, 0, 1, 1)
-#define MPP4_GE1_TXD0        MPP(4, 0x2, 0, 1, 1)
+#define MPP4_GE0_TXD4        MPP(4, 0x1, 0, 0, 1)
+#define MPP4_GE1_TXD0        MPP(4, 0x2, 0, 0, 1)
 #define MPP4_UNUSED        MPP(4, 0x3, 0, 0, 1)
 
 #define MPP5_GPIO        MPP(5, 0x0, 1, 1, 1)
-#define MPP5_GE0_TXD5        MPP(5, 0x1, 0, 1, 1)
-#define MPP5_GE1_TXD1        MPP(5, 0x2, 0, 1, 1)
+#define MPP5_GE0_TXD5        MPP(5, 0x1, 0, 0, 1)
+#define MPP5_GE1_TXD1        MPP(5, 0x2, 0, 0, 1)
 #define MPP5_UNUSED        MPP(5, 0x3, 0, 0, 1)
 
 #define MPP6_GPIO        MPP(6, 0x0, 1, 1, 1)
-#define MPP6_GE0_TXD6        MPP(6, 0x1, 0, 1, 1)
-#define MPP6_GE1_TXD2        MPP(6, 0x2, 0, 1, 1)
+#define MPP6_GE0_TXD6        MPP(6, 0x1, 0, 0, 1)
+#define MPP6_GE1_TXD2        MPP(6, 0x2, 0, 0, 1)
 #define MPP6_UNUSED        MPP(6, 0x3, 0, 0, 1)
 
 #define MPP7_GPIO        MPP(7, 0x0, 1, 1, 1)
-#define MPP7_GE0_TXD7        MPP(7, 0x1, 0, 1, 1)
-#define MPP7_GE1_TXD3        MPP(7, 0x2, 0, 1, 1)
+#define MPP7_GE0_TXD7        MPP(7, 0x1, 0, 0, 1)
+#define MPP7_GE1_TXD3        MPP(7, 0x2, 0, 0, 1)
 #define MPP7_UNUSED        MPP(7, 0x3, 0, 0, 1)
 
 #define MPP8_GPIO        MPP(8, 0x0, 1, 1, 1)
-#define MPP8_GE0_RXD4        MPP(8, 0x1, 1, 0, 1)
-#define MPP8_GE1_RXD0        MPP(8, 0x2, 1, 0, 1)
+#define MPP8_GE0_RXD4        MPP(8, 0x1, 0, 0, 1)
+#define MPP8_GE1_RXD0        MPP(8, 0x2, 0, 0, 1)
 #define MPP8_UNUSED        MPP(8, 0x3, 0, 0, 1)
 
 #define MPP9_GPIO        MPP(9, 0x0, 1, 1, 1)
-#define MPP9_GE0_RXD5        MPP(9, 0x1, 1, 0, 1)
-#define MPP9_GE1_RXD1        MPP(9, 0x2, 1, 0, 1)
+#define MPP9_GE0_RXD5        MPP(9, 0x1, 0, 0, 1)
+#define MPP9_GE1_RXD1        MPP(9, 0x2, 0, 0, 1)
 #define MPP9_UNUSED        MPP(9, 0x3, 0, 0, 1)
 
 #define MPP10_GPIO        MPP(10, 0x0, 1, 1, 1)
-#define MPP10_GE0_RXD6        MPP(10, 0x1, 1, 0, 1)
-#define MPP10_GE1_RXD2        MPP(10, 0x2, 1, 0, 1)
+#define MPP10_GE0_RXD6        MPP(10, 0x1, 0, 0, 1)
+#define MPP10_GE1_RXD2        MPP(10, 0x2, 0, 0, 1)
 #define MPP10_UNUSED        MPP(10, 0x3, 0, 0, 1)
 
 #define MPP11_GPIO        MPP(11, 0x0, 1, 1, 1)
-#define MPP11_GE0_RXD7        MPP(11, 0x1, 1, 0, 1)
-#define MPP11_GE1_RXD3        MPP(11, 0x2, 1, 0, 1)
+#define MPP11_GE0_RXD7        MPP(11, 0x1, 0, 0, 1)
+#define MPP11_GE1_RXD3        MPP(11, 0x2, 0, 0, 1)
 #define MPP11_UNUSED        MPP(11, 0x3, 0, 0, 1)
 
 #define MPP12_GPIO        MPP(12, 0x0, 1, 1, 1)
-#define MPP12_M_BB        MPP(12, 0x3, 1, 0, 1)
-#define MPP12_UA0_CTSn        MPP(12, 0x4, 1, 0, 1)
-#define MPP12_NAND_FLASH_REn0    MPP(12, 0x5, 0, 1, 1)
-#define MPP12_TDM0_SCSn        MPP(12, 0X6, 0, 1, 1)
+#define MPP12_M_BB        MPP(12, 0x3, 0, 0, 1)
+#define MPP12_UA0_CTSn        MPP(12, 0x4, 0, 0, 1)
+#define MPP12_NAND_FLASH_REn0    MPP(12, 0x5, 0, 0, 1)
+#define MPP12_TDM0_SCSn        MPP(12, 0X6, 0, 0, 1)
 #define MPP12_UNUSED        MPP(12, 0x1, 0, 0, 1)
 
 #define MPP13_GPIO        MPP(13, 0x0, 1, 1, 1)
-#define MPP13_SYSRST_OUTn    MPP(13, 0x3, 0, 1, 1)
-#define MPP13_UA0_RTSn        MPP(13, 0x4, 0, 1, 1)
-#define MPP13_NAN_FLASH_WEn0    MPP(13, 0x5, 0, 1, 1)
-#define MPP13_TDM_SCLK        MPP(13, 0x6, 0, 1, 1)
+#define MPP13_SYSRST_OUTn    MPP(13, 0x3, 0, 0, 1)
+#define MPP13_UA0_RTSn        MPP(13, 0x4, 0, 0, 1)
+#define MPP13_NAN_FLASH_WEn0    MPP(13, 0x5, 0, 0, 1)
+#define MPP13_TDM_SCLK        MPP(13, 0x6, 0, 0, 1)
 #define MPP13_UNUSED        MPP(13, 0x1, 0, 0, 1)
 
 #define MPP14_GPIO        MPP(14, 0x0, 1, 1, 1)
-#define MPP14_SATA1_ACTn    MPP(14, 0x3, 0, 1, 1)
-#define MPP14_UA1_CTSn        MPP(14, 0x4, 1, 0, 1)
-#define MPP14_NAND_FLASH_REn1    MPP(14, 0x5, 0, 1, 1)
-#define MPP14_TDM_SMOSI        MPP(14, 0x6, 0, 1, 1)
+#define MPP14_SATA1_ACTn    MPP(14, 0x3, 0, 0, 1)
+#define MPP14_UA1_CTSn        MPP(14, 0x4, 0, 0, 1)
+#define MPP14_NAND_FLASH_REn1    MPP(14, 0x5, 0, 0, 1)
+#define MPP14_TDM_SMOSI        MPP(14, 0x6, 0, 0, 1)
 #define MPP14_UNUSED        MPP(14, 0x1, 0, 0, 1)
 
 #define MPP15_GPIO        MPP(15, 0x0, 1, 1, 1)
-#define MPP15_SATA0_ACTn    MPP(15, 0x3, 0, 1, 1)
-#define MPP15_UA1_RTSn        MPP(15, 0x4, 0, 1, 1)
-#define MPP15_NAND_FLASH_WEn1    MPP(15, 0x5, 0, 1, 1)
-#define MPP15_TDM_SMISO        MPP(15, 0x6, 1, 0, 1)
+#define MPP15_SATA0_ACTn    MPP(15, 0x3, 0, 0, 1)
+#define MPP15_UA1_RTSn        MPP(15, 0x4, 0, 0, 1)
+#define MPP15_NAND_FLASH_WEn1    MPP(15, 0x5, 0, 0, 1)
+#define MPP15_TDM_SMISO        MPP(15, 0x6, 0, 0, 1)
 #define MPP15_UNUSED        MPP(15, 0x1, 0, 0, 1)
 
 #define MPP16_GPIO        MPP(16, 0x0, 1, 1, 1)
-#define MPP16_SATA1_PRESENTn    MPP(16, 0x3, 0, 1, 1)
-#define MPP16_UA2_TXD        MPP(16, 0x4, 0, 1, 1)
-#define MPP16_NAND_FLASH_REn3    MPP(16, 0x5, 0, 1, 1)
-#define MPP16_TDM_INTn        MPP(16, 0x6, 1, 0, 1)
+#define MPP16_SATA1_PRESENTn    MPP(16, 0x3, 0, 0, 1)
+#define MPP16_UA2_TXD        MPP(16, 0x4, 0, 0, 1)
+#define MPP16_NAND_FLASH_REn3    MPP(16, 0x5, 0, 0, 1)
+#define MPP16_TDM_INTn        MPP(16, 0x6, 0, 0, 1)
 #define MPP16_UNUSED        MPP(16, 0x1, 0, 0, 1)
 
 
 #define MPP17_GPIO        MPP(17, 0x0, 1, 1, 1)
-#define MPP17_SATA0_PRESENTn    MPP(17, 0x3, 0, 1, 1)
-#define MPP17_UA2_RXD        MPP(17, 0x4, 1, 0, 1)
-#define MPP17_NAND_FLASH_WEn3    MPP(17, 0x5, 0, 1, 1)
-#define MPP17_TDM_RSTn        MPP(17, 0x6, 0, 1, 1)
+#define MPP17_SATA0_PRESENTn    MPP(17, 0x3, 0, 0, 1)
+#define MPP17_UA2_RXD        MPP(17, 0x4, 0, 0, 1)
+#define MPP17_NAND_FLASH_WEn3    MPP(17, 0x5, 0, 0, 1)
+#define MPP17_TDM_RSTn        MPP(17, 0x6, 0, 0, 1)
 #define MPP17_UNUSED        MPP(17, 0x1, 0, 0, 1)
 
 
 #define MPP18_GPIO        MPP(18, 0x0, 1, 1, 1)
-#define MPP18_UA0_CTSn        MPP(18, 0x4, 1, 0, 1)
-#define MPP18_BOOT_FLASH_REn    MPP(18, 0x5, 0, 1, 1)
+#define MPP18_UA0_CTSn        MPP(18, 0x4, 0, 0, 1)
+#define MPP18_BOOT_FLASH_REn    MPP(18, 0x5, 0, 0, 1)
 #define MPP18_UNUSED        MPP(18, 0x1, 0, 0, 1)
 
 
 
 #define MPP19_GPIO        MPP(19, 0x0, 1, 1, 1)
-#define MPP19_UA0_CTSn        MPP(19, 0x4, 0, 1, 1)
-#define MPP19_BOOT_FLASH_WEn    MPP(19, 0x5, 0, 1, 1)
+#define MPP19_UA0_CTSn        MPP(19, 0x4, 0, 0, 1)
+#define MPP19_BOOT_FLASH_WEn    MPP(19, 0x5, 0, 0, 1)
 #define MPP19_UNUSED        MPP(19, 0x1, 0, 0, 1)
 
 
 #define MPP20_GPIO        MPP(20, 0x0, 1, 1, 1)
-#define MPP20_UA1_CTSs        MPP(20, 0x4, 1, 0, 1)
-#define MPP20_TDM_PCLK        MPP(20, 0x6, 1, 1, 0)
+#define MPP20_UA1_CTSs        MPP(20, 0x4, 0, 0, 1)
+#define MPP20_TDM_PCLK        MPP(20, 0x6, 0, 0, 0)
 #define MPP20_UNUSED        MPP(20, 0x1, 0, 0, 1)
 
 
 
 #define MPP21_GPIO        MPP(21, 0x0, 1, 1, 1)
-#define MPP21_UA1_CTSs        MPP(21, 0x4, 0, 1, 1)
-#define MPP21_TDM_FSYNC        MPP(21, 0x6, 1, 1, 0)
+#define MPP21_UA1_CTSs        MPP(21, 0x4, 0, 0, 1)
+#define MPP21_TDM_FSYNC        MPP(21, 0x6, 0, 0, 0)
 #define MPP21_UNUSED        MPP(21, 0x1, 0, 0, 1)
 
 
 
 #define MPP22_GPIO        MPP(22, 0x0, 1, 1, 1)
-#define MPP22_UA3_TDX        MPP(22, 0x4, 0, 1, 1)
-#define MPP22_NAND_FLASH_REn2    MPP(22, 0x5, 0, 1, 1)
-#define MPP22_TDM_DRX        MPP(22, 0x6, 1, 0, 1)
+#define MPP22_UA3_TDX        MPP(22, 0x4, 0, 0, 1)
+#define MPP22_NAND_FLASH_REn2    MPP(22, 0x5, 0, 0, 1)
+#define MPP22_TDM_DRX        MPP(22, 0x6, 0, 0, 1)
 #define MPP22_UNUSED        MPP(22, 0x1, 0, 0, 1)
 
 
 
 #define MPP23_GPIO        MPP(23, 0x0, 1, 1, 1)
-#define MPP23_UA3_RDX        MPP(23, 0x4, 1, 0, 1)
-#define MPP23_NAND_FLASH_WEn2    MPP(23, 0x5, 0, 1, 1)
-#define MPP23_TDM_DTX        MPP(23, 0x6, 0, 1, 1)
+#define MPP23_UA3_RDX        MPP(23, 0x4, 0, 0, 1)
+#define MPP23_NAND_FLASH_WEn2    MPP(23, 0x5, 0, 0, 1)
+#define MPP23_TDM_DTX        MPP(23, 0x6, 0, 0, 1)
 #define MPP23_UNUSED        MPP(23, 0x1, 0, 0, 1)
 
 
 #define MPP24_GPIO        MPP(24, 0x0, 1, 1, 1)
-#define MPP24_UA2_TXD        MPP(24, 0x4, 0, 1, 1)
-#define MPP24_TDM_INTn        MPP(24, 0x6, 1, 0, 1)
+#define MPP24_UA2_TXD        MPP(24, 0x4, 0, 0, 1)
+#define MPP24_TDM_INTn        MPP(24, 0x6, 0, 0, 1)
 #define MPP24_UNUSED        MPP(24, 0x1, 0, 0, 1)
 
 
 #define MPP25_GPIO        MPP(25, 0x0, 1, 1, 1)
-#define MPP25_UA2_RXD        MPP(25, 0x4, 1, 0, 1)
-#define MPP25_TDM_RSTn        MPP(25, 0x6, 0, 1, 1)
+#define MPP25_UA2_RXD        MPP(25, 0x4, 0, 0, 1)
+#define MPP25_TDM_RSTn        MPP(25, 0x6, 0, 0, 1)
 #define MPP25_UNUSED        MPP(25, 0x1, 0, 0, 1)
 
 
 #define MPP26_GPIO        MPP(26, 0x0, 1, 1, 1)
-#define MPP26_UA2_CTSn        MPP(26, 0x4, 1, 0, 1)
-#define MPP26_TDM_PCLK        MPP(26, 0x6, 1, 1, 1)
+#define MPP26_UA2_CTSn        MPP(26, 0x4, 0, 0, 1)
+#define MPP26_TDM_PCLK        MPP(26, 0x6, 0, 0, 1)
 #define MPP26_UNUSED        MPP(26, 0x1, 0, 0, 1)
 
 
 #define MPP27_GPIO        MPP(27, 0x0, 1, 1, 1)
-#define MPP27_UA2_RTSn        MPP(27, 0x4, 0, 1, 1)
-#define MPP27_TDM_FSYNC        MPP(27, 0x6, 1, 1, 1)
+#define MPP27_UA2_RTSn        MPP(27, 0x4, 0, 0, 1)
+#define MPP27_TDM_FSYNC        MPP(27, 0x6, 0, 0, 1)
 #define MPP27_UNUSED        MPP(27, 0x1, 0, 0, 1)
 
 
 #define MPP28_GPIO        MPP(28, 0x0, 1, 1, 1)
-#define MPP28_UA3_TXD        MPP(28, 0x4, 0, 1, 1)
-#define MPP28_TDM_DRX        MPP(28, 0x6, 1, 0, 1)
+#define MPP28_UA3_TXD        MPP(28, 0x4, 0, 0, 1)
+#define MPP28_TDM_DRX        MPP(28, 0x6, 0, 0, 1)
 #define MPP28_UNUSED        MPP(28, 0x1, 0, 0, 1)
 
 #define MPP29_GPIO        MPP(29, 0x0, 1, 1, 1)
-#define MPP29_UA3_RXD        MPP(29, 0x4, 1, 0, 1)
-#define MPP29_SYSRST_OUTn    MPP(29, 0x5, 0, 1, 1)
-#define MPP29_TDM_DTX        MPP(29, 0x6, 0, 1, 1)
+#define MPP29_UA3_RXD        MPP(29, 0x4, 0, 0, 1)
+#define MPP29_SYSRST_OUTn    MPP(29, 0x5, 0, 0, 1)
+#define MPP29_TDM_DTX        MPP(29, 0x6, 0, 0, 1)
 #define MPP29_UNUSED        MPP(29, 0x1, 0, 0, 1)
 
 #define MPP30_GPIO        MPP(30, 0x0, 1, 1, 1)
-#define MPP30_UA3_CTSn        MPP(30, 0x4, 1, 0, 1)
+#define MPP30_UA3_CTSn        MPP(30, 0x4, 0, 0, 1)
 #define MPP30_UNUSED        MPP(30, 0x1, 0, 0, 1)
 
 #define MPP31_GPIO        MPP(31, 0x0, 1, 1, 1)
-#define MPP31_UA3_RTSn        MPP(31, 0x4, 0, 1, 1)
-#define MPP31_TDM1_SCSn        MPP(31, 0x6, 0, 1, 1)
+#define MPP31_UA3_RTSn        MPP(31, 0x4, 0, 0, 1)
+#define MPP31_TDM1_SCSn        MPP(31, 0x6, 0, 0, 1)
 #define MPP31_UNUSED        MPP(31, 0x1, 0, 0, 1)
 
 
 #define MPP32_GPIO        MPP(32, 0x1, 1, 1, 1)
-#define MPP32_UA3_TDX        MPP(32, 0x4, 0, 1, 1)
-#define MPP32_SYSRST_OUTn    MPP(32, 0x5, 0, 1, 1)
-#define MPP32_TDM0_RXQ        MPP(32, 0x6, 0, 1, 1)
+#define MPP32_UA3_TDX        MPP(32, 0x4, 0, 0, 1)
+#define MPP32_SYSRST_OUTn    MPP(32, 0x5, 0, 0, 1)
+#define MPP32_TDM0_RXQ        MPP(32, 0x6, 0, 0, 1)
 #define MPP32_UNUSED        MPP(32, 0x3, 0, 0, 1)
 
 
 #define MPP33_GPIO        MPP(33, 0x1, 1, 1, 1)
-#define MPP33_UA3_RDX        MPP(33, 0x4, 1, 0, 1)
-#define MPP33_TDM0_TXQ        MPP(33, 0x6, 0, 1, 1)
+#define MPP33_UA3_RDX        MPP(33, 0x4, 0, 0, 1)
+#define MPP33_TDM0_TXQ        MPP(33, 0x6, 0, 0, 1)
 #define MPP33_UNUSED        MPP(33, 0x3, 0, 0, 1)
 
 
 
 #define MPP34_GPIO        MPP(34, 0x1, 1, 1, 1)
-#define MPP34_UA2_TDX        MPP(34, 0x4, 0, 1, 1)
-#define MPP34_TDM1_RXQ        MPP(34, 0x6, 0, 1, 1)
+#define MPP34_UA2_TDX        MPP(34, 0x4, 0, 0, 1)
+#define MPP34_TDM1_RXQ        MPP(34, 0x6, 0, 0, 1)
 #define MPP34_UNUSED        MPP(34, 0x3, 0, 0, 1)
 
 
 
 #define MPP35_GPIO        MPP(35, 0x1, 1, 1, 1)
-#define MPP35_UA2_RDX        MPP(35, 0x4, 1, 0, 1)
-#define MPP35_TDM1_TXQ        MPP(35, 0x6, 0, 1, 1)
+#define MPP35_UA2_RDX        MPP(35, 0x4, 0, 0, 1)
+#define MPP35_TDM1_TXQ        MPP(35, 0x6, 0, 0, 1)
 #define MPP35_UNUSED        MPP(35, 0x3, 0, 0, 1)
 
 #define MPP36_GPIO        MPP(36, 0x1, 1, 1, 1)
-#define MPP36_UA0_CTSn        MPP(36, 0x2, 1, 0, 1)
-#define MPP36_UA2_TDX        MPP(36, 0x4, 0, 1, 1)
-#define MPP36_TDM0_SCSn        MPP(36, 0x6, 0, 1, 1)
+#define MPP36_UA0_CTSn        MPP(36, 0x2, 0, 0, 1)
+#define MPP36_UA2_TDX        MPP(36, 0x4, 0, 0, 1)
+#define MPP36_TDM0_SCSn        MPP(36, 0x6, 0, 0, 1)
 #define MPP36_UNUSED        MPP(36, 0x3, 0, 0, 1)
 
 
 #define MPP37_GPIO        MPP(37, 0x1, 1, 1, 1)
-#define MPP37_UA0_RTSn        MPP(37, 0x2, 0, 1, 1)
-#define MPP37_UA2_RXD        MPP(37, 0x4, 1, 0, 1)
-#define MPP37_SYSRST_OUTn    MPP(37, 0x5, 0, 1, 1)
-#define MPP37_TDM_SCLK        MPP(37, 0x6, 0, 1, 1)
+#define MPP37_UA0_RTSn        MPP(37, 0x2, 0, 0, 1)
+#define MPP37_UA2_RXD        MPP(37, 0x4, 0, 0, 1)
+#define MPP37_SYSRST_OUTn    MPP(37, 0x5, 0, 0, 1)
+#define MPP37_TDM_SCLK        MPP(37, 0x6, 0, 0, 1)
 #define MPP37_UNUSED        MPP(37, 0x3, 0, 0, 1)
 
 
 
 
 #define MPP38_GPIO        MPP(38, 0x1, 1, 1, 1)
-#define MPP38_UA1_CTSn        MPP(38, 0x2, 1, 0, 1)
-#define MPP38_UA3_TXD        MPP(38, 0x4, 0, 1, 1)
-#define MPP38_SYSRST_OUTn    MPP(38, 0x5, 0, 1, 1)
-#define MPP38_TDM_SMOSI        MPP(38, 0x6, 0, 1, 1)
+#define MPP38_UA1_CTSn        MPP(38, 0x2, 0, 0, 1)
+#define MPP38_UA3_TXD        MPP(38, 0x4, 0, 0, 1)
+#define MPP38_SYSRST_OUTn    MPP(38, 0x5, 0, 0, 1)
+#define MPP38_TDM_SMOSI        MPP(38, 0x6, 0, 0, 1)
 #define MPP38_UNUSED        MPP(38, 0x3, 0, 0, 1)
 
 
 
 
 #define MPP39_GPIO        MPP(39, 0x1, 1, 1, 1)
-#define MPP39_UA1_RTSn        MPP(39, 0x2, 0, 1, 1)
-#define MPP39_UA3_RXD        MPP(39, 0x4, 1, 0, 1)
-#define MPP39_SYSRST_OUTn    MPP(39, 0x5, 0, 1, 1)
-#define MPP39_TDM_SMISO        MPP(39, 0x6, 1, 0, 1)
+#define MPP39_UA1_RTSn        MPP(39, 0x2, 0, 0, 1)
+#define MPP39_UA3_RXD        MPP(39, 0x4, 0, 0, 1)
+#define MPP39_SYSRST_OUTn    MPP(39, 0x5, 0, 0, 1)
+#define MPP39_TDM_SMISO        MPP(39, 0x6, 0, 0, 1)
 #define MPP39_UNUSED        MPP(39, 0x3, 0, 0, 1)
 
 
 
 #define MPP40_GPIO        MPP(40, 0x1, 1, 1, 1)
-#define MPP40_TDM_INTn        MPP(40, 0x6, 1, 0, 1)
+#define MPP40_TDM_INTn        MPP(40, 0x6, 0, 0, 1)
 #define MPP40_UNUSED        MPP(40, 0x0, 0, 0, 1)
 
 
 
 #define MPP41_GPIO        MPP(41, 0x1, 1, 1, 1)
-#define MPP41_TDM_RSTn        MPP(41, 0x6, 0, 1, 1)
+#define MPP41_TDM_RSTn        MPP(41, 0x6, 0, 0, 1)
 #define MPP41_UNUSED        MPP(41, 0x0, 0, 0, 1)
 
 
 
 #define MPP42_GPIO        MPP(42, 0x1, 1, 1, 1)
-#define MPP42_TDM_PCLK        MPP(42, 0x6, 1, 1, 1)
+#define MPP42_TDM_PCLK        MPP(42, 0x6, 0, 0, 1)
 #define MPP42_UNUSED        MPP(42, 0x0, 0, 0, 1)
 
 
 
 #define MPP43_GPIO        MPP(43, 0x1, 1, 1, 1)
-#define MPP43_TDM_FSYNC        MPP(43, 0x6, 1, 1, 1)
+#define MPP43_TDM_FSYNC        MPP(43, 0x6, 0, 0, 1)
 #define MPP43_UNUSED        MPP(43, 0x0, 0, 0, 1)
 
 
 
 #define MPP44_GPIO        MPP(44, 0x1, 1, 1, 1)
-#define MPP44_TDM_DRX        MPP(44, 0x6, 1, 0, 1)
+#define MPP44_TDM_DRX        MPP(44, 0x6, 0, 0, 1)
 #define MPP44_UNUSED        MPP(44, 0x0, 0, 0, 1)
 
 
 
 #define MPP45_GPIO        MPP(45, 0x1, 1, 1, 1)
-#define MPP45_SATA0_ACTn    MPP(45, 0x3, 0, 1, 1)
-#define MPP45_TDM_DRX        MPP(45, 0x6, 0, 1, 1)
+#define MPP45_SATA0_ACTn    MPP(45, 0x3, 0, 0, 1)
+#define MPP45_TDM_DRX        MPP(45, 0x6, 0, 0, 1)
 #define MPP45_UNUSED        MPP(45, 0x0, 0, 0, 1)
 
 
 #define MPP46_GPIO        MPP(46, 0x1, 1, 1, 1)
-#define MPP46_TDM_SCSn        MPP(46, 0x6, 0, 1, 1)
+#define MPP46_TDM_SCSn        MPP(46, 0x6, 0, 0, 1)
 #define MPP46_UNUSED        MPP(46, 0x0, 0, 0, 1)
 
 
@@ -323,14 +323,14 @@
 
 
 #define MPP48_GPIO        MPP(48, 0x1, 1, 1, 1)
-#define MPP48_SATA1_ACTn    MPP(48, 0x3, 0, 1, 1)
+#define MPP48_SATA1_ACTn    MPP(48, 0x3, 0, 0, 1)
 #define MPP48_UNUSED        MPP(48, 0x2, 0, 0, 1)
 
 
 
 #define MPP49_GPIO        MPP(49, 0x1, 1, 1, 1)
-#define MPP49_SATA0_ACTn    MPP(49, 0x3, 0, 1, 1)
-#define MPP49_M_BB        MPP(49, 0x4, 1, 0, 1)
+#define MPP49_SATA0_ACTn    MPP(49, 0x3, 0, 0, 1)
+#define MPP49_M_BB        MPP(49, 0x4, 0, 0, 1)
 #define MPP49_UNUSED        MPP(49, 0x2, 0, 0, 1)
 
 
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 309369e..be2002f 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -416,13 +416,13 @@
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 		omap1_usb_init(&innovator1510_usb_config);
-		innovator_config[1].data = &innovator1510_lcd_config;
+		innovator_config[0].data = &innovator1510_lcd_config;
 	}
 #endif
 #ifdef CONFIG_ARCH_OMAP16XX
 	if (cpu_is_omap1610()) {
 		omap1_usb_init(&h2_usb_config);
-		innovator_config[1].data = &innovator1610_lcd_config;
+		innovator_config[0].data = &innovator1610_lcd_config;
 	}
 #endif
 	omap_board_config = innovator_config;
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index d965da4..e20c8ab 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -364,8 +364,8 @@
 	  going on could result in system crashes;
 
 config OMAP4_ERRATA_I688
-	bool "OMAP4 errata: Async Bridge Corruption (BROKEN)"
-	depends on ARCH_OMAP4 && BROKEN
+	bool "OMAP4 errata: Async Bridge Corruption"
+	depends on ARCH_OMAP4
 	select ARCH_HAS_BARRIERS
 	help
 	  If a data is stalled inside asynchronous bridge because of back
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index fc9b238..bd76394 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -11,9 +11,9 @@
 					  omap_hwmod_common_data.o
 clock-common				= clock.o clock_common_data.o \
 					  clkt_dpll.o clkt_clksel.o
-secure-common                          = omap-smc.o omap-secure.o
+secure-common				= omap-smc.o omap-secure.o
 
-obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
 obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
 obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
 
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 21fc876..4e90715 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -814,7 +814,7 @@
 	.default_device	= &sdp4430_lcd_device,
 };
 
-static void omap_4430sdp_display_init(void)
+static void __init omap_4430sdp_display_init(void)
 {
 	int r;
 
@@ -851,7 +851,7 @@
 #define board_mux	NULL
  #endif
 
-static void omap4_sdp4430_wifi_mux_init(void)
+static void __init omap4_sdp4430_wifi_mux_init(void)
 {
 	omap_mux_init_gpio(GPIO_WIFI_IRQ, OMAP_PIN_INPUT |
 				OMAP_PIN_OFF_WAKEUPENABLE);
@@ -878,12 +878,17 @@
 	.board_tcxo_clock = WL12XX_TCXOCLOCK_26,
 };
 
-static void omap4_sdp4430_wifi_init(void)
+static void __init omap4_sdp4430_wifi_init(void)
 {
+	int ret;
+
 	omap4_sdp4430_wifi_mux_init();
-	if (wl12xx_set_platform_data(&omap4_sdp4430_wlan_data))
-		pr_err("Error setting wl12xx data\n");
-	platform_device_register(&omap_vwlan_device);
+	ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
+	if (ret)
+		pr_err("Error setting wl12xx data: %d\n", ret);
+	ret = platform_device_register(&omap_vwlan_device);
+	if (ret)
+		pr_err("Error registering wl12xx device: %d\n", ret);
 }
 
 static void __init omap_4430sdp_init(void)
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index e921e3b..d73316e 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -437,7 +437,7 @@
 	.reset_gpio_port[2]  = -EINVAL
 };
 
-static void cm_t35_init_usbh(void)
+static void  __init cm_t35_init_usbh(void)
 {
 	int err;
 
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index d587560..ad49762 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -17,6 +17,7 @@
 #include <linux/i2c/twl.h>
 
 #include <mach/hardware.h>
+#include <asm/hardware/gic.h>
 #include <asm/mach/arch.h>
 
 #include <plat/board.h>
@@ -102,6 +103,7 @@
 	.map_io		= omap242x_map_io,
 	.init_early	= omap2420_init_early,
 	.init_irq	= omap2_init_irq,
+	.handle_irq	= omap2_intc_handle_irq,
 	.init_machine	= omap_generic_init,
 	.timer		= &omap2_timer,
 	.dt_compat	= omap242x_boards_compat,
@@ -141,6 +143,7 @@
 	.map_io		= omap3_map_io,
 	.init_early	= omap3430_init_early,
 	.init_irq	= omap3_init_irq,
+	.handle_irq	= omap3_intc_handle_irq,
 	.init_machine	= omap3_init,
 	.timer		= &omap3_timer,
 	.dt_compat	= omap3_boards_compat,
@@ -160,6 +163,7 @@
 	.map_io		= omap4_map_io,
 	.init_early	= omap4430_init_early,
 	.init_irq	= gic_init_irq,
+	.handle_irq	= gic_handle_irq,
 	.init_machine	= omap4_init,
 	.timer		= &omap4_timer,
 	.dt_compat	= omap4_boards_compat,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 42a4d11..6722627 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -371,7 +371,11 @@
 	else
 		*openp = 0;
 
+#ifdef CONFIG_MMC_OMAP
 	omap_mmc_notify_cover_event(mmc_device, index, *openp);
+#else
+	pr_warn("MMC: notify cover event not available\n");
+#endif
 }
 
 static int n8x0_mmc_late_init(struct device *dev)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 003fe34..c877236 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -381,7 +381,7 @@
 	gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
 
 	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
-	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+	gpio_leds[0].gpio = gpio + TWL4030_GPIO_MAX + 1;
 
 	platform_device_register(&leds_gpio);
 
@@ -617,6 +617,21 @@
 	{ OMAP3_EVM_EHCI_SELECT, GPIOF_OUT_INIT_LOW,   "select EHCI port" },
 };
 
+static void __init omap3_evm_wl12xx_init(void)
+{
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+	int ret;
+
+	/* WL12xx WLAN Init */
+	ret = wl12xx_set_platform_data(&omap3evm_wlan_data);
+	if (ret)
+		pr_err("error setting wl12xx data: %d\n", ret);
+	ret = platform_device_register(&omap3evm_wlan_regulator);
+	if (ret)
+		pr_err("error registering wl12xx device: %d\n", ret);
+#endif
+}
+
 static void __init omap3_evm_init(void)
 {
 	omap3_evm_get_revision();
@@ -665,13 +680,7 @@
 	omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
 	omap3evm_init_smsc911x();
 	omap3_evm_display_init();
-
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
-	/* WL12xx WLAN Init */
-	if (wl12xx_set_platform_data(&omap3evm_wlan_data))
-		pr_err("error setting wl12xx data\n");
-	platform_device_register(&omap3evm_wlan_regulator);
-#endif
+	omap3_evm_wl12xx_init();
 }
 
 MACHINE_START(OMAP3EVM, "OMAP3 EVM")
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index b7779c20..28fc271 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -488,13 +488,15 @@
 static void __init omap4_panda_init(void)
 {
 	int package = OMAP_PACKAGE_CBS;
+	int ret;
 
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		package = OMAP_PACKAGE_CBL;
 	omap4_mux_init(board_mux, NULL, package);
 
-	if (wl12xx_set_platform_data(&omap_panda_wlan_data))
-		pr_err("error setting wl12xx data\n");
+	ret = wl12xx_set_platform_data(&omap_panda_wlan_data);
+	if (ret)
+		pr_err("error setting wl12xx data: %d\n", ret);
 
 	omap4_panda_i2c_init();
 	platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 8d7ce11..c126461 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -296,8 +296,10 @@
 
 void __init zoom_peripherals_init(void)
 {
-	if (wl12xx_set_platform_data(&omap_zoom_wlan_data))
-		pr_err("error setting wl12xx data\n");
+	int ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
+
+	if (ret)
+		pr_err("error setting wl12xx data: %d\n", ret);
 
 	omap_i2c_init();
 	platform_device_register(&omap_vwlan_device);
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index febffde..7e9338e 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -132,6 +132,7 @@
 void am33xx_map_io(void);
 void omap4_map_io(void);
 void ti81xx_map_io(void);
+void omap_barriers_init(void);
 
 /**
  * omap_test_timeout - busy-loop, testing a condition
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index cfdbb86..72e018b 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -65,7 +65,6 @@
 	struct timespec ts_preidle, ts_postidle, ts_idle;
 	u32 cpu1_state;
 	int idle_time;
-	int new_state_idx;
 	int cpu_id = smp_processor_id();
 
 	/* Used to keep track of the total time in idle */
@@ -84,8 +83,8 @@
 	 */
 	cpu1_state = pwrdm_read_pwrst(cpu1_pd);
 	if (cpu1_state != PWRDM_POWER_OFF) {
-		new_state_idx = drv->safe_state_index;
-		cx = cpuidle_get_statedata(&dev->states_usage[new_state_idx]);
+		index = drv->safe_state_index;
+		cx = cpuidle_get_statedata(&dev->states_usage[index]);
 	}
 
 	if (index > 0)
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
index 9970331..bbb870c 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -19,6 +19,8 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/smsc911x.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 
 #include <plat/board.h>
 #include <plat/gpmc.h>
@@ -42,6 +44,50 @@
 	.flags		= SMSC911X_USE_16BIT,
 };
 
+static struct regulator_consumer_supply gpmc_smsc911x_supply[] = {
+	REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+	REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+};
+
+/* Generic regulator definition to satisfy smsc911x */
+static struct regulator_init_data gpmc_smsc911x_reg_init_data = {
+	.constraints = {
+		.min_uV			= 3300000,
+		.max_uV			= 3300000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= ARRAY_SIZE(gpmc_smsc911x_supply),
+	.consumer_supplies	= gpmc_smsc911x_supply,
+};
+
+static struct fixed_voltage_config gpmc_smsc911x_fixed_reg_data = {
+	.supply_name		= "gpmc_smsc911x",
+	.microvolts		= 3300000,
+	.gpio			= -EINVAL,
+	.startup_delay		= 0,
+	.enable_high		= 0,
+	.enabled_at_boot	= 1,
+	.init_data		= &gpmc_smsc911x_reg_init_data,
+};
+
+/*
+ * Platform device id of 42 is a temporary fix to avoid conflicts
+ * with other reg-fixed-voltage devices. The real fix should
+ * involve the driver core providing a way of dynamically
+ * assigning a unique id on registration for platform devices
+ * in the same name space.
+ */
+static struct platform_device gpmc_smsc911x_regulator = {
+	.name		= "reg-fixed-voltage",
+	.id		= 42,
+	.dev = {
+		.platform_data	= &gpmc_smsc911x_fixed_reg_data,
+	},
+};
+
 /*
  * Initialize smsc911x device connected to the GPMC. Note that we
  * assume that pin multiplexing is done in the board-*.c file,
@@ -55,6 +101,12 @@
 
 	gpmc_cfg = board_data;
 
+	ret = platform_device_register(&gpmc_smsc911x_regulator);
+	if (ret < 0) {
+		pr_err("Unable to register smsc911x regulators: %d\n", ret);
+		return;
+	}
+
 	if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
 		pr_err("Failed to request GPMC mem region\n");
 		return;
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index ad0adb5..19dd165 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -293,8 +293,8 @@
 	}
 }
 
-static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
-					struct omap_mmc_platform_data *mmc)
+static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
+				 struct omap_mmc_platform_data *mmc)
 {
 	char *hc_name;
 
@@ -428,9 +428,10 @@
 	return 0;
 }
 
+static int omap_hsmmc_done;
 #define MAX_OMAP_MMC_HWMOD_NAME_LEN		16
 
-void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
+void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
 {
 	struct omap_hwmod *oh;
 	struct platform_device *pdev;
@@ -487,10 +488,15 @@
 	kfree(mmc_data);
 }
 
-void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
+void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	u32 reg;
 
+	if (omap_hsmmc_done)
+		return;
+
+	omap_hsmmc_done = 1;
+
 	if (!cpu_is_omap44xx()) {
 		if (cpu_is_omap2430()) {
 			control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index eb50c29..fb11b44 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -307,6 +307,7 @@
 void __init omap44xx_map_common_io(void)
 {
 	iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
+	omap_barriers_init();
 }
 #endif
 
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index 609ea2d..2cc1aa0 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -281,8 +281,16 @@
 	.ops	= &omap2_mbox_ops,
 	.priv	= &omap2_mbox_iva_priv,
 };
+#endif
 
-struct omap_mbox *omap2_mboxes[] = { &mbox_dsp_info, &mbox_iva_info, NULL };
+#ifdef CONFIG_ARCH_OMAP2
+struct omap_mbox *omap2_mboxes[] = {
+	&mbox_dsp_info,
+#ifdef CONFIG_SOC_OMAP2420
+	&mbox_iva_info,
+#endif
+	NULL
+};
 #endif
 
 #if defined(CONFIG_ARCH_OMAP4)
@@ -412,7 +420,8 @@
 	platform_driver_unregister(&omap2_mbox_driver);
 }
 
-module_init(omap2_mbox_init);
+/* must be ready before omap3isp is probed */
+subsys_initcall(omap2_mbox_init);
 module_exit(omap2_mbox_exit);
 
 MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index e1cc75d..611a0e3 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -100,8 +100,8 @@
 
 static char *omap_mux_options;
 
-static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
-				      int gpio, int val)
+static int _omap_mux_init_gpio(struct omap_mux_partition *partition,
+			       int gpio, int val)
 {
 	struct omap_mux_entry *e;
 	struct omap_mux *gpio_mux = NULL;
@@ -145,7 +145,7 @@
 	return 0;
 }
 
-int __init omap_mux_init_gpio(int gpio, int val)
+int omap_mux_init_gpio(int gpio, int val)
 {
 	struct omap_mux_partition *partition;
 	int ret;
@@ -159,9 +159,9 @@
 	return -ENODEV;
 }
 
-static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
-					const char *muxname,
-					struct omap_mux **found_mux)
+static int _omap_mux_get_by_name(struct omap_mux_partition *partition,
+				 const char *muxname,
+				 struct omap_mux **found_mux)
 {
 	struct omap_mux *mux = NULL;
 	struct omap_mux_entry *e;
@@ -218,7 +218,7 @@
 	return -ENODEV;
 }
 
-static int __init
+static int
 omap_mux_get_by_name(const char *muxname,
 			struct omap_mux_partition **found_partition,
 			struct omap_mux **found_mux)
@@ -240,7 +240,7 @@
 	return -ENODEV;
 }
 
-int __init omap_mux_init_signal(const char *muxname, int val)
+int omap_mux_init_signal(const char *muxname, int val)
 {
 	struct omap_mux_partition *partition = NULL;
 	struct omap_mux *mux = NULL;
@@ -1094,8 +1094,8 @@
 		omap_mux_package_init_balls(package_balls, superset);
 }
 
-static void omap_mux_init_signals(struct omap_mux_partition *partition,
-				  struct omap_board_mux *board_mux)
+static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
+					 struct omap_board_mux *board_mux)
 {
 	omap_mux_set_cmdline_signals();
 	omap_mux_write_array(partition, board_mux);
@@ -1109,8 +1109,8 @@
 {
 }
 
-static void omap_mux_init_signals(struct omap_mux_partition *partition,
-				  struct omap_board_mux *board_mux)
+static void __init omap_mux_init_signals(struct omap_mux_partition *partition,
+					 struct omap_board_mux *board_mux)
 {
 }
 
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index b13ef7e..503ac77 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -18,6 +18,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
+	__CPUINIT
 /*
  * OMAP4 specific entry point for secondary CPU to jump from ROM
  * code.  This routine also provides a holding flag into which
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 40a8fbc..ebc5950 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -24,6 +24,7 @@
 
 #include <plat/irqs.h>
 #include <plat/sram.h>
+#include <plat/omap-secure.h>
 
 #include <mach/hardware.h>
 #include <mach/omap-wakeupgen.h>
@@ -43,6 +44,9 @@
 
 void __iomem *dram_sync, *sram_sync;
 
+static phys_addr_t paddr;
+static u32 size;
+
 void omap_bus_sync(void)
 {
 	if (dram_sync && sram_sync) {
@@ -52,18 +56,20 @@
 	}
 }
 
-static int __init omap_barriers_init(void)
+/* Steal one page physical memory for barrier implementation */
+int __init omap_barrier_reserve_memblock(void)
 {
-	struct map_desc dram_io_desc[1];
-	phys_addr_t paddr;
-	u32 size;
-
-	if (!cpu_is_omap44xx())
-		return -ENODEV;
 
 	size = ALIGN(PAGE_SIZE, SZ_1M);
 	paddr = arm_memblock_steal(size, SZ_1M);
 
+	return 0;
+}
+
+void __init omap_barriers_init(void)
+{
+	struct map_desc dram_io_desc[1];
+
 	dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
 	dram_io_desc[0].pfn = __phys_to_pfn(paddr);
 	dram_io_desc[0].length = size;
@@ -75,9 +81,10 @@
 	pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
 		(long long) paddr, dram_io_desc[0].virtual);
 
-	return 0;
 }
-core_initcall(omap_barriers_init);
+#else
+void __init omap_barriers_init(void)
+{}
 #endif
 
 void __init gic_init_irq(void)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 5192cab..eba6cd3 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1517,8 +1517,8 @@
 	if (oh->_state != _HWMOD_STATE_INITIALIZED &&
 	    oh->_state != _HWMOD_STATE_IDLE &&
 	    oh->_state != _HWMOD_STATE_DISABLED) {
-		WARN(1, "omap_hwmod: %s: enabled state can only be entered "
-		     "from initialized, idle, or disabled state\n", oh->name);
+		WARN(1, "omap_hwmod: %s: enabled state can only be entered from initialized, idle, or disabled state\n",
+			oh->name);
 		return -EINVAL;
 	}
 
@@ -1600,8 +1600,8 @@
 	pr_debug("omap_hwmod: %s: idling\n", oh->name);
 
 	if (oh->_state != _HWMOD_STATE_ENABLED) {
-		WARN(1, "omap_hwmod: %s: idle state can only be entered from "
-		     "enabled state\n", oh->name);
+		WARN(1, "omap_hwmod: %s: idle state can only be entered from enabled state\n",
+			oh->name);
 		return -EINVAL;
 	}
 
@@ -1682,8 +1682,8 @@
 
 	if (oh->_state != _HWMOD_STATE_IDLE &&
 	    oh->_state != _HWMOD_STATE_ENABLED) {
-		WARN(1, "omap_hwmod: %s: disabled state can only be entered "
-		     "from idle, or enabled state\n", oh->name);
+		WARN(1, "omap_hwmod: %s: disabled state can only be entered from idle, or enabled state\n",
+			oh->name);
 		return -EINVAL;
 	}
 
@@ -2240,8 +2240,8 @@
 	BUG_ON(!oh);
 
 	if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
-		WARN(1, "omap_device: %s: OCP barrier impossible due to "
-		      "device configuration\n", oh->name);
+		WARN(1, "omap_device: %s: OCP barrier impossible due to device configuration\n",
+			oh->name);
 		return;
 	}
 
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 1881fe9..5a65dd0 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -174,14 +174,17 @@
 	freq = clk->rate;
 	clk_put(clk);
 
+	rcu_read_lock();
 	opp = opp_find_freq_ceil(dev, &freq);
 	if (IS_ERR(opp)) {
+		rcu_read_unlock();
 		pr_err("%s: unable to find boot up OPP for vdd_%s\n",
 			__func__, vdd_name);
 		goto exit;
 	}
 
 	bootup_volt = opp_get_voltage(opp);
+	rcu_read_unlock();
 	if (!bootup_volt) {
 		pr_err("%s: unable to find voltage corresponding "
 			"to the bootup OPP for vdd_%s\n", __func__, vdd_name);
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index b8822f8..23de98d 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -82,13 +82,7 @@
 	f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
 	f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
 
-	/* Ignore UART clocks.  These are handled by UART core (serial.c) */
-	f1 &= ~(OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_UART2_MASK);
-	f2 &= ~OMAP24XX_EN_UART3_MASK;
-
-	if (f1 | f2)
-		return 1;
-	return 0;
+	return (f1 | f2) ? 1 : 0;
 }
 
 static void omap2_enter_full_retention(void)
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 33dd655..a1d6154 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -19,6 +19,7 @@
 
 #include "common.h"
 #include <plat/cpu.h>
+#include <plat/irqs.h>
 #include <plat/prcm.h>
 
 #include "vp.h"
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 247d894..f590afc 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -107,18 +107,18 @@
 	omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
 }
 
-static void omap_uart_set_forceidle(struct platform_device *pdev)
+static void omap_uart_set_smartidle(struct platform_device *pdev)
 {
 	struct omap_device *od = to_omap_device(pdev);
 
-	omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE);
+	omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART);
 }
 
 #else
 static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
 {}
 static void omap_uart_set_noidle(struct platform_device *pdev) {}
-static void omap_uart_set_forceidle(struct platform_device *pdev) {}
+static void omap_uart_set_smartidle(struct platform_device *pdev) {}
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_OMAP_MUX
@@ -349,7 +349,7 @@
 	omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
 	omap_up.flags = UPF_BOOT_AUTOCONF;
 	omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
-	omap_up.set_forceidle = omap_uart_set_forceidle;
+	omap_up.set_forceidle = omap_uart_set_smartidle;
 	omap_up.set_noidle = omap_uart_set_noidle;
 	omap_up.enable_wakeup = omap_uart_enable_wakeup;
 	omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 771dc78..f51348d 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -486,7 +486,7 @@
 void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
 {
 	struct omap_hwmod	*oh[2];
-	struct omap_device	*od;
+	struct platform_device	*pdev;
 	int			bus_id = -1;
 	int			i;
 
@@ -522,11 +522,11 @@
 		return;
 	}
 
-	od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
+	pdev = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
 				(void *)&usbhs_data, sizeof(usbhs_data),
 				omap_uhhtll_latency,
 				ARRAY_SIZE(omap_uhhtll_latency), false);
-	if (IS_ERR(od)) {
+	if (IS_ERR(pdev)) {
 		pr_err("Could not build hwmod devices %s,%s\n",
 			USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
 		return;
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 031d116..175b7d8 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -247,7 +247,7 @@
  * omap_vc_i2c_init - initialize I2C interface to PMIC
  * @voltdm: voltage domain containing VC data
  *
- * Use PMIC supplied seetings for I2C high-speed mode and
+ * Use PMIC supplied settings for I2C high-speed mode and
  * master code (if set) and program the VC I2C configuration
  * register.
  *
@@ -265,8 +265,8 @@
 
 	if (initialized) {
 		if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
-			pr_warn("%s: I2C config for all channels must match.",
-				__func__);
+			pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).",
+				__func__, voltdm->name, i2c_high_speed);
 		return;
 	}
 
@@ -292,9 +292,7 @@
 	u32 val;
 
 	if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
-		pr_err("%s: PMIC info requried to configure vc for"
-			"vdd_%s not populated.Hence cannot initialize vc\n",
-			__func__, voltdm->name);
+		pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name);
 		return;
 	}
 
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index c005e2f..57db203 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -108,6 +108,7 @@
 	 * XXX Will depend on the process, validation, and binning
 	 * for the currently-running IC
 	 */
+#ifdef CONFIG_PM_OPP
 	if (cpu_is_omap3630()) {
 		omap3_voltdm_mpu.volt_data = omap36xx_vddmpu_volt_data;
 		omap3_voltdm_core.volt_data = omap36xx_vddcore_volt_data;
@@ -115,6 +116,7 @@
 		omap3_voltdm_mpu.volt_data = omap34xx_vddmpu_volt_data;
 		omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
 	}
+#endif
 
 	if (cpu_is_omap3517() || cpu_is_omap3505())
 		voltdms = voltagedomains_am35xx;
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index 4e11d02..c3115f6 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -100,9 +100,11 @@
 	 * XXX Will depend on the process, validation, and binning
 	 * for the currently-running IC
 	 */
+#ifdef CONFIG_PM_OPP
 	omap4_voltdm_mpu.volt_data = omap44xx_vdd_mpu_volt_data;
 	omap4_voltdm_iva.volt_data = omap44xx_vdd_iva_volt_data;
 	omap4_voltdm_core.volt_data = omap44xx_vdd_core_volt_data;
+#endif
 
 	for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
 		voltdm->sys_clk.name = sys_clk_name;
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index 807391d..0df8882 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -41,6 +41,11 @@
 	u32 val, sys_clk_rate, timeout, waittime;
 	u32 vddmin, vddmax, vstepmin, vstepmax;
 
+	if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+		pr_err("%s: No PMIC info for vdd_%s\n", __func__, voltdm->name);
+		return;
+	}
+
 	if (!voltdm->read || !voltdm->write) {
 		pr_err("%s: No read/write API for accessing vdd_%s regs\n",
 			__func__, voltdm->name);
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 0e28bae..5dad38e 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -29,6 +29,7 @@
 #include <mach/hardware.h>
 #include <mach/orion5x.h>
 #include <plat/orion_nand.h>
+#include <plat/ehci-orion.h>
 #include <plat/time.h>
 #include <plat/common.h>
 #include <plat/addr-map.h>
@@ -72,7 +73,8 @@
  ****************************************************************************/
 void __init orion5x_ehci0_init(void)
 {
-	orion_ehci_init(ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL);
+	orion_ehci_init(ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL,
+			EHCI_PHY_ORION);
 }
 
 
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index fb9b62d..208eef1 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -45,6 +45,7 @@
 #include <mach/hx4700.h>
 #include <mach/irda.h>
 
+#include <sound/ak4641.h>
 #include <video/platform_lcd.h>
 #include <video/w100fb.h>
 
@@ -765,6 +766,28 @@
 };
 
 /*
+ * Asahi Kasei AK4641 on I2C
+ */
+
+static struct ak4641_platform_data ak4641_info = {
+	.gpio_power = GPIO27_HX4700_CODEC_ON,
+	.gpio_npdn  = GPIO109_HX4700_CODEC_nPDN,
+};
+
+static struct i2c_board_info i2c_board_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("ak4641", 0x12),
+		.platform_data = &ak4641_info,
+	},
+};
+
+static struct platform_device audio = {
+	.name	= "hx4700-audio",
+	.id	= -1,
+};
+
+
+/*
  * PCMCIA
  */
 
@@ -790,6 +813,7 @@
 	&gpio_vbus,
 	&power_supply,
 	&strataflash,
+	&audio,
 	&pcmcia,
 };
 
@@ -827,6 +851,7 @@
 	pxa_set_ficp_info(&ficp_info);
 	pxa27x_set_i2c_power_info(NULL);
 	pxa_set_i2c_info(NULL);
+	i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info));
 	i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));
 	pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
 	spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 91e4f6c..00d6eac 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -25,7 +25,6 @@
 #include <linux/suspend.h>
 #include <linux/syscore_ops.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
 
 #include <asm/mach/map.h>
 #include <asm/suspend.h>
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index aed6cbc..c1673b3 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -22,7 +22,6 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/i2c/pxa-i2c.h>
-#include <linux/gpio.h>
 
 #include <asm/mach/map.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c
index febc809..5aded5e 100644
--- a/arch/arm/mach-pxa/saarb.c
+++ b/arch/arm/mach-pxa/saarb.c
@@ -15,7 +15,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/mfd/88pm860x.h>
-#include <linux/gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 8d5168d..30989ba 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -168,6 +168,7 @@
 #define MAXCTRL_SEL_SH   4
 #define MAXCTRL_STR      (1u << 7)
 
+extern int max1111_read_channel(int);
 /*
  * Read MAX1111 ADC
  */
@@ -177,8 +178,6 @@
 	if (machine_is_tosa())
 	    return 0;
 
-	extern int max1111_read_channel(int);
-
 	/* max1111 accepts channels from 0-3, however,
 	 * it is encoded from 0-7 here in the code.
 	 */
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 34cbdac..438f02f 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -172,10 +172,9 @@
 static unsigned long spitz_charger_wakeup(void)
 {
 	unsigned long ret;
-	ret = (!gpio_get_value(SPITZ_GPIO_KEY_INT)
+	ret = ((!gpio_get_value(SPITZ_GPIO_KEY_INT)
 		<< GPIO_bit(SPITZ_GPIO_KEY_INT))
-		| (!gpio_get_value(SPITZ_GPIO_SYNC)
-		<< GPIO_bit(SPITZ_GPIO_SYNC));
+		| gpio_get_value(SPITZ_GPIO_SYNC));
 	return ret;
 }
 
diff --git a/arch/arm/mach-s3c2410/cpu-freq.c b/arch/arm/mach-s3c2410/cpu-freq.c
index 7dc6c46..5404535 100644
--- a/arch/arm/mach-s3c2410/cpu-freq.c
+++ b/arch/arm/mach-s3c2410/cpu-freq.c
@@ -115,7 +115,8 @@
 	.debug_io_show	= s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
 };
 
-static int s3c2410_cpufreq_add(struct device *dev)
+static int s3c2410_cpufreq_add(struct device *dev,
+			       struct subsys_interface *sif)
 {
 	return s3c_cpufreq_register(&s3c2410_cpufreq_info);
 }
@@ -133,7 +134,8 @@
 
 arch_initcall(s3c2410_cpufreq_init);
 
-static int s3c2410a_cpufreq_add(struct device *dev)
+static int s3c2410a_cpufreq_add(struct device *dev,
+				struct subsys_interface *sif)
 {
 	/* alter the maximum freq settings for S3C2410A. If a board knows
 	 * it only has a maximum of 200, then it should register its own
@@ -144,7 +146,7 @@
 	s3c2410_cpufreq_info.max.pclk =  66500000;
 	s3c2410_cpufreq_info.name = "s3c2410a";
 
-	return s3c2410_cpufreq_add(dev);
+	return s3c2410_cpufreq_add(dev, sif);
 }
 
 static struct subsys_interface s3c2410a_cpufreq_interface = {
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 2afd000..4803338 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -132,7 +132,8 @@
 	},
 };
 
-static int __init s3c2410_dma_add(struct device *dev)
+static int __init s3c2410_dma_add(struct device *dev,
+				  struct subsys_interface *sif)
 {
 	s3c2410_dma_init();
 	s3c24xx_dma_order_set(&s3c2410_dma_order);
@@ -148,7 +149,7 @@
 
 static int __init s3c2410_dma_drvinit(void)
 {
-	return subsys_interface_register(&s3c2410_interface);
+	return subsys_interface_register(&s3c2410_dma_interface);
 }
 
 arch_initcall(s3c2410_dma_drvinit);
diff --git a/arch/arm/mach-s3c2410/pll.c b/arch/arm/mach-s3c2410/pll.c
index c07438b..e0b3b34 100644
--- a/arch/arm/mach-s3c2410/pll.c
+++ b/arch/arm/mach-s3c2410/pll.c
@@ -66,7 +66,7 @@
     { .frequency = 270000000, .index = PLLVAL(127, 1, 1),  },
 };
 
-static int s3c2410_plls_add(struct device *dev)
+static int s3c2410_plls_add(struct device *dev, struct subsys_interface *sif)
 {
 	return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz));
 }
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index fda5385..03f706d 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -111,7 +111,7 @@
 	.resume		= s3c2410_pm_resume,
 };
 
-static int s3c2410_pm_add(struct device *dev)
+static int s3c2410_pm_add(struct device *dev, struct subsys_interface *sif)
 {
 	pm_cpu_prep = s3c2410_pm_prepare;
 	pm_cpu_sleep = s3c2410_cpu_suspend;
diff --git a/arch/arm/mach-s3c2412/cpu-freq.c b/arch/arm/mach-s3c2412/cpu-freq.c
index d8664b7..125be7d 100644
--- a/arch/arm/mach-s3c2412/cpu-freq.c
+++ b/arch/arm/mach-s3c2412/cpu-freq.c
@@ -194,7 +194,8 @@
 	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs),
 };
 
-static int s3c2412_cpufreq_add(struct device *dev)
+static int s3c2412_cpufreq_add(struct device *dev,
+			       struct subsys_interface *sif)
 {
 	unsigned long fclk_rate;
 
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index 142acd3..38472ac 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -159,7 +159,8 @@
 	.map_size	= ARRAY_SIZE(s3c2412_dma_mappings),
 };
 
-static int __init s3c2412_dma_add(struct device *dev)
+static int __init s3c2412_dma_add(struct device *dev,
+				  struct subsys_interface *sif)
 {
 	s3c2410_dma_init();
 	return s3c24xx_dma_init_map(&s3c2412_dma_sel);
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index a8a46c1..e65619d 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -170,7 +170,7 @@
 
 static struct irq_chip s3c2412_irq_rtc_chip;
 
-static int s3c2412_irq_add(struct device *dev)
+static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif)
 {
 	unsigned int irqno;
 
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
index d1adfa6..d045885 100644
--- a/arch/arm/mach-s3c2412/pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -56,7 +56,7 @@
 {
 }
 
-static int s3c2412_pm_add(struct device *dev)
+static int s3c2412_pm_add(struct device *dev, struct subsys_interface *sif)
 {
 	pm_cpu_prep = s3c2412_pm_prepare;
 	pm_cpu_sleep = s3c2412_cpu_suspend;
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
index 36df761..fd49f35 100644
--- a/arch/arm/mach-s3c2416/irq.c
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -213,7 +213,8 @@
 	return 0;
 }
 
-static int __init s3c2416_irq_add(struct device *dev)
+static int __init s3c2416_irq_add(struct device *dev,
+				  struct subsys_interface *sif)
 {
 	printk(KERN_INFO "S3C2416: IRQ Support\n");
 
diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c
index 3bdb15a..1bd4817 100644
--- a/arch/arm/mach-s3c2416/pm.c
+++ b/arch/arm/mach-s3c2416/pm.c
@@ -48,7 +48,7 @@
 	__raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
 }
 
-static int s3c2416_pm_add(struct device *dev)
+static int s3c2416_pm_add(struct device *dev, struct subsys_interface *sif)
 {
 	pm_cpu_prep = s3c2416_pm_prepare;
 	pm_cpu_sleep = s3c2416_cpu_suspend;
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index bedbc87..414364e 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -149,7 +149,7 @@
 	CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
 };
 
-static int s3c2440_clk_add(struct device *dev)
+static int s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
 {
 	struct clk *clock_upll;
 	struct clk *clock_h;
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
index 15b1ddf..5f0a0c8 100644
--- a/arch/arm/mach-s3c2440/dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -174,7 +174,8 @@
 	},
 };
 
-static int __init s3c2440_dma_add(struct device *dev)
+static int __init s3c2440_dma_add(struct device *dev,
+				  struct subsys_interface *sif)
 {
 	s3c2410_dma_init();
 	s3c24xx_dma_order_set(&s3c2440_dma_order);
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 4fee9bc..4a18cde 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -92,7 +92,7 @@
 	.irq_ack	= s3c_irq_wdtac97_ack,
 };
 
-static int s3c2440_irq_add(struct device *dev)
+static int s3c2440_irq_add(struct device *dev, struct subsys_interface *sif)
 {
 	unsigned int irqno;
 
diff --git a/arch/arm/mach-s3c2440/s3c2440-cpufreq.c b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c
index cf75966..6177676 100644
--- a/arch/arm/mach-s3c2440/s3c2440-cpufreq.c
+++ b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c
@@ -270,7 +270,8 @@
 	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
 };
 
-static int s3c2440_cpufreq_add(struct device *dev)
+static int s3c2440_cpufreq_add(struct device *dev,
+			       struct subsys_interface *sif)
 {
 	xtal = s3c_cpufreq_clk_get(NULL, "xtal");
 	hclk = s3c_cpufreq_clk_get(NULL, "hclk");
diff --git a/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c b/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
index b5368ae..551fb43 100644
--- a/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
+++ b/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
@@ -51,7 +51,7 @@
 	{ .frequency = 400000000,	.index = PLLVAL(0x5c, 1, 1),  }, 	/* FVco 800.000000 */
 };
 
-static int s3c2440_plls12_add(struct device *dev)
+static int s3c2440_plls12_add(struct device *dev, struct subsys_interface *sif)
 {
 	struct clk *xtal_clk;
 	unsigned long xtal;
diff --git a/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c b/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
index 42f2b5c..3f15bcf 100644
--- a/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
+++ b/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
@@ -79,7 +79,8 @@
 	{ .frequency = 402192000,	.index = PLLVAL(87, 2, 1), 	}, 	/* FVco 804.384000 */
 };
 
-static int s3c2440_plls169344_add(struct device *dev)
+static int s3c2440_plls169344_add(struct device *dev,
+				  struct subsys_interface *sif)
 {
 	struct clk *xtal_clk;
 	unsigned long xtal;
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c
index 8004e04..22cb7c9 100644
--- a/arch/arm/mach-s3c2440/s3c2442.c
+++ b/arch/arm/mach-s3c2440/s3c2442.c
@@ -122,7 +122,7 @@
 	},
 };
 
-static int s3c2442_clk_add(struct device *dev)
+static int s3c2442_clk_add(struct device *dev, struct subsys_interface *sif)
 {
 	struct clk *clock_upll;
 	struct clk *clock_h;
diff --git a/arch/arm/mach-s3c2440/s3c244x-clock.c b/arch/arm/mach-s3c2440/s3c244x-clock.c
index b3fdbdd..6d9b688 100644
--- a/arch/arm/mach-s3c2440/s3c244x-clock.c
+++ b/arch/arm/mach-s3c2440/s3c244x-clock.c
@@ -72,7 +72,7 @@
 	},
 };
 
-static int s3c244x_clk_add(struct device *dev)
+static int s3c244x_clk_add(struct device *dev, struct subsys_interface *sif)
 {
 	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
 	unsigned long clkdivn;
diff --git a/arch/arm/mach-s3c2440/s3c244x-irq.c b/arch/arm/mach-s3c2440/s3c244x-irq.c
index 74d3dcf..5fe8e58 100644
--- a/arch/arm/mach-s3c2440/s3c244x-irq.c
+++ b/arch/arm/mach-s3c2440/s3c244x-irq.c
@@ -91,7 +91,7 @@
 	.irq_ack	= s3c_irq_cam_ack,
 };
 
-static int s3c244x_irq_add(struct device *dev)
+static int s3c244x_irq_add(struct device *dev, struct subsys_interface *sif)
 {
 	unsigned int irqno;
 
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
index de6b4a2..1422451 100644
--- a/arch/arm/mach-s3c2443/dma.c
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -135,7 +135,8 @@
 	.map_size	= ARRAY_SIZE(s3c2443_dma_mappings),
 };
 
-static int __init s3c2443_dma_add(struct device *dev)
+static int __init s3c2443_dma_add(struct device *dev,
+				  struct subsys_interface *sif)
 {
 	s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
 	return s3c24xx_dma_init_map(&s3c2443_dma_sel);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 35e4ff2..ac2829f 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -241,7 +241,8 @@
 	return 0;
 }
 
-static int __init s3c2443_irq_add(struct device *dev)
+static int __init s3c2443_irq_add(struct device *dev,
+				  struct subsys_interface *sif)
 {
 	printk("S3C2443: IRQ Support\n");
 
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 31bb27d..aebbcc2 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -138,6 +138,11 @@
 		.ctrlbit	= S3C_CLKCON_PCLK_TSADC,
 	}, {
 		.name		= "i2c",
+#ifdef CONFIG_S3C_DEV_I2C1
+		.devname        = "s3c2440-i2c.0",
+#else
+		.devname	= "s3c2440-i2c",
+#endif
 		.parent		= &clk_p,
 		.enable		= s3c64xx_pclk_ctrl,
 		.ctrlbit	= S3C_CLKCON_PCLK_IIC,
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index 4a7394d..bee7dcd 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -49,7 +49,7 @@
 
 /* uart registration process */
 
-void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
 	s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
 }
diff --git a/arch/arm/mach-s5p64x0/pm.c b/arch/arm/mach-s5p64x0/pm.c
index 23f9b22..9cba18b 100644
--- a/arch/arm/mach-s5p64x0/pm.c
+++ b/arch/arm/mach-s5p64x0/pm.c
@@ -160,7 +160,7 @@
 
 }
 
-static int s5p64x0_pm_add(struct device *dev)
+static int s5p64x0_pm_add(struct device *dev, struct subsys_interface *sif)
 {
 	pm_cpu_prep = s5p64x0_pm_prepare;
 	pm_cpu_sleep = s5p64x0_cpu_suspend;
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index c78dfdd..b9ec0c3 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -175,7 +175,7 @@
 	return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
 }
 
-static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
+static int s5pv210_clk_hdmiphy_ctrl(struct clk *clk, int enable)
 {
 	return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
 }
@@ -372,7 +372,7 @@
 	}, {
 		.name		= "hdmiphy",
 		.devname	= "s5pv210-hdmi",
-		.enable		= exynos4_clk_hdmiphy_ctrl,
+		.enable		= s5pv210_clk_hdmiphy_ctrl,
 		.ctrlbit	= (1 << 0),
 	}, {
 		.name		= "dacphy",
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
index 677c71c..736bfb1 100644
--- a/arch/arm/mach-s5pv210/pm.c
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -133,7 +133,7 @@
 	s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
 }
 
-static int s5pv210_pm_add(struct device *dev)
+static int s5pv210_pm_add(struct device *dev, struct subsys_interface *sif)
 {
 	pm_cpu_prep = s5pv210_pm_prepare;
 	pm_cpu_sleep = s5pv210_cpu_suspend;
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index eff8a96..33dad1d 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -30,6 +30,7 @@
 #include <linux/serial_sci.h>
 #include <linux/smsc911x.h>
 #include <linux/gpio.h>
+#include <linux/videodev2.h>
 #include <linux/input.h>
 #include <linux/input/sh_keysc.h>
 #include <linux/mmc/host.h>
@@ -37,7 +38,6 @@
 #include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/mfd/tmio.h>
 #include <linux/sh_clk.h>
-#include <linux/dma-mapping.h>
 #include <video/sh_mobile_lcdc.h>
 #include <video/sh_mipi_dsi.h>
 #include <sound/sh_fsi.h>
@@ -159,19 +159,12 @@
 	},
 };
 
-static struct sh_mmcif_dma sh_mmcif_dma = {
-	.chan_priv_rx	= {
-		.slave_id	= SHDMA_SLAVE_MMCIF_RX,
-	},
-	.chan_priv_tx	= {
-		.slave_id	= SHDMA_SLAVE_MMCIF_TX,
-	},
-};
 static struct sh_mmcif_plat_data sh_mmcif_platdata = {
 	.sup_pclk	= 0,
 	.ocr		= MMC_VDD_165_195,
 	.caps		= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
-	.dma		= &sh_mmcif_dma,
+	.slave_id_tx	= SHDMA_SLAVE_MMCIF_TX,
+	.slave_id_rx	= SHDMA_SLAVE_MMCIF_RX,
 };
 
 static struct platform_device mmc_device = {
@@ -236,16 +229,6 @@
 	gpio_set_value(GPIO_PORT235, 1);
 }
 
-static void lcd_on(void *board_data, struct fb_info *info)
-{
-	lcd_backlight_on();
-}
-
-static void lcd_off(void *board_data)
-{
-	lcd_backlight_reset();
-}
-
 /* LCDC0 */
 static const struct fb_videomode lcdc0_modes[] = {
 	{
@@ -269,14 +252,14 @@
 		.interface_type = RGB24,
 		.clock_divider = 1,
 		.flags = LCDC_FLAGS_DWPOL,
-		.lcd_size_cfg.width = 44,
-		.lcd_size_cfg.height = 79,
 		.fourcc = V4L2_PIX_FMT_RGB565,
-		.lcd_cfg = lcdc0_modes,
-		.num_cfg = ARRAY_SIZE(lcdc0_modes),
-		.board_cfg = {
-			.display_on = lcd_on,
-			.display_off = lcd_off,
+		.lcd_modes = lcdc0_modes,
+		.num_modes = ARRAY_SIZE(lcdc0_modes),
+		.panel_cfg = {
+			.width = 44,
+			.height = 79,
+			.display_on = lcd_backlight_on,
+			.display_off = lcd_backlight_reset,
 		},
 	}
 };
@@ -321,12 +304,11 @@
 	},
 };
 
-#define DSI0PHYCR	0xe615006c
 static int sh_mipi_set_dot_clock(struct platform_device *pdev,
 				 void __iomem *base,
 				 int enable)
 {
-	struct clk *pck;
+	struct clk *pck, *phy;
 	int ret;
 
 	pck = clk_get(&pdev->dev, "dsip_clk");
@@ -335,18 +317,27 @@
 		goto sh_mipi_set_dot_clock_pck_err;
 	}
 
+	phy = clk_get(&pdev->dev, "dsiphy_clk");
+	if (IS_ERR(phy)) {
+		ret = PTR_ERR(phy);
+		goto sh_mipi_set_dot_clock_phy_err;
+	}
+
 	if (enable) {
 		clk_set_rate(pck, clk_round_rate(pck,  24000000));
-		__raw_writel(0x2a809010, DSI0PHYCR);
+		clk_set_rate(phy, clk_round_rate(pck, 510000000));
 		clk_enable(pck);
+		clk_enable(phy);
 	} else {
 		clk_disable(pck);
+		clk_disable(phy);
 	}
 
 	ret = 0;
 
+	clk_put(phy);
+sh_mipi_set_dot_clock_phy_err:
 	clk_put(pck);
-
 sh_mipi_set_dot_clock_pck_err:
 	return ret;
 }
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index aab0a34..d4cc2de 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -258,10 +258,16 @@
 
 static struct resource meram_resources[] = {
 	[0] = {
-		.name   = "MERAM",
-		.start  = 0xe8000000,
-		.end    = 0xe81fffff,
-		.flags  = IORESOURCE_MEM,
+		.name	= "regs",
+		.start	= 0xe8000000,
+		.end	= 0xe807ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "meram",
+		.start	= 0xe8080000,
+		.end	= 0xe81fffff,
+		.flags	= IORESOURCE_MEM,
 	},
 };
 
@@ -295,15 +301,6 @@
 	},
 };
 
-static struct sh_mmcif_dma sh_mmcif_dma = {
-	.chan_priv_rx	= {
-		.slave_id	= SHDMA_SLAVE_MMCIF_RX,
-	},
-	.chan_priv_tx	= {
-		.slave_id	= SHDMA_SLAVE_MMCIF_TX,
-	},
-};
-
 static struct sh_mmcif_plat_data sh_mmcif_plat = {
 	.sup_pclk	= 0,
 	.ocr		= MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -311,7 +308,8 @@
 			  MMC_CAP_8_BIT_DATA |
 			  MMC_CAP_NEEDS_POLL,
 	.get_cd		= slot_cn7_get_cd,
-	.dma		= &sh_mmcif_dma,
+	.slave_id_tx	= SHDMA_SLAVE_MMCIF_TX,
+	.slave_id_rx	= SHDMA_SLAVE_MMCIF_RX,
 };
 
 static struct platform_device sh_mmcif_device = {
@@ -445,82 +443,6 @@
 	.resource	= usb1_host_resources,
 };
 
-static const struct fb_videomode ap4evb_lcdc_modes[] = {
-	{
-#ifdef CONFIG_AP4EVB_QHD
-		.name		= "R63302(QHD)",
-		.xres		= 544,
-		.yres		= 961,
-		.left_margin	= 72,
-		.right_margin	= 600,
-		.hsync_len	= 16,
-		.upper_margin	= 8,
-		.lower_margin	= 8,
-		.vsync_len	= 2,
-		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
-#else
-		.name		= "WVGA Panel",
-		.xres		= 800,
-		.yres		= 480,
-		.left_margin	= 220,
-		.right_margin	= 110,
-		.hsync_len	= 70,
-		.upper_margin	= 20,
-		.lower_margin	= 5,
-		.vsync_len	= 5,
-		.sync		= 0,
-#endif
-	},
-};
-static struct sh_mobile_meram_cfg lcd_meram_cfg = {
-	.icb[0] = {
-		.marker_icb     = 28,
-		.cache_icb      = 24,
-		.meram_offset   = 0x0,
-		.meram_size     = 0x40,
-	},
-	.icb[1] = {
-		.marker_icb     = 29,
-		.cache_icb      = 25,
-		.meram_offset   = 0x40,
-		.meram_size     = 0x40,
-	},
-};
-
-static struct sh_mobile_lcdc_info lcdc_info = {
-	.meram_dev = &meram_info,
-	.ch[0] = {
-		.chan = LCDC_CHAN_MAINLCD,
-		.fourcc = V4L2_PIX_FMT_RGB565,
-		.lcd_cfg = ap4evb_lcdc_modes,
-		.num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
-		.meram_cfg = &lcd_meram_cfg,
-	}
-};
-
-static struct resource lcdc_resources[] = {
-	[0] = {
-		.name	= "LCDC",
-		.start	= 0xfe940000, /* P4-only space */
-		.end	= 0xfe943fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= intcs_evt2irq(0x580),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device lcdc_device = {
-	.name		= "sh_mobile_lcdc_fb",
-	.num_resources	= ARRAY_SIZE(lcdc_resources),
-	.resource	= lcdc_resources,
-	.dev	= {
-		.platform_data	= &lcdc_info,
-		.coherent_dma_mask = ~0,
-	},
-};
-
 /*
  * QHD display
  */
@@ -601,6 +523,8 @@
 	},
 };
 
+static struct sh_mobile_lcdc_info lcdc_info;
+
 static struct sh_mipi_dsi_info mipidsi0_info = {
 	.data_format	= MIPI_RGB888,
 	.lcd_chan	= &lcdc_info.ch[0],
@@ -627,6 +551,81 @@
 };
 #endif /* CONFIG_AP4EVB_QHD */
 
+/* LCDC0 */
+static const struct fb_videomode ap4evb_lcdc_modes[] = {
+	{
+#ifdef CONFIG_AP4EVB_QHD
+		.name		= "R63302(QHD)",
+		.xres		= 544,
+		.yres		= 961,
+		.left_margin	= 72,
+		.right_margin	= 600,
+		.hsync_len	= 16,
+		.upper_margin	= 8,
+		.lower_margin	= 8,
+		.vsync_len	= 2,
+		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+#else
+		.name		= "WVGA Panel",
+		.xres		= 800,
+		.yres		= 480,
+		.left_margin	= 220,
+		.right_margin	= 110,
+		.hsync_len	= 70,
+		.upper_margin	= 20,
+		.lower_margin	= 5,
+		.vsync_len	= 5,
+		.sync		= 0,
+#endif
+	},
+};
+
+static const struct sh_mobile_meram_cfg lcd_meram_cfg = {
+	.icb[0] = {
+		.meram_size     = 0x40,
+	},
+	.icb[1] = {
+		.meram_size     = 0x40,
+	},
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+	.meram_dev = &meram_info,
+	.ch[0] = {
+		.chan = LCDC_CHAN_MAINLCD,
+		.fourcc = V4L2_PIX_FMT_RGB565,
+		.lcd_modes = ap4evb_lcdc_modes,
+		.num_modes = ARRAY_SIZE(ap4evb_lcdc_modes),
+		.meram_cfg = &lcd_meram_cfg,
+#ifdef CONFIG_AP4EVB_QHD
+		.tx_dev = &mipidsi0_device,
+#endif
+	}
+};
+
+static struct resource lcdc_resources[] = {
+	[0] = {
+		.name	= "LCDC",
+		.start	= 0xfe940000, /* P4-only space */
+		.end	= 0xfe943fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= intcs_evt2irq(0x580),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device lcdc_device = {
+	.name		= "sh_mobile_lcdc_fb",
+	.num_resources	= ARRAY_SIZE(lcdc_resources),
+	.resource	= lcdc_resources,
+	.dev	= {
+		.platform_data	= &lcdc_info,
+		.coherent_dma_mask = ~0,
+	},
+};
+
 /* FSI */
 #define IRQ_FSI		evt2irq(0x1840)
 static int __fsi_set_rate(struct clk *clk, long rate, int enable)
@@ -806,65 +805,11 @@
 	},
 };
 
-static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
-	.icb[0] = {
-		.marker_icb     = 30,
-		.cache_icb      = 26,
-		.meram_offset   = 0x80,
-		.meram_size     = 0x100,
-	},
-	.icb[1] = {
-		.marker_icb     = 31,
-		.cache_icb      = 27,
-		.meram_offset   = 0x180,
-		.meram_size     = 0x100,
-	},
-};
-
-static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
-	.clock_source = LCDC_CLK_EXTERNAL,
-	.meram_dev = &meram_info,
-	.ch[0] = {
-		.chan = LCDC_CHAN_MAINLCD,
-		.fourcc = V4L2_PIX_FMT_RGB565,
-		.interface_type = RGB24,
-		.clock_divider = 1,
-		.flags = LCDC_FLAGS_DWPOL,
-		.meram_cfg = &hdmi_meram_cfg,
-	}
-};
-
-static struct resource lcdc1_resources[] = {
-	[0] = {
-		.name	= "LCDC1",
-		.start	= 0xfe944000,
-		.end	= 0xfe947fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= intcs_evt2irq(0x1780),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device lcdc1_device = {
-	.name		= "sh_mobile_lcdc_fb",
-	.num_resources	= ARRAY_SIZE(lcdc1_resources),
-	.resource	= lcdc1_resources,
-	.id             = 1,
-	.dev	= {
-		.platform_data	= &sh_mobile_lcdc1_info,
-		.coherent_dma_mask = ~0,
-	},
-};
-
+/* LCDC1 */
 static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
 				unsigned long *parent_freq);
 
-
 static struct sh_mobile_hdmi_info hdmi_info = {
-	.lcd_chan = &sh_mobile_lcdc1_info.ch[0],
-	.lcd_dev = &lcdc1_device.dev,
 	.flags = HDMI_SND_SRC_SPDIF,
 	.clk_optimize_parent = ap4evb_clk_optimize,
 };
@@ -893,10 +838,6 @@
 	},
 };
 
-static struct platform_device fsi_hdmi_device = {
-	.name		= "sh_fsi2_b_hdmi",
-};
-
 static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
 				unsigned long *parent_freq)
 {
@@ -916,6 +857,57 @@
 	return error;
 }
 
+static const struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+	.icb[0] = {
+		.meram_size     = 0x100,
+	},
+	.icb[1] = {
+		.meram_size     = 0x100,
+	},
+};
+
+static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
+	.clock_source = LCDC_CLK_EXTERNAL,
+	.meram_dev = &meram_info,
+	.ch[0] = {
+		.chan = LCDC_CHAN_MAINLCD,
+		.fourcc = V4L2_PIX_FMT_RGB565,
+		.interface_type = RGB24,
+		.clock_divider = 1,
+		.flags = LCDC_FLAGS_DWPOL,
+		.meram_cfg = &hdmi_meram_cfg,
+		.tx_dev = &hdmi_device,
+	}
+};
+
+static struct resource lcdc1_resources[] = {
+	[0] = {
+		.name	= "LCDC1",
+		.start	= 0xfe944000,
+		.end	= 0xfe947fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= intcs_evt2irq(0x1780),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device lcdc1_device = {
+	.name		= "sh_mobile_lcdc_fb",
+	.num_resources	= ARRAY_SIZE(lcdc1_resources),
+	.resource	= lcdc1_resources,
+	.id             = 1,
+	.dev	= {
+		.platform_data	= &sh_mobile_lcdc1_info,
+		.coherent_dma_mask = ~0,
+	},
+};
+
+static struct platform_device fsi_hdmi_device = {
+	.name		= "sh_fsi2_b_hdmi",
+};
+
 static struct gpio_led ap4evb_leds[] = {
 	{
 		.name			= "led4",
@@ -1050,9 +1042,9 @@
 	&fsi_ak4643_device,
 	&fsi_hdmi_device,
 	&sh_mmcif_device,
-	&lcdc1_device,
-	&lcdc_device,
 	&hdmi_device,
+	&lcdc_device,
+	&lcdc1_device,
 	&ceu_device,
 	&ap4evb_camera,
 	&meram_device,
@@ -1363,8 +1355,8 @@
 	lcdc_info.ch[0].interface_type		= RGB24;
 	lcdc_info.ch[0].clock_divider		= 1;
 	lcdc_info.ch[0].flags			= LCDC_FLAGS_DWPOL;
-	lcdc_info.ch[0].lcd_size_cfg.width	= 44;
-	lcdc_info.ch[0].lcd_size_cfg.height	= 79;
+	lcdc_info.ch[0].panel_cfg.width		= 44;
+	lcdc_info.ch[0].panel_cfg.height	= 79;
 
 	platform_add_devices(qhd_devices, ARRAY_SIZE(qhd_devices));
 
@@ -1405,8 +1397,8 @@
 	lcdc_info.ch[0].interface_type		= RGB18;
 	lcdc_info.ch[0].clock_divider		= 3;
 	lcdc_info.ch[0].flags			= 0;
-	lcdc_info.ch[0].lcd_size_cfg.width	= 152;
-	lcdc_info.ch[0].lcd_size_cfg.height	= 91;
+	lcdc_info.ch[0].panel_cfg.width		= 152;
+	lcdc_info.ch[0].panel_cfg.height	= 91;
 
 	/* enable TouchScreen */
 	irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
index 4d22016..fb90f08 100644
--- a/arch/arm/mach-shmobile/board-bonito.c
+++ b/arch/arm/mach-shmobile/board-bonito.c
@@ -245,9 +245,9 @@
 		.interface_type		= RGB24,
 		.clock_divider		= 5,
 		.flags			= 0,
-		.lcd_cfg		= &lcdc0_mode,
-		.num_cfg		= 1,
-		.lcd_size_cfg = {
+		.lcd_modes		= &lcdc0_mode,
+		.num_modes		= 1,
+		.panel_cfg = {
 			.width	= 152,
 			.height = 91,
 		},
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index 857ceee..c8e7ca2 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -143,11 +143,10 @@
 static struct gpio_keys_platform_data gpio_key_info = {
 	.buttons        = gpio_buttons,
 	.nbuttons       = ARRAY_SIZE(gpio_buttons),
-	.poll_interval  = 250, /* polled for now */
 };
 
 static struct platform_device gpio_keys_device = {
-	.name   = "gpio-keys-polled", /* polled for now */
+	.name   = "gpio-keys",
 	.id     = -1,
 	.dev    = {
 		.platform_data  = &gpio_key_info,
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 9b42fbd..e761b28 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -43,7 +43,6 @@
 #include <linux/smsc911x.h>
 #include <linux/sh_intc.h>
 #include <linux/tca6416_keypad.h>
-#include <linux/usb/r8a66597.h>
 #include <linux/usb/renesas_usbhs.h>
 #include <linux/dma-mapping.h>
 
@@ -145,11 +144,6 @@
  * 1-2 short | VBUS 5V       | Host
  * open      | external VBUS | Function
  *
- * *1
- * CN31 is used as
- * CONFIG_USB_R8A66597_HCD	Host
- * CONFIG_USB_RENESAS_USBHS	Function
- *
  * CAUTION
  *
  * renesas_usbhs driver can use external interrupt mode
@@ -161,15 +155,6 @@
  * mackerel can not use external interrupt (IRQ7-PORT167) mode on "USB0",
  * because Touchscreen is using IRQ7-PORT40.
  * It is impossible to use IRQ7 demux on this board.
- *
- * We can use external interrupt mode USB-Function on "USB1".
- * USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
- * But don't select both drivers in same time.
- * These uses same IRQ number for request_irq(), and aren't supporting
- * IRQF_SHARED / IORESOURCE_IRQ_SHAREABLE.
- *
- * Actually these are old/new version of USB driver.
- * This mean its register will be broken if it supports shared IRQ,
  */
 
 /*
@@ -208,6 +193,16 @@
  */
 
 /*
+ * FSI - AK4642
+ *
+ * it needs amixer settings for playing
+ *
+ * amixer set "Headphone" on
+ * amixer set "HPOUTL Mixer DACH" on
+ * amixer set "HPOUTR Mixer DACH" on
+ */
+
+/*
  * FIXME !!
  *
  * gpio_no_direction
@@ -323,8 +318,14 @@
 
 static struct resource meram_resources[] = {
 	[0] = {
-		.name	= "MERAM",
+		.name	= "regs",
 		.start	= 0xe8000000,
+		.end	= 0xe807ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "meram",
+		.start	= 0xe8080000,
 		.end	= 0xe81fffff,
 		.flags	= IORESOURCE_MEM,
 	},
@@ -356,29 +357,23 @@
 	},
 };
 
-static int mackerel_set_brightness(void *board_data, int brightness)
+static int mackerel_set_brightness(int brightness)
 {
 	gpio_set_value(GPIO_PORT31, brightness);
 
 	return 0;
 }
 
-static int mackerel_get_brightness(void *board_data)
+static int mackerel_get_brightness(void)
 {
 	return gpio_get_value(GPIO_PORT31);
 }
 
-static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+static const struct sh_mobile_meram_cfg lcd_meram_cfg = {
 	.icb[0] = {
-		.marker_icb     = 28,
-		.cache_icb      = 24,
-		.meram_offset   = 0x0,
 		.meram_size     = 0x40,
 	},
 	.icb[1] = {
-		.marker_icb     = 29,
-		.cache_icb      = 25,
-		.meram_offset   = 0x40,
 		.meram_size     = 0x40,
 	},
 };
@@ -389,20 +384,20 @@
 	.ch[0] = {
 		.chan = LCDC_CHAN_MAINLCD,
 		.fourcc = V4L2_PIX_FMT_RGB565,
-		.lcd_cfg = mackerel_lcdc_modes,
-		.num_cfg = ARRAY_SIZE(mackerel_lcdc_modes),
+		.lcd_modes = mackerel_lcdc_modes,
+		.num_modes = ARRAY_SIZE(mackerel_lcdc_modes),
 		.interface_type		= RGB24,
 		.clock_divider		= 3,
 		.flags			= 0,
-		.lcd_size_cfg.width	= 152,
-		.lcd_size_cfg.height	= 91,
-		.board_cfg = {
-			.set_brightness = mackerel_set_brightness,
-			.get_brightness = mackerel_get_brightness,
+		.panel_cfg = {
+			.width		= 152,
+			.height		= 91,
 		},
 		.bl_info = {
 			.name = "sh_mobile_lcdc_bl",
 			.max_brightness = 1,
+			.set_brightness = mackerel_set_brightness,
+			.get_brightness = mackerel_get_brightness,
 		},
 		.meram_cfg = &lcd_meram_cfg,
 	}
@@ -431,61 +426,8 @@
 	},
 };
 
-static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
-	.icb[0] = {
-		.marker_icb     = 30,
-		.cache_icb      = 26,
-		.meram_offset   = 0x80,
-		.meram_size     = 0x100,
-	},
-	.icb[1] = {
-		.marker_icb     = 31,
-		.cache_icb      = 27,
-		.meram_offset   = 0x180,
-		.meram_size     = 0x100,
-	},
-};
 /* HDMI */
-static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
-	.meram_dev = &mackerel_meram_info,
-	.clock_source = LCDC_CLK_EXTERNAL,
-	.ch[0] = {
-		.chan = LCDC_CHAN_MAINLCD,
-		.fourcc = V4L2_PIX_FMT_RGB565,
-		.interface_type = RGB24,
-		.clock_divider = 1,
-		.flags = LCDC_FLAGS_DWPOL,
-		.meram_cfg = &hdmi_meram_cfg,
-	}
-};
-
-static struct resource hdmi_lcdc_resources[] = {
-	[0] = {
-		.name	= "LCDC1",
-		.start	= 0xfe944000,
-		.end	= 0xfe947fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= intcs_evt2irq(0x1780),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device hdmi_lcdc_device = {
-	.name		= "sh_mobile_lcdc_fb",
-	.num_resources	= ARRAY_SIZE(hdmi_lcdc_resources),
-	.resource	= hdmi_lcdc_resources,
-	.id		= 1,
-	.dev	= {
-		.platform_data	= &hdmi_lcdc_info,
-		.coherent_dma_mask = ~0,
-	},
-};
-
 static struct sh_mobile_hdmi_info hdmi_info = {
-	.lcd_chan	= &hdmi_lcdc_info.ch[0],
-	.lcd_dev	= &hdmi_lcdc_device.dev,
 	.flags		= HDMI_SND_SRC_SPDIF,
 };
 
@@ -513,6 +455,53 @@
 	},
 };
 
+static const struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+	.icb[0] = {
+		.meram_size     = 0x100,
+	},
+	.icb[1] = {
+		.meram_size     = 0x100,
+	},
+};
+
+static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
+	.meram_dev = &mackerel_meram_info,
+	.clock_source = LCDC_CLK_EXTERNAL,
+	.ch[0] = {
+		.chan = LCDC_CHAN_MAINLCD,
+		.fourcc = V4L2_PIX_FMT_RGB565,
+		.interface_type = RGB24,
+		.clock_divider = 1,
+		.flags = LCDC_FLAGS_DWPOL,
+		.meram_cfg = &hdmi_meram_cfg,
+		.tx_dev = &hdmi_device,
+	}
+};
+
+static struct resource hdmi_lcdc_resources[] = {
+	[0] = {
+		.name	= "LCDC1",
+		.start	= 0xfe944000,
+		.end	= 0xfe947fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= intcs_evt2irq(0x1780),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device hdmi_lcdc_device = {
+	.name		= "sh_mobile_lcdc_fb",
+	.num_resources	= ARRAY_SIZE(hdmi_lcdc_resources),
+	.resource	= hdmi_lcdc_resources,
+	.id		= 1,
+	.dev	= {
+		.platform_data	= &hdmi_lcdc_info,
+		.coherent_dma_mask = ~0,
+	},
+};
+
 static struct platform_device fsi_hdmi_device = {
 	.name		= "sh_fsi2_b_hdmi",
 };
@@ -676,51 +665,16 @@
  * Use J30 to select between Host and Function. This setting
  * can however not be detected by software. Hotplug of USBHS1
  * is provided via IRQ8.
+ *
+ * Current USB1 works as "USB Host".
+ *  - set J30 "short"
+ *
+ * If you want to use it as "USB gadget",
+ *  - J30 "open"
+ *  - modify usbhs1_get_id() USBHS_HOST -> USBHS_GADGET
+ *  - add .get_vbus = usbhs_get_vbus in usbhs1_private
  */
 #define IRQ8 evt2irq(0x0300)
-
-/* USBHS1 USB Host support via r8a66597_hcd */
-static void usb1_host_port_power(int port, int power)
-{
-	if (!power) /* only power-on is supported for now */
-		return;
-
-	/* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
-	__raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
-}
-
-static struct r8a66597_platdata usb1_host_data = {
-	.on_chip	= 1,
-	.port_power	= usb1_host_port_power,
-};
-
-static struct resource usb1_host_resources[] = {
-	[0] = {
-		.name	= "USBHS1",
-		.start	= 0xe68b0000,
-		.end	= 0xe68b00e6 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0x1ce0) /* USB1_USB1I0 */,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device usb1_host_device = {
-	.name	= "r8a66597_hcd",
-	.id	= 1,
-	.dev = {
-		.dma_mask		= NULL,         /*  not use dma */
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &usb1_host_data,
-	},
-	.num_resources	= ARRAY_SIZE(usb1_host_resources),
-	.resource	= usb1_host_resources,
-};
-
-/* USBHS1 USB Function support via renesas_usbhs */
-
 #define USB_PHY_MODE		(1 << 4)
 #define USB_PHY_INT_EN		((1 << 3) | (1 << 2))
 #define USB_PHY_ON		(1 << 1)
@@ -776,7 +730,7 @@
 
 static int usbhs1_get_id(struct platform_device *pdev)
 {
-	return USBHS_GADGET;
+	return USBHS_HOST;
 }
 
 static u32 usbhs1_pipe_cfg[] = {
@@ -807,7 +761,6 @@
 			.hardware_exit	= usbhs1_hardware_exit,
 			.get_id		= usbhs1_get_id,
 			.phy_reset	= usbhs_phy_reset,
-			.get_vbus	= usbhs_get_vbus,
 		},
 		.driver_param = {
 			.buswait_bwait	= 4,
@@ -1184,15 +1137,6 @@
 	},
 };
 
-static struct sh_mmcif_dma sh_mmcif_dma = {
-	.chan_priv_rx	= {
-		.slave_id	= SHDMA_SLAVE_MMCIF_RX,
-	},
-	.chan_priv_tx	= {
-		.slave_id	= SHDMA_SLAVE_MMCIF_TX,
-	},
-};
-
 static struct sh_mmcif_plat_data sh_mmcif_plat = {
 	.sup_pclk	= 0,
 	.ocr		= MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -1200,7 +1144,8 @@
 			  MMC_CAP_8_BIT_DATA |
 			  MMC_CAP_NEEDS_POLL,
 	.get_cd		= slot_cn7_get_cd,
-	.dma		= &sh_mmcif_dma,
+	.slave_id_tx	= SHDMA_SLAVE_MMCIF_TX,
+	.slave_id_rx	= SHDMA_SLAVE_MMCIF_RX,
 };
 
 static struct platform_device sh_mmcif_device = {
@@ -1311,7 +1256,6 @@
 	&nor_flash_device,
 	&smc911x_device,
 	&lcdc_device,
-	&usb1_host_device,
 	&usbhs1_device,
 	&usbhs0_device,
 	&leds_device,
@@ -1326,8 +1270,8 @@
 	&sh_mmcif_device,
 	&ceu_device,
 	&mackerel_camera,
-	&hdmi_lcdc_device,
 	&hdmi_device,
+	&hdmi_lcdc_device,
 	&meram_device,
 };
 
@@ -1473,9 +1417,6 @@
 	gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
 	gpio_request(GPIO_FN_IDIN_1_113, NULL);
 
-	/* USB phy tweak to make the r8a66597_hcd host driver work */
-	__raw_writew(0x8a0a, 0xe6058130);       /* USBCR4 */
-
 	/* enable FSI2 port A (ak4643) */
 	gpio_request(GPIO_FN_FSIAIBT,	NULL);
 	gpio_request(GPIO_FN_FSIAILR,	NULL);
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index afbead6..7727cca 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -365,6 +365,114 @@
 			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
 };
 
+/* DSI DIV */
+static unsigned long dsiphy_recalc(struct clk *clk)
+{
+	u32 value;
+
+	value = __raw_readl(clk->mapping->base);
+
+	/* FIXME */
+	if (!(value & 0x000B8000))
+		return clk->parent->rate;
+
+	value &= 0x3f;
+	value += 1;
+
+	if ((value < 12) ||
+	    (value > 33)) {
+		pr_err("DSIPHY has wrong value (%d)", value);
+		return 0;
+	}
+
+	return clk->parent->rate / value;
+}
+
+static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
+{
+	return clk_rate_mult_range_round(clk, 12, 33, rate);
+}
+
+static void dsiphy_disable(struct clk *clk)
+{
+	u32 value;
+
+	value = __raw_readl(clk->mapping->base);
+	value &= ~0x000B8000;
+
+	__raw_writel(value , clk->mapping->base);
+}
+
+static int dsiphy_enable(struct clk *clk)
+{
+	u32 value;
+	int multi;
+
+	value = __raw_readl(clk->mapping->base);
+	multi = (value & 0x3f) + 1;
+
+	if ((multi < 12) || (multi > 33))
+		return -EIO;
+
+	__raw_writel(value | 0x000B8000, clk->mapping->base);
+
+	return 0;
+}
+
+static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 value;
+	int idx;
+
+	idx = rate / clk->parent->rate;
+	if ((idx < 12) || (idx > 33))
+		return -EINVAL;
+
+	idx += -1;
+
+	value = __raw_readl(clk->mapping->base);
+	value = (value & ~0x3f) + idx;
+
+	__raw_writel(value, clk->mapping->base);
+
+	return 0;
+}
+
+static struct clk_ops dsiphy_clk_ops = {
+	.recalc		= dsiphy_recalc,
+	.round_rate	= dsiphy_round_rate,
+	.set_rate	= dsiphy_set_rate,
+	.enable		= dsiphy_enable,
+	.disable	= dsiphy_disable,
+};
+
+static struct clk_mapping dsi0phy_clk_mapping = {
+	.phys	= DSI0PHYCR,
+	.len	= 4,
+};
+
+static struct clk_mapping dsi1phy_clk_mapping = {
+	.phys	= DSI1PHYCR,
+	.len	= 4,
+};
+
+static struct clk dsi0phy_clk = {
+	.ops		= &dsiphy_clk_ops,
+	.parent		= &div6_clks[DIV6_DSI0P], /* late install */
+	.mapping	= &dsi0phy_clk_mapping,
+};
+
+static struct clk dsi1phy_clk = {
+	.ops		= &dsiphy_clk_ops,
+	.parent		= &div6_clks[DIV6_DSI1P], /* late install */
+	.mapping	= &dsi1phy_clk_mapping,
+};
+
+static struct clk *late_main_clks[] = {
+	&dsi0phy_clk,
+	&dsi1phy_clk,
+};
+
 enum { MSTP001,
 	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
 	MSTP219,
@@ -429,6 +537,8 @@
 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
 	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
 	CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+	CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
+	CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
 
 	/* MSTP32 clocks */
 	CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
@@ -504,6 +614,9 @@
 	if (!ret)
 		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
+	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+		ret = clk_register(late_main_clks[k]);
+
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	if (!ret)
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
index 881d515..cad5757 100644
--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -515,8 +515,8 @@
 	SHDMA_SLAVE_MMCIF_RX,
 };
 
-/* PINT interrupts are located at Linux IRQ 768 and up */
-#define SH73A0_PINT0_IRQ(irq) ((irq) + 768)
-#define SH73A0_PINT1_IRQ(irq) ((irq) + 800)
+/* PINT interrupts are located at Linux IRQ 800 and up */
+#define SH73A0_PINT0_IRQ(irq) ((irq) + 800)
+#define SH73A0_PINT1_IRQ(irq) ((irq) + 832)
 
 #endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
index 1eda6b0..9857595 100644
--- a/arch/arm/mach-shmobile/intc-sh73a0.c
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/sh_intc.h>
@@ -445,6 +446,7 @@
 		setup_irq(gic_spi(1 + k), &sh73a0_irq_pin_cascade[k]);
 
 		n = intcs_evt2irq(to_intc_vect(gic_spi(1 + k)));
+		WARN_ON(irq_alloc_desc_at(n, numa_node_id()) != n);
 		irq_set_chip_and_handler_name(n, &intca_gic_irq_chip,
 					      handle_level_irq, "level");
 		set_irq_flags(n, IRQF_VALID); /* yuck */
diff --git a/arch/arm/mach-shmobile/pfc-r8a7779.c b/arch/arm/mach-shmobile/pfc-r8a7779.c
index 963532f..d14c9b0 100644
--- a/arch/arm/mach-shmobile/pfc-r8a7779.c
+++ b/arch/arm/mach-shmobile/pfc-r8a7779.c
@@ -2120,7 +2120,7 @@
 	    FN_AUDATA3, 0, 0, 0 }
 	},
 	{ PINMUX_CFG_REG_VAR("IPSR4", 0xfffc0030, 32,
-			     3, 1, 1, 1, 1, 1, 1, 3, 3, 1,
+			     3, 1, 1, 1, 1, 1, 1, 3, 3,
 			     1, 1, 1, 1, 1, 1, 3, 3, 3, 2) {
 	    /* IP4_31_29 [3] */
 	    FN_DU1_DB0, FN_VI2_DATA4_VI2_B4, FN_SCL2_B, FN_SD3_DAT0,
diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c
index 1bd6585..336093f 100644
--- a/arch/arm/mach-shmobile/pfc-sh7372.c
+++ b/arch/arm/mach-shmobile/pfc-sh7372.c
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/gpio.h>
+#include <mach/irqs.h>
 #include <mach/sh7372.h>
 
 #define CPU_ALL_PORT(fn, pfx, sfx) \
@@ -1594,6 +1595,43 @@
 	{ },
 };
 
+#define EXT_IRQ16L(n) evt2irq(0x200 + ((n) << 5))
+#define EXT_IRQ16H(n) evt2irq(0x3200 + (((n) - 16) << 5))
+static struct pinmux_irq pinmux_irqs[] = {
+	PINMUX_IRQ(EXT_IRQ16L(0), PORT6_FN0, PORT162_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(1), PORT12_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(2), PORT4_FN0, PORT5_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(3), PORT8_FN0, PORT16_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(4), PORT17_FN0, PORT163_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(5), PORT18_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(6), PORT39_FN0, PORT164_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(7), PORT40_FN0, PORT167_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(8), PORT41_FN0, PORT168_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(9), PORT42_FN0, PORT169_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(10), PORT65_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(11), PORT67_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(12), PORT80_FN0, PORT137_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(13), PORT81_FN0, PORT145_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(14), PORT82_FN0, PORT146_FN0),
+	PINMUX_IRQ(EXT_IRQ16L(15), PORT83_FN0, PORT147_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(16), PORT84_FN0, PORT170_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(17), PORT85_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(18), PORT86_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(19), PORT87_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(20), PORT92_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(21), PORT93_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(22), PORT94_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(23), PORT95_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(24), PORT112_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(25), PORT119_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(26), PORT121_FN0, PORT172_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(27), PORT122_FN0, PORT180_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(28), PORT123_FN0, PORT181_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(29), PORT129_FN0, PORT182_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(30), PORT130_FN0, PORT183_FN0),
+	PINMUX_IRQ(EXT_IRQ16H(31), PORT138_FN0, PORT184_FN0),
+};
+
 static struct pinmux_info sh7372_pinmux_info = {
 	.name = "sh7372_pfc",
 	.reserved_id = PINMUX_RESERVED,
@@ -1614,6 +1652,9 @@
 
 	.gpio_data = pinmux_data,
 	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+
+	.gpio_irq = pinmux_irqs,
+	.gpio_irq_size = ARRAY_SIZE(pinmux_irqs),
 };
 
 void sh7372_pinmux_init(void)
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index 0d159d6..2d0d421 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -80,7 +80,7 @@
 	/* enable cache coherency */
 	modify_scu_cpu_psr(0, 3 << (cpu * 8));
 
-	if (((__raw_readw(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
+	if (((__raw_readl(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
 		__raw_writel(1 << cpu, __io(WUPCR));	/* wake up */
 	else
 		__raw_writel(1 << cpu, __io(SRESCR));	/* reset */
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index fcf4f37..330afdf 100644
--- a/arch/arm/mach-tegra/board-paz00.c
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -60,9 +60,9 @@
 		.uartclk	= 216000000,
 	}, {
 		/* serial port on mini-pcie */
-		.membase	= IO_ADDRESS(TEGRA_UARTD_BASE),
-		.mapbase	= TEGRA_UARTD_BASE,
-		.irq		= INT_UARTD,
+		.membase	= IO_ADDRESS(TEGRA_UARTC_BASE),
+		.mapbase	= TEGRA_UARTC_BASE,
+		.irq		= INT_UARTC,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
 		.type		= PORT_TEGRA,
 		.iotype		= UPIO_MEM,
@@ -174,7 +174,7 @@
 static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = {
 	/* name		parent		rate		enabled */
 	{ "uarta",	"pll_p",	216000000,	true },
-	{ "uartd",	"pll_p",	216000000,	true },
+	{ "uartc",	"pll_p",	216000000,	true },
 
 	{ "pll_p_out4",	"pll_p",	24000000,	true },
 	{ "usbd",	"clk_m",	12000000,	false },
diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h
index ffa83f5..3c9f8da 100644
--- a/arch/arm/mach-tegra/board-paz00.h
+++ b/arch/arm/mach-tegra/board-paz00.h
@@ -22,7 +22,7 @@
 /* SDCARD */
 #define TEGRA_GPIO_SD1_CD		TEGRA_GPIO_PV5
 #define TEGRA_GPIO_SD1_WP		TEGRA_GPIO_PH1
-#define TEGRA_GPIO_SD1_POWER		TEGRA_GPIO_PT3
+#define TEGRA_GPIO_SD1_POWER		TEGRA_GPIO_PV1
 
 /* ULPI */
 #define TEGRA_ULPI_RST			TEGRA_GPIO_PV0
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
index d0132e8..3c9339058 100644
--- a/arch/arm/mach-tegra/include/mach/dma.h
+++ b/arch/arm/mach-tegra/include/mach/dma.h
@@ -23,11 +23,6 @@
 
 #include <linux/list.h>
 
-#if defined(CONFIG_TEGRA_SYSTEM_DMA)
-
-struct tegra_dma_req;
-struct tegra_dma_channel;
-
 #define TEGRA_DMA_REQ_SEL_CNTR			0
 #define TEGRA_DMA_REQ_SEL_I2S_2			1
 #define TEGRA_DMA_REQ_SEL_I2S_1			2
@@ -56,6 +51,11 @@
 #define TEGRA_DMA_REQ_SEL_OWR			25
 #define TEGRA_DMA_REQ_SEL_INVALID		31
 
+#if defined(CONFIG_TEGRA_SYSTEM_DMA)
+
+struct tegra_dma_req;
+struct tegra_dma_channel;
+
 enum tegra_dma_mode {
 	TEGRA_DMA_SHARED = 1,
 	TEGRA_DMA_MODE_CONTINOUS = 2,
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 1a3ca24..7edef91 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -631,7 +631,8 @@
 
 config ARM_LPAE
 	bool "Support for the Large Physical Address Extension"
-	depends on MMU && CPU_V7
+	depends on MMU && CPU_32v7 && !CPU_32v6 && !CPU_32v5 && \
+		!CPU_32v4 && !CPU_32v3
 	help
 	  Say Y if you have an ARMv7 processor supporting the LPAE page
 	  table format and you would like to access memory beyond the
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 07c4bc8..a655d3d 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -54,9 +54,15 @@
 	and	r1, r1, #7			@ mask of the bits for current cache only
 	cmp	r1, #2				@ see what cache we have at this level
 	blt	skip				@ skip if no cache, or just i-cache
+#ifdef CONFIG_PREEMPT
+	save_and_disable_irqs_notrace r9	@ make cssr&csidr read atomic
+#endif
 	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
 	isb					@ isb to sych the new cssr&csidr
 	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
+#ifdef CONFIG_PREEMPT
+	restore_irqs_notrace r9
+#endif
 	and	r2, r1, #7			@ extract the length of the cache lines
 	add	r2, r2, #4			@ add 4 (line length offset)
 	ldr	r4, =0x3ff
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 06383b5..4de7d1e 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -69,6 +69,7 @@
 	omap_vram_reserve_sdram_memblock();
 	omap_dsp_reserve_sdram_memblock();
 	omap_secure_ram_reserve_memblock();
+	omap_barrier_reserve_memblock();
 }
 
 void __init omap_init_consistent_dma_size(void)
diff --git a/arch/arm/plat-omap/include/plat/omap-secure.h b/arch/arm/plat-omap/include/plat/omap-secure.h
index 64f9d1c..8c7994c 100644
--- a/arch/arm/plat-omap/include/plat/omap-secure.h
+++ b/arch/arm/plat-omap/include/plat/omap-secure.h
@@ -3,11 +3,17 @@
 
 #include <linux/types.h>
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 extern int omap_secure_ram_reserve_memblock(void);
 #else
 static inline void omap_secure_ram_reserve_memblock(void)
 { }
 #endif
 
+#ifdef CONFIG_OMAP4_ERRATA_I688
+extern int omap_barrier_reserve_memblock(void);
+#else
+static inline void omap_barrier_reserve_memblock(void)
+{ }
+#endif
 #endif /* __OMAP_SECURE_H__ */
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index e5a2fde..089899a 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -789,10 +789,7 @@
 /*****************************************************************************
  * EHCI
  ****************************************************************************/
-static struct orion_ehci_data orion_ehci_data = {
-	.phy_version	= EHCI_PHY_NA,
-};
-
+static struct orion_ehci_data orion_ehci_data;
 static u64 ehci_dmamask = DMA_BIT_MASK(32);
 
 
@@ -812,8 +809,10 @@
 };
 
 void __init orion_ehci_init(unsigned long mapbase,
-			    unsigned long irq)
+			    unsigned long irq,
+			    enum orion_ehci_phy_ver phy_version)
 {
+	orion_ehci_data.phy_version = phy_version;
 	fill_resources(&orion_ehci, orion_ehci_resources, mapbase, SZ_4K - 1,
 		       irq);
 
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index 0fe08d7..a7fa005 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -89,7 +89,8 @@
 			    unsigned long irq_1);
 
 void __init orion_ehci_init(unsigned long mapbase,
-			    unsigned long irq);
+			    unsigned long irq,
+			    enum orion_ehci_phy_ver phy_version);
 
 void __init orion_ehci_1_init(unsigned long mapbase,
 			      unsigned long irq);
diff --git a/arch/arm/plat-orion/mpp.c b/arch/arm/plat-orion/mpp.c
index 9155343..3b1e17b 100644
--- a/arch/arm/plat-orion/mpp.c
+++ b/arch/arm/plat-orion/mpp.c
@@ -64,8 +64,7 @@
 			gpio_mode |= GPIO_INPUT_OK;
 		if (*mpp_list & MPP_OUTPUT_MASK)
 			gpio_mode |= GPIO_OUTPUT_OK;
-		if (sel != 0)
-			gpio_mode = 0;
+
 		orion_gpio_set_valid(num, gpio_mode);
 	}
 
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 32a6e39..f10768e 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -468,8 +468,10 @@
 {
 	struct s3c2410_platform_i2c *npd;
 
-	if (!pd)
+	if (!pd) {
 		pd = &default_i2c_data;
+		pd->bus_num = 0;
+	}
 
 	npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
 			       &s3c_device_i2c0);
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h
index 8f39aa5..9a78012 100644
--- a/arch/arm/plat-samsung/include/plat/regs-fb.h
+++ b/arch/arm/plat-samsung/include/plat/regs-fb.h
@@ -91,6 +91,9 @@
 #define VIDCON1_VSTATUS_BACKPORCH		(0x1 << 13)
 #define VIDCON1_VSTATUS_ACTIVE			(0x2 << 13)
 #define VIDCON1_VSTATUS_FRONTPORCH		(0x0 << 13)
+#define VIDCON1_VCLK_MASK			(0x3 << 9)
+#define VIDCON1_VCLK_HOLD			(0x0 << 9)
+#define VIDCON1_VCLK_RUN			(0x1 << 9)
 
 #define VIDCON1_INV_VCLK			(1 << 7)
 #define VIDCON1_INV_HSYNC			(1 << 6)
@@ -164,15 +167,17 @@
 #define VIDTCON1_HSPW(_x)			((_x) << 0)
 
 #define VIDTCON2				(0x18)
+#define VIDTCON2_LINEVAL_E(_x)			((((_x) & 0x800) >> 11) << 23)
 #define VIDTCON2_LINEVAL_MASK			(0x7ff << 11)
 #define VIDTCON2_LINEVAL_SHIFT			(11)
 #define VIDTCON2_LINEVAL_LIMIT			(0x7ff)
-#define VIDTCON2_LINEVAL(_x)			((_x) << 11)
+#define VIDTCON2_LINEVAL(_x)			(((_x) & 0x7ff) << 11)
 
+#define VIDTCON2_HOZVAL_E(_x)			((((_x) & 0x800) >> 11) << 22)
 #define VIDTCON2_HOZVAL_MASK			(0x7ff << 0)
 #define VIDTCON2_HOZVAL_SHIFT			(0)
 #define VIDTCON2_HOZVAL_LIMIT			(0x7ff)
-#define VIDTCON2_HOZVAL(_x)			((_x) << 0)
+#define VIDTCON2_HOZVAL(_x)			(((_x) & 0x7ff) << 0)
 
 /* WINCONx */
 
@@ -228,25 +233,29 @@
 /* Local input channels (windows 0-2) */
 #define SHADOWCON_CHx_LOCAL_ENABLE(_win)	(1 << (5 + (_win)))
 
+#define VIDOSDxA_TOPLEFT_X_E(_x)		((((_x) & 0x800) >> 11) << 23)
 #define VIDOSDxA_TOPLEFT_X_MASK			(0x7ff << 11)
 #define VIDOSDxA_TOPLEFT_X_SHIFT		(11)
 #define VIDOSDxA_TOPLEFT_X_LIMIT		(0x7ff)
-#define VIDOSDxA_TOPLEFT_X(_x)			((_x) << 11)
+#define VIDOSDxA_TOPLEFT_X(_x)			(((_x) & 0x7ff) << 11)
 
+#define VIDOSDxA_TOPLEFT_Y_E(_x)		((((_x) & 0x800) >> 11) << 22)
 #define VIDOSDxA_TOPLEFT_Y_MASK			(0x7ff << 0)
 #define VIDOSDxA_TOPLEFT_Y_SHIFT		(0)
 #define VIDOSDxA_TOPLEFT_Y_LIMIT		(0x7ff)
-#define VIDOSDxA_TOPLEFT_Y(_x)			((_x) << 0)
+#define VIDOSDxA_TOPLEFT_Y(_x)			(((_x) & 0x7ff) << 0)
 
+#define VIDOSDxB_BOTRIGHT_X_E(_x)		((((_x) & 0x800) >> 11) << 23)
 #define VIDOSDxB_BOTRIGHT_X_MASK		(0x7ff << 11)
 #define VIDOSDxB_BOTRIGHT_X_SHIFT		(11)
 #define VIDOSDxB_BOTRIGHT_X_LIMIT		(0x7ff)
-#define VIDOSDxB_BOTRIGHT_X(_x)			((_x) << 11)
+#define VIDOSDxB_BOTRIGHT_X(_x)			(((_x) & 0x7ff) << 11)
 
+#define VIDOSDxB_BOTRIGHT_Y_E(_x)		((((_x) & 0x800) >> 11) << 22)
 #define VIDOSDxB_BOTRIGHT_Y_MASK		(0x7ff << 0)
 #define VIDOSDxB_BOTRIGHT_Y_SHIFT		(0)
 #define VIDOSDxB_BOTRIGHT_Y_LIMIT		(0x7ff)
-#define VIDOSDxB_BOTRIGHT_Y(_x)			((_x) << 0)
+#define VIDOSDxB_BOTRIGHT_Y(_x)			(((_x) & 0x7ff) << 0)
 
 /* For VIDOSD[1..4]C */
 #define VIDISD14C_ALPHA0_R(_x)			((_x) << 20)
@@ -278,15 +287,17 @@
 #define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
 #define VIDW_BUF_SIZE(_buff)			(0x100 + ((_buff) * 4))
 
+#define VIDW_BUF_SIZE_OFFSET_E(_x)		((((_x) & 0x2000) >> 13) << 27)
 #define VIDW_BUF_SIZE_OFFSET_MASK		(0x1fff << 13)
 #define VIDW_BUF_SIZE_OFFSET_SHIFT		(13)
 #define VIDW_BUF_SIZE_OFFSET_LIMIT		(0x1fff)
-#define VIDW_BUF_SIZE_OFFSET(_x)		((_x) << 13)
+#define VIDW_BUF_SIZE_OFFSET(_x)		(((_x) & 0x1fff) << 13)
 
+#define VIDW_BUF_SIZE_PAGEWIDTH_E(_x)		((((_x) & 0x2000) >> 13) << 26)
 #define VIDW_BUF_SIZE_PAGEWIDTH_MASK		(0x1fff << 0)
 #define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT		(0)
 #define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT		(0x1fff)
-#define VIDW_BUF_SIZE_PAGEWIDTH(_x)		((_x) << 0)
+#define VIDW_BUF_SIZE_PAGEWIDTH(_x)		(((_x) & 0x1fff) << 0)
 
 /* Interrupt controls and status */
 
@@ -384,3 +395,9 @@
 #define WPALCON_W0PAL_16BPP_A555		(0x5 << 0)
 #define WPALCON_W0PAL_16BPP_565			(0x6 << 0)
 
+/* Blending equation control */
+#define BLENDCON				(0x260)
+#define BLENDCON_NEW_MASK			(1 << 0)
+#define BLENDCON_NEW_8BIT_ALPHA_VALUE		(1 << 0)
+#define BLENDCON_NEW_4BIT_ALPHA_VALUE		(0 << 0)
+
diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile
index ecca820..6891257 100644
--- a/arch/c6x/boot/Makefile
+++ b/arch/c6x/boot/Makefile
@@ -13,7 +13,7 @@
 endif
 
 $(obj)/%.dtb: $(src)/dts/%.dts FORCE
-	$(call cmd,dtc)
+	$(call if_changed_dep,dtc)
 
 quiet_cmd_cp = CP      $< $@$2
 	cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h
index 756bde4..3c79368 100644
--- a/arch/m68k/include/asm/mcf_pgtable.h
+++ b/arch/m68k/include/asm/mcf_pgtable.h
@@ -78,7 +78,8 @@
 				 | CF_PAGE_READABLE \
 				 | CF_PAGE_WRITABLE \
 				 | CF_PAGE_EXEC \
-				 | CF_PAGE_SYSTEM)
+				 | CF_PAGE_SYSTEM \
+				 | CF_PAGE_SHARED)
 
 #define PAGE_COPY	__pgprot(CF_PAGE_VALID \
 				 | CF_PAGE_ACCESSED \
diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
index babd5a9..875b800 100644
--- a/arch/m68k/mm/mcfmmu.c
+++ b/arch/m68k/mm/mcfmmu.c
@@ -87,7 +87,7 @@
 
 int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
 {
-	unsigned long flags, mmuar;
+	unsigned long flags, mmuar, mmutr;
 	struct mm_struct *mm;
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -137,9 +137,10 @@
 	if (!pte_dirty(*pte) && !KMAPAREA(mmuar))
 		set_pte(pte, pte_wrprotect(*pte));
 
-	mmu_write(MMUTR, (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) |
-		(((int)(pte->pte) & (int)CF_PAGE_MMUTR_MASK)
-		>> CF_PAGE_MMUTR_SHIFT) | MMUTR_V);
+	mmutr = (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) | MMUTR_V;
+	if ((mmuar < TASK_UNMAPPED_BASE) || (mmuar >= TASK_SIZE))
+		mmutr |= (pte->pte & CF_PAGE_MMUTR_MASK) >> CF_PAGE_MMUTR_SHIFT;
+	mmu_write(MMUTR, mmutr);
 
 	mmu_write(MMUDR, (pte_val(*pte) & PAGE_MASK) |
 		((pte->pte) & CF_PAGE_MMUDR_MASK) | MMUDR_SZ_8KB | MMUDR_X);
diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S
index 863889f..281e38c 100644
--- a/arch/m68k/platform/coldfire/entry.S
+++ b/arch/m68k/platform/coldfire/entry.S
@@ -136,7 +136,7 @@
 	movel	%sp,%d1			/* get thread_info pointer */
 	andl	#-THREAD_SIZE,%d1	/* at base of kernel stack */
 	movel	%d1,%a0
-	movel	%a0@(TINFO_FLAGS),%d1	/* get thread_info->flags */
+	moveb	%a0@(TINFO_FLAGS+3),%d1	/* thread_info->flags (low 8 bits) */
 	jne	Lwork_to_do		/* still work to do */
 
 Lreturn:
@@ -148,8 +148,6 @@
 	btst	#TIF_NEED_RESCHED,%d1
 	jne	reschedule
 
-	/* GERG: do we need something here for TRACEing?? */
-
 Lsignal_return:
 	subql	#4,%sp			/* dummy return address */
 	SAVE_SWITCH_STACK
diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h
index 054537c..e612ce4 100644
--- a/arch/openrisc/include/asm/ptrace.h
+++ b/arch/openrisc/include/asm/ptrace.h
@@ -77,7 +77,6 @@
 	long  syscallno;	/* Syscall number (used by strace) */
 	long dummy;		/* Cheap alignment fix */
 };
-#endif /* __ASSEMBLY__ */
 
 /* TODO: Rename this to REDZONE because that's what it is */
 #define STACK_FRAME_OVERHEAD  128  /* size of minimum stack frame */
@@ -87,6 +86,13 @@
 #define user_stack_pointer(regs)	((unsigned long)(regs)->sp)
 #define profile_pc(regs)		instruction_pointer(regs)
 
+static inline long regs_return_value(struct pt_regs *regs)
+{
+	return regs->gpr[11];
+}
+
+#endif /* __ASSEMBLY__ */
+
 /*
  * Offsets used by 'ptrace' system call interface.
  */
diff --git a/arch/openrisc/kernel/init_task.c b/arch/openrisc/kernel/init_task.c
index 45744a38..ca53408 100644
--- a/arch/openrisc/kernel/init_task.c
+++ b/arch/openrisc/kernel/init_task.c
@@ -17,6 +17,7 @@
 
 #include <linux/init_task.h>
 #include <linux/mqueue.h>
+#include <linux/export.h>
 
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
 static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
diff --git a/arch/openrisc/kernel/irq.c b/arch/openrisc/kernel/irq.c
index 59b3023..4bfead2 100644
--- a/arch/openrisc/kernel/irq.c
+++ b/arch/openrisc/kernel/irq.c
@@ -23,6 +23,7 @@
 #include <linux/irq.h>
 #include <linux/seq_file.h>
 #include <linux/kernel_stat.h>
+#include <linux/export.h>
 
 #include <linux/irqflags.h>
 
diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c
index 656b94b..7259047 100644
--- a/arch/openrisc/kernel/ptrace.c
+++ b/arch/openrisc/kernel/ptrace.c
@@ -188,11 +188,9 @@
 		 */
 		ret = -1L;
 
-	/* Are these regs right??? */
-	if (unlikely(current->audit_context))
-		audit_syscall_entry(audit_arch(), regs->syscallno,
-				    regs->gpr[3], regs->gpr[4],
-				    regs->gpr[5], regs->gpr[6]);
+	audit_syscall_entry(audit_arch(), regs->syscallno,
+			    regs->gpr[3], regs->gpr[4],
+			    regs->gpr[5], regs->gpr[6]);
 
 	return ret ? : regs->syscallno;
 }
@@ -201,9 +199,7 @@
 {
 	int step;
 
-	if (unlikely(current->audit_context))
-		audit_syscall_exit(AUDITSC_RESULT(regs->gpr[11]),
-				   regs->gpr[11]);
+	audit_syscall_exit(regs);
 
 	step = test_thread_flag(TIF_SINGLESTEP);
 	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 55cca1d..19ab7b2 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -31,7 +31,11 @@
 UTS_MACHINE	:= parisc64
 CHECKFLAGS	+= -D__LP64__=1 -m64
 WIDTH		:= 64
+
+# FIXME: if no default set, should really try to locate dynamically
+ifeq ($(CROSS_COMPILE),)
 CROSS_COMPILE	:= hppa64-linux-gnu-
+endif
 else # 32-bit
 WIDTH		:=
 endif
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 2156e07..1acf650 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -24,10 +24,6 @@
 CONFIG_SCANLOG=m
 CONFIG_PPC_SMLPAR=y
 CONFIG_DTL=y
-CONFIG_PPC_ISERIES=y
-CONFIG_VIODASD=y
-CONFIG_VIOCD=m
-CONFIG_VIOTAPE=m
 CONFIG_PPC_MAPLE=y
 CONFIG_PPC_PASEMI=y
 CONFIG_PPC_PASEMI_IOMMU=y
@@ -259,7 +255,6 @@
 CONFIG_MLX4_EN=m
 CONFIG_QLGE=m
 CONFIG_BE2NET=m
-CONFIG_ISERIES_VETH=m
 CONFIG_PPP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 43268f1..6d42297 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -142,6 +142,11 @@
 	return pdev ? pci_name(pdev) : "<null>";
 } 
 
+static inline const char *eeh_driver_name(struct pci_dev *pdev)
+{
+	return (pdev && pdev->driver) ? pdev->driver->name : "<null>";
+}
+
 #endif /* CONFIG_EEH */
 
 #else /* CONFIG_PCI */
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 78a2051..84cc784 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -83,8 +83,18 @@
 
 #ifndef __ASSEMBLY__
 
-#define instruction_pointer(regs) ((regs)->nip)
-#define user_stack_pointer(regs) ((regs)->gpr[1])
+#define GET_IP(regs)		((regs)->nip)
+#define GET_USP(regs)		((regs)->gpr[1])
+#define GET_FP(regs)		(0)
+#define SET_FP(regs, val)
+
+#ifdef CONFIG_SMP
+extern unsigned long profile_pc(struct pt_regs *regs);
+#define profile_pc profile_pc
+#endif
+
+#include <asm-generic/ptrace.h>
+
 #define kernel_stack_pointer(regs) ((regs)->gpr[1])
 static inline int is_syscall_success(struct pt_regs *regs)
 {
@@ -99,12 +109,6 @@
 		return -regs->gpr[3];
 }
 
-#ifdef CONFIG_SMP
-extern unsigned long profile_pc(struct pt_regs *regs);
-#else
-#define profile_pc(regs) instruction_pointer(regs)
-#endif
-
 #ifdef __powerpc64__
 #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
 #else
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 4f80cf1..3e57a00 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -1213,7 +1213,7 @@
 	stw	r3,_TRAP(r1)
 2:	addi	r3,r1,STACK_FRAME_OVERHEAD
 	mr	r4,r9
-	bl	do_signal
+	bl	do_notify_resume
 	REST_NVGPRS(r1)
 	b	recheck
 
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index d834425..866462c 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -751,12 +751,16 @@
 
 	andi.	r0,r4,_TIF_NEED_RESCHED
 	beq	1f
+	li	r5,1
+	TRACE_AND_RESTORE_IRQ(r5);
 	bl	.schedule
 	b	.ret_from_except_lite
 
 1:	bl	.save_nvgprs
+	li	r5,1
+	TRACE_AND_RESTORE_IRQ(r5);
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.do_signal
+	bl	.do_notify_resume
 	b	.ret_from_except
 
 unrecov_restore:
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index d4be7bb..15c5a4f 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -774,8 +774,8 @@
 program_check_common:
 	EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
 	bl	.save_nvgprs
+	DISABLE_INTS
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	ENABLE_INTS
 	bl	.program_check_exception
 	b	.ret_from_except
 
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 701d4ac..01e2877 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -118,10 +118,14 @@
 static inline notrace void decrementer_check_overflow(void)
 {
 	u64 now = get_tb_or_rtc();
-	u64 *next_tb = &__get_cpu_var(decrementers_next_tb);
+	u64 *next_tb;
+
+	preempt_disable();
+	next_tb = &__get_cpu_var(decrementers_next_tb);
 
 	if (now >= *next_tb)
 		set_dec(1);
+	preempt_enable();
 }
 
 notrace void arch_local_irq_restore(unsigned long en)
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index 10a140f..64483fd 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -865,6 +865,7 @@
 {
 	unsigned long flags;
 	s64 left;
+	unsigned long val;
 
 	if (!event->hw.idx || !event->hw.sample_period)
 		return;
@@ -880,7 +881,12 @@
 
 	event->hw.state = 0;
 	left = local64_read(&event->hw.period_left);
-	write_pmc(event->hw.idx, left);
+
+	val = 0;
+	if (left < 0x80000000L)
+		val = 0x80000000L - left;
+
+	write_pmc(event->hw.idx, val);
 
 	perf_event_update_userpage(event);
 	perf_pmu_enable(event->pmu);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index ebe5766..d817ab0 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -566,12 +566,12 @@
 		 */
 		if (!__kernel_text_address(pc) ||
 		     __get_user(instr, (unsigned int __user *)pc)) {
-			printk("XXXXXXXX ");
+			printk(KERN_CONT "XXXXXXXX ");
 		} else {
 			if (regs->nip == pc)
-				printk("<%08x> ", instr);
+				printk(KERN_CONT "<%08x> ", instr);
 			else
-				printk("%08x ", instr);
+				printk(KERN_CONT "%08x ", instr);
 		}
 
 		pc += sizeof(int);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 517b1d8..9f843cd 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -716,7 +716,6 @@
 	int cpu;
 
 	slb_set_size(SLB_MIN_SIZE);
-	stop_topology_update();
 	printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id());
 
 	while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) &&
@@ -732,7 +731,6 @@
 		rc = atomic_read(&data->error);
 
 	atomic_set(&data->error, rc);
-	start_topology_update();
 	pSeries_coalesce_init();
 
 	if (wake_when_done) {
@@ -846,6 +844,7 @@
 	atomic_set(&data.error, 0);
 	data.token = rtas_token("ibm,suspend-me");
 	data.complete = &done;
+	stop_topology_update();
 
 	/* Call function on all CPUs.  One of us will make the
 	 * rtas call
@@ -858,6 +857,8 @@
 	if (atomic_read(&data.error) != 0)
 		printk(KERN_ERR "Error doing global join\n");
 
+	start_topology_update();
+
 	return atomic_read(&data.error);
 }
 #else /* CONFIG_PPC_PSERIES */
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 2300426..ac6e437 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
 
 #include <linux/tracehook.h>
 #include <linux/signal.h>
+#include <linux/key.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -113,8 +114,9 @@
 	}
 }
 
-static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
+static int do_signal(struct pt_regs *regs)
 {
+	sigset_t *oldset;
 	siginfo_t info;
 	int signr;
 	struct k_sigaction ka;
@@ -123,7 +125,7 @@
 
 	if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK)
 		oldset = &current->saved_sigmask;
-	else if (!oldset)
+	else
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -191,14 +193,16 @@
 	return ret;
 }
 
-void do_signal(struct pt_regs *regs, unsigned long thread_info_flags)
+void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
 {
 	if (thread_info_flags & _TIF_SIGPENDING)
-		do_signal_pending(NULL, regs);
+		do_signal(regs);
 
 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 		clear_thread_flag(TIF_NOTIFY_RESUME);
 		tracehook_notify_resume(regs);
+		if (current->replacement_session_keyring)
+			key_replace_session_keyring();
 	}
 }
 
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 6c0ddfc..8dde973 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -12,7 +12,7 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
+extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags);
 
 extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
 				  size_t frame_size, int is_32);
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index a70bc1e..f92b9ef 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -52,32 +52,38 @@
 
 static unsigned int pnv_get_one_msi(struct pnv_phb *phb)
 {
-	unsigned int id;
+	unsigned long flags;
+	unsigned int id, rc;
 
-	spin_lock(&phb->lock);
+	spin_lock_irqsave(&phb->lock, flags);
+
 	id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next);
 	if (id >= phb->msi_count && phb->msi_next)
 		id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0);
 	if (id >= phb->msi_count) {
-		spin_unlock(&phb->lock);
-		return 0;
+		rc = 0;
+		goto out;
 	}
 	__set_bit(id, phb->msi_map);
-	spin_unlock(&phb->lock);
-	return id + phb->msi_base;
+	rc = id + phb->msi_base;
+out:
+	spin_unlock_irqrestore(&phb->lock, flags);
+	return rc;
 }
 
 static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq)
 {
+	unsigned long flags;
 	unsigned int id;
 
 	if (WARN_ON(hwirq < phb->msi_base ||
 		    hwirq >= (phb->msi_base + phb->msi_count)))
 		return;
 	id = hwirq - phb->msi_base;
-	spin_lock(&phb->lock);
+
+	spin_lock_irqsave(&phb->lock, flags);
 	__clear_bit(id, phb->msi_map);
-	spin_unlock(&phb->lock);
+	spin_unlock_irqrestore(&phb->lock, flags);
 }
 
 static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 5658690..c0b40af 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -551,9 +551,9 @@
 			printk (KERN_ERR "EEH: %d reads ignored for recovering device at "
 				"location=%s driver=%s pci addr=%s\n",
 				pdn->eeh_check_count, location,
-				dev->driver->name, eeh_pci_name(dev));
+				eeh_driver_name(dev), eeh_pci_name(dev));
 			printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n",
-				dev->driver->name);
+				eeh_driver_name(dev));
 			dump_stack();
 		}
 		goto dn_unlock;
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c
index b84a8b2..47226e0 100644
--- a/arch/powerpc/platforms/pseries/suspend.c
+++ b/arch/powerpc/platforms/pseries/suspend.c
@@ -24,6 +24,7 @@
 #include <asm/machdep.h>
 #include <asm/mmu.h>
 #include <asm/rtas.h>
+#include <asm/topology.h>
 
 static u64 stream_id;
 static struct device suspend_dev;
@@ -138,8 +139,11 @@
 			ssleep(1);
 	} while (rc == -EAGAIN);
 
-	if (!rc)
+	if (!rc) {
+		stop_topology_update();
 		rc = pm_suspend(PM_SUSPEND_MEM);
+		start_topology_update();
+	}
 
 	stream_id = 0;
 
diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c
index 5768743..97fe82e 100644
--- a/arch/powerpc/platforms/wsp/ics.c
+++ b/arch/powerpc/platforms/wsp/ics.c
@@ -346,7 +346,7 @@
 	 * For the moment only implement delivery to all cpus or one cpu.
 	 * Get current irq_server for the given irq
 	 */
-	ret = cache_hwirq_map(ics, d->irq, cpumask);
+	ret = cache_hwirq_map(ics, hw_irq, cpumask);
 	if (ret == -1) {
 		char cpulist[128];
 		cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
diff --git a/arch/powerpc/platforms/wsp/smp.c b/arch/powerpc/platforms/wsp/smp.c
index 71bd105..0ba103a 100644
--- a/arch/powerpc/platforms/wsp/smp.c
+++ b/arch/powerpc/platforms/wsp/smp.c
@@ -71,7 +71,7 @@
 
 static int __init smp_a2_probe(void)
 {
-	return cpus_weight(cpu_possible_map);
+	return num_possible_cpus();
 }
 
 static struct smp_ops_t a2_smp_ops = {
diff --git a/arch/powerpc/platforms/wsp/wsp_pci.c b/arch/powerpc/platforms/wsp/wsp_pci.c
index e0262cd..d24b3ac 100644
--- a/arch/powerpc/platforms/wsp/wsp_pci.c
+++ b/arch/powerpc/platforms/wsp/wsp_pci.c
@@ -468,15 +468,15 @@
 #define DUMP_REG(x) \
 	pr_debug("%-30s : 0x%016llx\n", #x, in_be64(hose->cfg_data + x))
 
-#ifdef CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS
-	/* WSP DD1 has a bogus class code by default in the PCI-E
-	 * root complex's built-in P2P bridge */
+	/*
+	 * Some WSP variants  has a bogus class code by default in the PCI-E
+	 * root complex's built-in P2P bridge
+	 */
 	val = in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1);
 	pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", val);
 	out_be64(hose->cfg_data + PCIE_REG_SYS_CFG1,
 		 (val & ~PCIE_REG_SYS_CFG1_CLASS_CODE) | (PCI_CLASS_BRIDGE_PCI << 8));
 	pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1));
-#endif /* CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS */
 
 #ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
 	/* XXX Disable TCE caching, it doesn't work on DD1 */
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 30eb17e..6073288 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -385,26 +385,36 @@
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
 	struct pci_controller *hose = pci_bus_to_host(bus);
-	int i;
+	int i, is_pcie = 0, no_link;
 
-	if ((bus->parent == hose->bus) &&
-	    ((fsl_pcie_bus_fixup &&
-	      early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) ||
-	     (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)))
-	{
-		for (i = 0; i < 4; ++i) {
+	/* The root complex bridge comes up with bogus resources,
+	 * we copy the PHB ones in.
+	 *
+	 * With the current generic PCI code, the PHB bus no longer
+	 * has bus->resource[0..4] set, so things are a bit more
+	 * tricky.
+	 */
+
+	if (fsl_pcie_bus_fixup)
+		is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
+	no_link = !!(hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK);
+
+	if (bus->parent == hose->bus && (is_pcie || no_link)) {
+		for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; ++i) {
 			struct resource *res = bus->resource[i];
-			struct resource *par = bus->parent->resource[i];
-			if (res) {
-				res->start = 0;
-				res->end   = 0;
-				res->flags = 0;
-			}
-			if (res && par) {
-				res->start = par->start;
-				res->end   = par->end;
-				res->flags = par->flags;
-			}
+			struct resource *par;
+
+			if (!res)
+				continue;
+			if (i == 0)
+				par = &hose->io_resource;
+			else if (i < 4)
+				par = &hose->mem_resources[i-1];
+			else par = NULL;
+
+			res->start = par ? par->start : 0;
+			res->end   = par ? par->end   : 0;
+			res->flags = par ? par->flags : 0;
 		}
 	}
 }
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index d172758..6d99a5f 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -227,6 +227,9 @@
 config SYSVIPC_COMPAT
 	def_bool y if COMPAT && SYSVIPC
 
+config KEYS_COMPAT
+	def_bool y if COMPAT && KEYS
+
 config AUDIT_ARCH
 	def_bool y
 
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 2e49748..234f1d8 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -172,13 +172,6 @@
 	return is_32bit_task();
 }
 
-#else
-
-static inline int is_compat_task(void)
-{
-	return 0;
-}
-
 #endif
 
 static inline void __user *arch_compat_alloc_user_space(long len)
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 18c51df..ff605a3 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -662,7 +662,7 @@
 ENTRY(sys32_poll_wrapper)
 	llgtr	%r2,%r2			# struct pollfd *
 	llgfr	%r3,%r3			# unsigned int
-	lgfr	%r4,%r4			# long
+	lgfr	%r4,%r4			# int
 	jg	sys_poll		# branch to system call
 
 ENTRY(sys32_setresgid16_wrapper)
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index 39f8fd4..c383ce4 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/gfp.h>
 #include <linux/slab.h>
-#include <linux/crash_dump.h>
 #include <linux/bootmem.h>
 #include <linux/elf.h>
 #include <asm/ipl.h>
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 3201ae4..e795933 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -29,7 +29,6 @@
 #include <asm/irq.h>
 #include <asm/timer.h>
 #include <asm/nmi.h>
-#include <asm/compat.h>
 #include <asm/smp.h>
 #include "entry.h"
 
@@ -76,7 +75,6 @@
 	if (test_thread_flag(TIF_MCCK_PENDING)) {
 		local_mcck_enable();
 		local_irq_enable();
-		s390_handle_mcck();
 		return;
 	}
 	trace_hardirqs_on();
@@ -93,10 +91,12 @@
 	for (;;) {
 		tick_nohz_idle_enter();
 		rcu_idle_enter();
-		while (!need_resched())
+		while (!need_resched() && !test_thread_flag(TIF_MCCK_PENDING))
 			default_idle();
 		rcu_idle_exit();
 		tick_nohz_idle_exit();
+		if (test_thread_flag(TIF_MCCK_PENDING))
+			s390_handle_mcck();
 		preempt_enable_no_resched();
 		schedule();
 		preempt_disable();
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 9d82ed4..61f9548 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -20,8 +20,8 @@
 #include <linux/regset.h>
 #include <linux/tracehook.h>
 #include <linux/seccomp.h>
+#include <linux/compat.h>
 #include <trace/syscall.h>
-#include <asm/compat.h>
 #include <asm/segment.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 354de07..3b2efc8 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -46,6 +46,7 @@
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
 #include <linux/memory.h>
+#include <linux/compat.h>
 
 #include <asm/ipl.h>
 #include <asm/uaccess.h>
@@ -59,7 +60,6 @@
 #include <asm/ptrace.h>
 #include <asm/sections.h>
 #include <asm/ebcdic.h>
-#include <asm/compat.h>
 #include <asm/kvm_virtio.h>
 #include <asm/diag.h>
 
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index a8ba840..2d421d9 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -30,7 +30,6 @@
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/lowcore.h>
-#include <asm/compat.h>
 #include "entry.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index fa02f44..14da278 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -113,11 +113,14 @@
 static int s390_next_ktime(ktime_t expires,
 			   struct clock_event_device *evt)
 {
+	struct timespec ts;
 	u64 nsecs;
 
-	nsecs = ktime_to_ns(ktime_sub(expires, ktime_get_monotonic_offset()));
+	ts.tv_sec = ts.tv_nsec = 0;
+	monotonic_to_bootbased(&ts);
+	nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
 	do_div(nsecs, 125);
-	S390_lowcore.clock_comparator = TOD_UNIX_EPOCH + (nsecs << 9);
+	S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
 	set_clock_comparator(S390_lowcore.clock_comparator);
 	return 0;
 }
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 354dd39..e8fcd92 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -36,7 +36,6 @@
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
-#include <asm/compat.h>
 #include "../kernel/entry.h"
 
 #ifndef CONFIG_64BIT
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 5d63301..5023661 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -223,16 +223,38 @@
 #ifdef CONFIG_MEMORY_HOTPLUG
 int arch_add_memory(int nid, u64 start, u64 size)
 {
-	struct pglist_data *pgdat;
+	unsigned long zone_start_pfn, zone_end_pfn, nr_pages;
+	unsigned long start_pfn = PFN_DOWN(start);
+	unsigned long size_pages = PFN_DOWN(size);
 	struct zone *zone;
 	int rc;
 
-	pgdat = NODE_DATA(nid);
-	zone = pgdat->node_zones + ZONE_MOVABLE;
 	rc = vmem_add_mapping(start, size);
 	if (rc)
 		return rc;
-	rc = __add_pages(nid, zone, PFN_DOWN(start), PFN_DOWN(size));
+	for_each_zone(zone) {
+		if (zone_idx(zone) != ZONE_MOVABLE) {
+			/* Add range within existing zone limits */
+			zone_start_pfn = zone->zone_start_pfn;
+			zone_end_pfn = zone->zone_start_pfn +
+				       zone->spanned_pages;
+		} else {
+			/* Add remaining range to ZONE_MOVABLE */
+			zone_start_pfn = start_pfn;
+			zone_end_pfn = start_pfn + size_pages;
+		}
+		if (start_pfn < zone_start_pfn || start_pfn >= zone_end_pfn)
+			continue;
+		nr_pages = (start_pfn + size_pages > zone_end_pfn) ?
+			   zone_end_pfn - start_pfn : size_pages;
+		rc = __add_pages(nid, zone, start_pfn, nr_pages);
+		if (rc)
+			break;
+		start_pfn += nr_pages;
+		size_pages -= nr_pages;
+		if (!size_pages)
+			break;
+	}
 	if (rc)
 		vmem_remove_mapping(start, size);
 	return rc;
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index f09c748..a0155c0 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -29,8 +29,8 @@
 #include <linux/mman.h>
 #include <linux/module.h>
 #include <linux/random.h>
+#include <linux/compat.h>
 #include <asm/pgalloc.h>
-#include <asm/compat.h>
 
 static unsigned long stack_maxrandom_size(void)
 {
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 9a4d02f..51b0738 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -574,7 +574,7 @@
 	page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
 	mp = (struct gmap_pgtable *) page->index;
 	BUG_ON(!list_empty(&mp->mapper));
-	pgtable_page_ctor(page);
+	pgtable_page_dtor(page);
 	atomic_set(&page->_mapcount, -1);
 	kfree(mp);
 	__free_page(page);
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
index 0838154..24b1ee4 100644
--- a/arch/sh/boards/board-sh7757lcr.c
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -169,6 +169,11 @@
 		.end    = 0xfee00fff,
 		.flags  = IORESOURCE_MEM,
 	}, {
+		/* TSU */
+		.start  = 0xfee01800,
+		.end    = 0xfee01fff,
+		.flags  = IORESOURCE_MEM,
+	}, {
 		.start  = 316,
 		.end    = 316,
 		.flags  = IORESOURCE_IRQ,
@@ -210,20 +215,13 @@
 	},
 };
 
-static struct sh_mmcif_dma sh7757lcr_mmcif_dma = {
-	.chan_priv_tx	= {
-		.slave_id = SHDMA_SLAVE_MMCIF_TX,
-	},
-	.chan_priv_rx	= {
-		.slave_id = SHDMA_SLAVE_MMCIF_RX,
-	}
-};
-
 static struct sh_mmcif_plat_data sh_mmcif_plat = {
-	.dma		= &sh7757lcr_mmcif_dma,
 	.sup_pclk	= 0x0f,
-	.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+	.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
+			  MMC_CAP_NONREMOVABLE,
 	.ocr		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.slave_id_tx	= SHDMA_SLAVE_MMCIF_TX,
+	.slave_id_rx	= SHDMA_SLAVE_MMCIF_RX,
 };
 
 static struct platform_device sh_mmcif_device = {
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 6418e95..8cf02e3 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -22,6 +22,7 @@
 #include <linux/i2c.h>
 #include <linux/smsc911x.h>
 #include <linux/gpio.h>
+#include <linux/videodev2.h>
 #include <media/ov772x.h>
 #include <media/soc_camera.h>
 #include <media/soc_camera_platform.h>
@@ -156,7 +157,7 @@
 #define PORT_DRVCRA	0xA405018A
 #define PORT_DRVCRB	0xA405018C
 
-static int ap320_wvga_set_brightness(void *board_data, int brightness)
+static int ap320_wvga_set_brightness(int brightness)
 {
 	if (brightness) {
 		gpio_set_value(GPIO_PTS3, 0);
@@ -169,12 +170,12 @@
 	return 0;
 }
 
-static int ap320_wvga_get_brightness(void *board_data)
+static int ap320_wvga_get_brightness(void)
 {
 	return gpio_get_value(GPIO_PTS3);
 }
 
-static void ap320_wvga_power_on(void *board_data, struct fb_info *info)
+static void ap320_wvga_power_on(void)
 {
 	msleep(100);
 
@@ -182,7 +183,7 @@
 	__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
 }
 
-static void ap320_wvga_power_off(void *board_data)
+static void ap320_wvga_power_off(void)
 {
 	/* ASD AP-320/325 LCD OFF */
 	__raw_writew(0, FPGA_LCDREG);
@@ -210,21 +211,19 @@
 		.fourcc = V4L2_PIX_FMT_RGB565,
 		.interface_type = RGB18,
 		.clock_divider = 1,
-		.lcd_cfg = ap325rxa_lcdc_modes,
-		.num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes),
-		.lcd_size_cfg = { /* 7.0 inch */
-			.width = 152,
+		.lcd_modes = ap325rxa_lcdc_modes,
+		.num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes),
+		.panel_cfg = {
+			.width = 152,	/* 7.0 inch */
 			.height = 91,
-		},
-		.board_cfg = {
 			.display_on = ap320_wvga_power_on,
 			.display_off = ap320_wvga_power_off,
-			.set_brightness = ap320_wvga_set_brightness,
-			.get_brightness = ap320_wvga_get_brightness,
 		},
 		.bl_info = {
 			.name = "sh_mobile_lcdc_bl",
 			.max_brightness = 1,
+			.set_brightness = ap320_wvga_set_brightness,
+			.get_brightness = ap320_wvga_get_brightness,
 		},
 	}
 };
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 033ef2b..0b08230 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -29,9 +29,11 @@
 #include <linux/input.h>
 #include <linux/input/sh_keysc.h>
 #include <linux/sh_eth.h>
+#include <linux/videodev2.h>
 #include <video/sh_mobile_lcdc.h>
 #include <sound/sh_fsi.h>
 #include <media/sh_mobile_ceu.h>
+#include <media/soc_camera.h>
 #include <media/tw9910.h>
 #include <media/mt9t112.h>
 #include <asm/heartbeat.h>
@@ -308,14 +310,14 @@
 	},
 };
 
-static int ecovec24_set_brightness(void *board_data, int brightness)
+static int ecovec24_set_brightness(int brightness)
 {
 	gpio_set_value(GPIO_PTR1, brightness);
 
 	return 0;
 }
 
-static int ecovec24_get_brightness(void *board_data)
+static int ecovec24_get_brightness(void)
 {
 	return gpio_get_value(GPIO_PTR1);
 }
@@ -325,17 +327,15 @@
 		.interface_type = RGB18,
 		.chan = LCDC_CHAN_MAINLCD,
 		.fourcc = V4L2_PIX_FMT_RGB565,
-		.lcd_size_cfg = { /* 7.0 inch */
+		.panel_cfg = { /* 7.0 inch */
 			.width = 152,
 			.height = 91,
 		},
-		.board_cfg = {
-			.set_brightness = ecovec24_set_brightness,
-			.get_brightness = ecovec24_get_brightness,
-		},
 		.bl_info = {
 			.name = "sh_mobile_lcdc_bl",
 			.max_brightness = 1,
+			.set_brightness = ecovec24_set_brightness,
+			.get_brightness = ecovec24_get_brightness,
 		},
 	}
 };
@@ -1114,8 +1114,8 @@
 		/* DVI */
 		lcdc_info.clock_source			= LCDC_CLK_EXTERNAL;
 		lcdc_info.ch[0].clock_divider		= 1;
-		lcdc_info.ch[0].lcd_cfg			= ecovec_dvi_modes;
-		lcdc_info.ch[0].num_cfg			= ARRAY_SIZE(ecovec_dvi_modes);
+		lcdc_info.ch[0].lcd_modes		= ecovec_dvi_modes;
+		lcdc_info.ch[0].num_modes		= ARRAY_SIZE(ecovec_dvi_modes);
 
 		gpio_set_value(GPIO_PTA2, 1);
 		gpio_set_value(GPIO_PTU1, 1);
@@ -1123,8 +1123,8 @@
 		/* Panel */
 		lcdc_info.clock_source			= LCDC_CLK_PERIPHERAL;
 		lcdc_info.ch[0].clock_divider		= 2;
-		lcdc_info.ch[0].lcd_cfg			= ecovec_lcd_modes;
-		lcdc_info.ch[0].num_cfg			= ARRAY_SIZE(ecovec_lcd_modes);
+		lcdc_info.ch[0].lcd_modes		= ecovec_lcd_modes;
+		lcdc_info.ch[0].num_modes		= ARRAY_SIZE(ecovec_lcd_modes);
 
 		gpio_set_value(GPIO_PTR1, 1);
 
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
index 25e145f..c148b36 100644
--- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
+++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
@@ -251,8 +251,7 @@
 	write_memory_start(sohandle, so);
 }
 
-int kfr2r09_lcd_setup(void *board_data, void *sohandle,
-		      struct sh_mobile_lcdc_sys_bus_ops *so)
+int kfr2r09_lcd_setup(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
 {
 	/* power on */
 	gpio_set_value(GPIO_PTF4, 0);  /* PROTECT/ -> L */
@@ -273,8 +272,7 @@
 	return 0;
 }
 
-void kfr2r09_lcd_start(void *board_data, void *sohandle,
-		       struct sh_mobile_lcdc_sys_bus_ops *so)
+void kfr2r09_lcd_start(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
 {
 	write_memory_start(sohandle, so);
 }
@@ -327,12 +325,12 @@
 	return 0;
 }
 
-void kfr2r09_lcd_on(void *board_data, struct fb_info *info)
+void kfr2r09_lcd_on(void)
 {
 	kfr2r09_lcd_backlight(1);
 }
 
-void kfr2r09_lcd_off(void *board_data)
+void kfr2r09_lcd_off(void)
 {
 	kfr2r09_lcd_backlight(0);
 }
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 2a18b06..d04a55d 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -22,6 +22,7 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/i2c.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/videodev2.h>
 #include <media/rj54n1cb0c.h>
 #include <media/soc_camera.h>
 #include <media/sh_mobile_ceu.h>
@@ -147,13 +148,11 @@
 		.interface_type = SYS18,
 		.clock_divider = 6,
 		.flags = LCDC_FLAGS_DWPOL,
-		.lcd_cfg = kfr2r09_lcdc_modes,
-		.num_cfg = ARRAY_SIZE(kfr2r09_lcdc_modes),
-		.lcd_size_cfg = {
+		.lcd_modes = kfr2r09_lcdc_modes,
+		.num_modes = ARRAY_SIZE(kfr2r09_lcdc_modes),
+		.panel_cfg = {
 			.width = 35,
 			.height = 58,
-		},
-		.board_cfg = {
 			.setup_sys = kfr2r09_lcd_setup,
 			.start_transfer = kfr2r09_lcd_start,
 			.display_on = kfr2r09_lcd_on,
diff --git a/arch/sh/boards/mach-migor/lcd_qvga.c b/arch/sh/boards/mach-migor/lcd_qvga.c
index de9014a..8bccd34 100644
--- a/arch/sh/boards/mach-migor/lcd_qvga.c
+++ b/arch/sh/boards/mach-migor/lcd_qvga.c
@@ -113,8 +113,7 @@
 	0x0010, 0x16B0, 0x0011, 0x0111, 0x0007, 0x0061,
 };
 
-int migor_lcd_qvga_setup(void *board_data, void *sohandle,
-			 struct sh_mobile_lcdc_sys_bus_ops *so)
+int migor_lcd_qvga_setup(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
 {
 	unsigned long xres = 320;
 	unsigned long yres = 240;
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 68c3d6f..ff6f69c 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -21,9 +21,11 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/videodev2.h>
 #include <video/sh_mobile_lcdc.h>
 #include <media/sh_mobile_ceu.h>
 #include <media/ov772x.h>
+#include <media/soc_camera.h>
 #include <media/tw9910.h>
 #include <asm/clock.h>
 #include <asm/machvec.h>
@@ -244,9 +246,9 @@
 		.fourcc = V4L2_PIX_FMT_RGB565,
 		.interface_type = RGB16,
 		.clock_divider = 2,
-		.lcd_cfg = migor_lcd_modes,
-		.num_cfg = ARRAY_SIZE(migor_lcd_modes),
-		.lcd_size_cfg = { /* 7.0 inch */
+		.lcd_modes = migor_lcd_modes,
+		.num_modes = ARRAY_SIZE(migor_lcd_modes),
+		.panel_cfg = { /* 7.0 inch */
 			.width = 152,
 			.height = 91,
 		},
@@ -258,13 +260,11 @@
 		.fourcc = V4L2_PIX_FMT_RGB565,
 		.interface_type = SYS16A,
 		.clock_divider = 10,
-		.lcd_cfg = migor_lcd_modes,
-		.num_cfg = ARRAY_SIZE(migor_lcd_modes),
-		.lcd_size_cfg = { /* 2.4 inch */
-			.width = 49,
+		.lcd_modes = migor_lcd_modes,
+		.num_modes = ARRAY_SIZE(migor_lcd_modes),
+		.panel_cfg = {
+			.width = 49,	/* 2.4 inch */
 			.height = 37,
-		},
-		.board_cfg = {
 			.setup_sys = migor_lcd_qvga_setup,
 		},
 		.sys_bus_cfg = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 036fe1a..9bf528b 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -24,6 +24,7 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/sh_eth.h>
+#include <linux/videodev2.h>
 #include <video/sh_mobile_lcdc.h>
 #include <media/sh_mobile_ceu.h>
 #include <sound/sh_fsi.h>
@@ -181,12 +182,10 @@
 		.chan = LCDC_CHAN_MAINLCD,
 		.fourcc = V4L2_PIX_FMT_RGB565,
 		.clock_divider = 1,
-		.lcd_size_cfg = { /* 7.0 inch */
+		.panel_cfg = { /* 7.0 inch */
 			.width = 152,
 			.height = 91,
 		},
-		.board_cfg = {
-		},
 	}
 };
 
@@ -887,12 +886,12 @@
 
 	if (sw & SW41_B) {
 		/* 720p */
-		lcdc_info.ch[0].lcd_cfg	= lcdc_720p_modes;
-		lcdc_info.ch[0].num_cfg	= ARRAY_SIZE(lcdc_720p_modes);
+		lcdc_info.ch[0].lcd_modes = lcdc_720p_modes;
+		lcdc_info.ch[0].num_modes = ARRAY_SIZE(lcdc_720p_modes);
 	} else {
 		/* VGA */
-		lcdc_info.ch[0].lcd_cfg	= lcdc_vga_modes;
-		lcdc_info.ch[0].num_cfg	= ARRAY_SIZE(lcdc_vga_modes);
+		lcdc_info.ch[0].lcd_modes = lcdc_vga_modes;
+		lcdc_info.ch[0].num_modes = ARRAY_SIZE(lcdc_vga_modes);
 	}
 
 	if (sw & SW41_A) {
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index fa7b978..fb8f1499 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -74,7 +74,7 @@
 	{ SH4_PCIINT_MLCK,	"master lock error" },
 	{ SH4_PCIINT_TABT,	"target-target abort" },
 	{ SH4_PCIINT_TRET,	"target retry time out" },
-	{ SH4_PCIINT_MFDE,	"master function disable erorr" },
+	{ SH4_PCIINT_MFDE,	"master function disable error" },
 	{ SH4_PCIINT_PRTY,	"address parity error" },
 	{ SH4_PCIINT_SERR,	"SERR" },
 	{ SH4_PCIINT_TWDP,	"data parity error for target write" },
diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h
index a1c9c0d..071bcb4 100644
--- a/arch/sh/include/asm/device.h
+++ b/arch/sh/include/asm/device.h
@@ -3,9 +3,10 @@
  *
  * This file is released under the GPLv2
  */
+#ifndef __ASM_SH_DEVICE_H
+#define __ASM_SH_DEVICE_H
 
-struct dev_archdata {
-};
+#include <asm-generic/device.h>
 
 struct platform_device;
 /* allocate contiguous memory chunk and fill in struct resource */
@@ -14,5 +15,4 @@
 
 void plat_early_device_setup(void);
 
-struct pdev_archdata {
-};
+#endif /* __ASM_SH_DEVICE_H */
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
index 07e635b..ba3d93d 100644
--- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
+++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
@@ -4,21 +4,21 @@
 #include <video/sh_mobile_lcdc.h>
 
 #if defined(CONFIG_FB_SH_MOBILE_LCDC) || defined(CONFIG_FB_SH_MOBILE_LCDC_MODULE)
-void kfr2r09_lcd_on(void *board_data, struct fb_info *info);
-void kfr2r09_lcd_off(void *board_data);
-int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+void kfr2r09_lcd_on(void);
+void kfr2r09_lcd_off(void);
+int kfr2r09_lcd_setup(void *sys_ops_handle,
 		      struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
-void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle,
+void kfr2r09_lcd_start(void *sys_ops_handle,
 		       struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
 #else
-static void kfr2r09_lcd_on(void *board_data) {}
-static void kfr2r09_lcd_off(void *board_data) {}
-static int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+static void kfr2r09_lcd_on(void) {}
+static void kfr2r09_lcd_off(void) {}
+static int kfr2r09_lcd_setup(void *sys_ops_handle,
 				struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
 {
 	return -ENODEV;
 }
-static void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle,
+static void kfr2r09_lcd_start(void *sys_ops_handle,
 				struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
 {
 }
diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h
index 42fccf9..7de7bb7 100644
--- a/arch/sh/include/mach-migor/mach/migor.h
+++ b/arch/sh/include/mach-migor/mach/migor.h
@@ -9,7 +9,7 @@
 
 #include <video/sh_mobile_lcdc.h>
 
-int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
+int migor_lcd_qvga_setup(void *sys_ops_handle,
 			 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
 
 #endif /* __ASM_SH_MIGOR_H */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index b3c039a..70bd966 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -343,7 +343,7 @@
 	CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[HWBLK_CEU1]),
 	CLKDEV_CON_ID("beu1", &mstp_clks[HWBLK_BEU1]),
 	CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
-	CLKDEV_CON_ID("spu0", &mstp_clks[HWBLK_SPU]),
+	CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]),
 	CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
 	CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
 	CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]),
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index a7b2da6..2875e8b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -133,7 +133,7 @@
 	[0] = {
 		.start	= 0xfe002000,
 		.end	= 0xfe0020ff,
-		.flags	= IORESOURCE_MEM,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
 	},
 	[1] = {
 		.start	= 86,
@@ -661,6 +661,25 @@
 	.resource	= spi0_resources,
 };
 
+static struct resource spi1_resources[] = {
+	{
+		.start	= 0xffd8ee70,
+		.end	= 0xffd8eeff,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+	},
+	{
+		.start	= 54,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device spi1_device = {
+	.name	= "sh_spi",
+	.id	= 1,
+	.num_resources	= ARRAY_SIZE(spi1_resources),
+	.resource	= spi1_resources,
+};
+
 static struct resource usb_ehci_resources[] = {
 	[0] = {
 		.start	= 0xfe4f1000,
@@ -720,6 +739,7 @@
 	&dma2_device,
 	&dma3_device,
 	&spi0_device,
+	&spi1_device,
 	&usb_ehci_device,
 	&usb_ohci_device,
 };
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 3147a9a..f624174 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -63,7 +63,7 @@
 	mp_ops->prepare_cpus(max_cpus);
 
 #ifndef CONFIG_HOTPLUG_CPU
-	init_cpu_present(&cpu_possible_map);
+	init_cpu_present(cpu_possible_mask);
 #endif
 }
 
diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c
index 4649a6f..772caff 100644
--- a/arch/sh/kernel/topology.c
+++ b/arch/sh/kernel/topology.c
@@ -27,7 +27,7 @@
 	 * Presently all SH-X3 SMP cores are multi-cores, so just keep it
 	 * simple until we have a method for determining topology..
 	 */
-	return cpu_possible_map;
+	return *cpu_possible_mask;
 }
 
 const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index ae08cbb..949e2d3 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -23,6 +23,7 @@
 #define MAX_OCACHE_PAGES	32
 #define MAX_ICACHE_PAGES	32
 
+#ifdef CONFIG_CACHE_WRITEBACK
 static void sh2a_flush_oc_line(unsigned long v, int way)
 {
 	unsigned long addr = (v & 0x000007f0) | (way << 11);
@@ -34,6 +35,7 @@
 		__raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr);
 	}
 }
+#endif
 
 static void sh2a_invalidate_line(unsigned long cache_addr, unsigned long v)
 {
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index 6919e93..2479049 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -29,10 +29,11 @@
 extern void fpu_init(void);
 extern void mxcsr_feature_mask_init(void);
 extern int init_fpu(struct task_struct *child);
-extern asmlinkage void math_state_restore(void);
-extern void __math_state_restore(void);
+extern void math_state_restore(void);
 extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
 
+DECLARE_PER_CPU(struct task_struct *, fpu_owner_task);
+
 extern user_regset_active_fn fpregs_active, xfpregs_active;
 extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get,
 				xstateregs_get;
@@ -212,19 +213,11 @@
 
 #endif	/* CONFIG_X86_64 */
 
-/* We need a safe address that is cheap to find and that is already
-   in L1 during context switch. The best choices are unfortunately
-   different for UP and SMP */
-#ifdef CONFIG_SMP
-#define safe_address (__per_cpu_offset[0])
-#else
-#define safe_address (__get_cpu_var(kernel_cpustat).cpustat[CPUTIME_USER])
-#endif
-
 /*
- * These must be called with preempt disabled
+ * These must be called with preempt disabled. Returns
+ * 'true' if the FPU state is still intact.
  */
-static inline void fpu_save_init(struct fpu *fpu)
+static inline int fpu_save_init(struct fpu *fpu)
 {
 	if (use_xsave()) {
 		fpu_xsave(fpu);
@@ -233,33 +226,33 @@
 		 * xsave header may indicate the init state of the FP.
 		 */
 		if (!(fpu->state->xsave.xsave_hdr.xstate_bv & XSTATE_FP))
-			return;
+			return 1;
 	} else if (use_fxsr()) {
 		fpu_fxsave(fpu);
 	} else {
 		asm volatile("fnsave %[fx]; fwait"
 			     : [fx] "=m" (fpu->state->fsave));
-		return;
+		return 0;
 	}
 
-	if (unlikely(fpu->state->fxsave.swd & X87_FSW_ES))
+	/*
+	 * If exceptions are pending, we need to clear them so
+	 * that we don't randomly get exceptions later.
+	 *
+	 * FIXME! Is this perhaps only true for the old-style
+	 * irq13 case? Maybe we could leave the x87 state
+	 * intact otherwise?
+	 */
+	if (unlikely(fpu->state->fxsave.swd & X87_FSW_ES)) {
 		asm volatile("fnclex");
-
-	/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
-	   is pending.  Clear the x87 state here by setting it to fixed
-	   values. safe_address is a random variable that should be in L1 */
-	alternative_input(
-		ASM_NOP8 ASM_NOP2,
-		"emms\n\t"	  	/* clear stack tags */
-		"fildl %P[addr]",	/* set F?P to defined value */
-		X86_FEATURE_FXSAVE_LEAK,
-		[addr] "m" (safe_address));
+		return 0;
+	}
+	return 1;
 }
 
-static inline void __save_init_fpu(struct task_struct *tsk)
+static inline int __save_init_fpu(struct task_struct *tsk)
 {
-	fpu_save_init(&tsk->thread.fpu);
-	task_thread_info(tsk)->status &= ~TS_USEDFPU;
+	return fpu_save_init(&tsk->thread.fpu);
 }
 
 static inline int fpu_fxrstor_checking(struct fpu *fpu)
@@ -277,44 +270,212 @@
 
 static inline int restore_fpu_checking(struct task_struct *tsk)
 {
+	/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
+	   is pending.  Clear the x87 state here by setting it to fixed
+	   values. "m" is a random variable that should be in L1 */
+	alternative_input(
+		ASM_NOP8 ASM_NOP2,
+		"emms\n\t"	  	/* clear stack tags */
+		"fildl %P[addr]",	/* set F?P to defined value */
+		X86_FEATURE_FXSAVE_LEAK,
+		[addr] "m" (tsk->thread.fpu.has_fpu));
+
 	return fpu_restore_checking(&tsk->thread.fpu);
 }
 
 /*
+ * Software FPU state helpers. Careful: these need to
+ * be preemption protection *and* they need to be
+ * properly paired with the CR0.TS changes!
+ */
+static inline int __thread_has_fpu(struct task_struct *tsk)
+{
+	return tsk->thread.fpu.has_fpu;
+}
+
+/* Must be paired with an 'stts' after! */
+static inline void __thread_clear_has_fpu(struct task_struct *tsk)
+{
+	tsk->thread.fpu.has_fpu = 0;
+	percpu_write(fpu_owner_task, NULL);
+}
+
+/* Must be paired with a 'clts' before! */
+static inline void __thread_set_has_fpu(struct task_struct *tsk)
+{
+	tsk->thread.fpu.has_fpu = 1;
+	percpu_write(fpu_owner_task, tsk);
+}
+
+/*
+ * Encapsulate the CR0.TS handling together with the
+ * software flag.
+ *
+ * These generally need preemption protection to work,
+ * do try to avoid using these on their own.
+ */
+static inline void __thread_fpu_end(struct task_struct *tsk)
+{
+	__thread_clear_has_fpu(tsk);
+	stts();
+}
+
+static inline void __thread_fpu_begin(struct task_struct *tsk)
+{
+	clts();
+	__thread_set_has_fpu(tsk);
+}
+
+/*
+ * FPU state switching for scheduling.
+ *
+ * This is a two-stage process:
+ *
+ *  - switch_fpu_prepare() saves the old state and
+ *    sets the new state of the CR0.TS bit. This is
+ *    done within the context of the old process.
+ *
+ *  - switch_fpu_finish() restores the new state as
+ *    necessary.
+ */
+typedef struct { int preload; } fpu_switch_t;
+
+/*
+ * FIXME! We could do a totally lazy restore, but we need to
+ * add a per-cpu "this was the task that last touched the FPU
+ * on this CPU" variable, and the task needs to have a "I last
+ * touched the FPU on this CPU" and check them.
+ *
+ * We don't do that yet, so "fpu_lazy_restore()" always returns
+ * false, but some day..
+ */
+static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu)
+{
+	return new == percpu_read_stable(fpu_owner_task) &&
+		cpu == new->thread.fpu.last_cpu;
+}
+
+static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct task_struct *new, int cpu)
+{
+	fpu_switch_t fpu;
+
+	fpu.preload = tsk_used_math(new) && new->fpu_counter > 5;
+	if (__thread_has_fpu(old)) {
+		if (!__save_init_fpu(old))
+			cpu = ~0;
+		old->thread.fpu.last_cpu = cpu;
+		old->thread.fpu.has_fpu = 0;	/* But leave fpu_owner_task! */
+
+		/* Don't change CR0.TS if we just switch! */
+		if (fpu.preload) {
+			new->fpu_counter++;
+			__thread_set_has_fpu(new);
+			prefetch(new->thread.fpu.state);
+		} else
+			stts();
+	} else {
+		old->fpu_counter = 0;
+		old->thread.fpu.last_cpu = ~0;
+		if (fpu.preload) {
+			new->fpu_counter++;
+			if (fpu_lazy_restore(new, cpu))
+				fpu.preload = 0;
+			else
+				prefetch(new->thread.fpu.state);
+			__thread_fpu_begin(new);
+		}
+	}
+	return fpu;
+}
+
+/*
+ * By the time this gets called, we've already cleared CR0.TS and
+ * given the process the FPU if we are going to preload the FPU
+ * state - all we need to do is to conditionally restore the register
+ * state itself.
+ */
+static inline void switch_fpu_finish(struct task_struct *new, fpu_switch_t fpu)
+{
+	if (fpu.preload) {
+		if (unlikely(restore_fpu_checking(new)))
+			__thread_fpu_end(new);
+	}
+}
+
+/*
  * Signal frame handlers...
  */
 extern int save_i387_xstate(void __user *buf);
 extern int restore_i387_xstate(void __user *buf);
 
-static inline void __unlazy_fpu(struct task_struct *tsk)
-{
-	if (task_thread_info(tsk)->status & TS_USEDFPU) {
-		__save_init_fpu(tsk);
-		stts();
-	} else
-		tsk->fpu_counter = 0;
-}
-
 static inline void __clear_fpu(struct task_struct *tsk)
 {
-	if (task_thread_info(tsk)->status & TS_USEDFPU) {
+	if (__thread_has_fpu(tsk)) {
 		/* Ignore delayed exceptions from user space */
 		asm volatile("1: fwait\n"
 			     "2:\n"
 			     _ASM_EXTABLE(1b, 2b));
-		task_thread_info(tsk)->status &= ~TS_USEDFPU;
-		stts();
+		__thread_fpu_end(tsk);
 	}
 }
 
+/*
+ * Were we in an interrupt that interrupted kernel mode?
+ *
+ * We can do a kernel_fpu_begin/end() pair *ONLY* if that
+ * pair does nothing at all: the thread must not have fpu (so
+ * that we don't try to save the FPU state), and TS must
+ * be set (so that the clts/stts pair does nothing that is
+ * visible in the interrupted kernel thread).
+ */
+static inline bool interrupted_kernel_fpu_idle(void)
+{
+	return !__thread_has_fpu(current) &&
+		(read_cr0() & X86_CR0_TS);
+}
+
+/*
+ * Were we in user mode (or vm86 mode) when we were
+ * interrupted?
+ *
+ * Doing kernel_fpu_begin/end() is ok if we are running
+ * in an interrupt context from user mode - we'll just
+ * save the FPU state as required.
+ */
+static inline bool interrupted_user_mode(void)
+{
+	struct pt_regs *regs = get_irq_regs();
+	return regs && user_mode_vm(regs);
+}
+
+/*
+ * Can we use the FPU in kernel mode with the
+ * whole "kernel_fpu_begin/end()" sequence?
+ *
+ * It's always ok in process context (ie "not interrupt")
+ * but it is sometimes ok even from an irq.
+ */
+static inline bool irq_fpu_usable(void)
+{
+	return !in_interrupt() ||
+		interrupted_user_mode() ||
+		interrupted_kernel_fpu_idle();
+}
+
 static inline void kernel_fpu_begin(void)
 {
-	struct thread_info *me = current_thread_info();
+	struct task_struct *me = current;
+
+	WARN_ON_ONCE(!irq_fpu_usable());
 	preempt_disable();
-	if (me->status & TS_USEDFPU)
-		__save_init_fpu(me->task);
-	else
+	if (__thread_has_fpu(me)) {
+		__save_init_fpu(me);
+		__thread_clear_has_fpu(me);
+		/* We do 'stts()' in kernel_fpu_end() */
+	} else {
+		percpu_write(fpu_owner_task, NULL);
 		clts();
+	}
 }
 
 static inline void kernel_fpu_end(void)
@@ -323,14 +484,6 @@
 	preempt_enable();
 }
 
-static inline bool irq_fpu_usable(void)
-{
-	struct pt_regs *regs;
-
-	return !in_interrupt() || !(regs = get_irq_regs()) || \
-		user_mode(regs) || (read_cr0() & X86_CR0_TS);
-}
-
 /*
  * Some instructions like VIA's padlock instructions generate a spurious
  * DNA fault but don't modify SSE registers. And these instructions
@@ -363,20 +516,64 @@
 }
 
 /*
+ * The question "does this thread have fpu access?"
+ * is slightly racy, since preemption could come in
+ * and revoke it immediately after the test.
+ *
+ * However, even in that very unlikely scenario,
+ * we can just assume we have FPU access - typically
+ * to save the FP state - we'll just take a #NM
+ * fault and get the FPU access back.
+ *
+ * The actual user_fpu_begin/end() functions
+ * need to be preemption-safe, though.
+ *
+ * NOTE! user_fpu_end() must be used only after you
+ * have saved the FP state, and user_fpu_begin() must
+ * be used only immediately before restoring it.
+ * These functions do not do any save/restore on
+ * their own.
+ */
+static inline int user_has_fpu(void)
+{
+	return __thread_has_fpu(current);
+}
+
+static inline void user_fpu_end(void)
+{
+	preempt_disable();
+	__thread_fpu_end(current);
+	preempt_enable();
+}
+
+static inline void user_fpu_begin(void)
+{
+	preempt_disable();
+	if (!user_has_fpu())
+		__thread_fpu_begin(current);
+	preempt_enable();
+}
+
+/*
  * These disable preemption on their own and are safe
  */
 static inline void save_init_fpu(struct task_struct *tsk)
 {
+	WARN_ON_ONCE(!__thread_has_fpu(tsk));
 	preempt_disable();
 	__save_init_fpu(tsk);
-	stts();
+	__thread_fpu_end(tsk);
 	preempt_enable();
 }
 
 static inline void unlazy_fpu(struct task_struct *tsk)
 {
 	preempt_disable();
-	__unlazy_fpu(tsk);
+	if (__thread_has_fpu(tsk)) {
+		__save_init_fpu(tsk);
+		__thread_fpu_end(tsk);
+	} else
+		tsk->fpu_counter = 0;
 	preempt_enable();
 }
 
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 096c975..461ce43 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -242,4 +242,12 @@
 static inline void perf_events_lapic_init(void)	{ }
 #endif
 
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
+ extern void amd_pmu_enable_virt(void);
+ extern void amd_pmu_disable_virt(void);
+#else
+ static inline void amd_pmu_enable_virt(void) { }
+ static inline void amd_pmu_disable_virt(void) { }
+#endif
+
 #endif /* _ASM_X86_PERF_EVENT_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index aa9088c..58545c9 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -374,6 +374,8 @@
 };
 
 struct fpu {
+	unsigned int last_cpu;
+	unsigned int has_fpu;
 	union thread_xstate *state;
 };
 
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index bc817cd..cfd8144 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -247,8 +247,6 @@
  * ever touches our thread-synchronous status, so we don't
  * have to worry about atomic accesses.
  */
-#define TS_USEDFPU		0x0001	/* FPU was used by this task
-					   this quantum (SMP) */
 #define TS_COMPAT		0x0002	/* 32bit syscall active (64BIT)*/
 #define TS_POLLING		0x0004	/* idle task polling need_resched,
 					   skip sending interrupt */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index d43cad7..c0f7d68 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1044,6 +1044,9 @@
 
 DEFINE_PER_CPU(unsigned int, irq_count) = -1;
 
+DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);
+EXPORT_PER_CPU_SYMBOL(fpu_owner_task);
+
 /*
  * Special IST stacks which the CPU switches to when it calls
  * an IST-marked descriptor entry. Up to 7 stacks (hardware
@@ -1111,6 +1114,8 @@
 
 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
 EXPORT_PER_CPU_SYMBOL(current_task);
+DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);
+EXPORT_PER_CPU_SYMBOL(fpu_owner_task);
 
 #ifdef CONFIG_CC_STACKPROTECTOR
 DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 6b45e5e..73d08ed 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -326,8 +326,7 @@
 	l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
 }
 
-static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf,
-					int index)
+static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index)
 {
 	int node;
 
@@ -725,14 +724,16 @@
 #define CPUID4_INFO_IDX(x, y)	(&((per_cpu(ici_cpuid4_info, x))[y]))
 
 #ifdef CONFIG_SMP
-static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+
+static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
 {
-	struct _cpuid4_info	*this_leaf, *sibling_leaf;
-	unsigned long num_threads_sharing;
-	int index_msb, i, sibling;
+	struct _cpuid4_info *this_leaf;
+	int ret, i, sibling;
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
-	if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
+	ret = 0;
+	if (index == 3) {
+		ret = 1;
 		for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
 			if (!per_cpu(ici_cpuid4_info, i))
 				continue;
@@ -743,8 +744,35 @@
 				set_bit(sibling, this_leaf->shared_cpu_map);
 			}
 		}
-		return;
+	} else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) {
+		ret = 1;
+		for_each_cpu(i, cpu_sibling_mask(cpu)) {
+			if (!per_cpu(ici_cpuid4_info, i))
+				continue;
+			this_leaf = CPUID4_INFO_IDX(i, index);
+			for_each_cpu(sibling, cpu_sibling_mask(cpu)) {
+				if (!cpu_online(sibling))
+					continue;
+				set_bit(sibling, this_leaf->shared_cpu_map);
+			}
+		}
 	}
+
+	return ret;
+}
+
+static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+{
+	struct _cpuid4_info *this_leaf, *sibling_leaf;
+	unsigned long num_threads_sharing;
+	int index_msb, i;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+	if (c->x86_vendor == X86_VENDOR_AMD) {
+		if (cache_shared_amd_cpu_map_setup(cpu, index))
+			return;
+	}
+
 	this_leaf = CPUID4_INFO_IDX(cpu, index);
 	num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing;
 
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 786e76a..e4eeaaf 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -528,6 +528,7 @@
 
 	sprintf(name, "threshold_bank%i", bank);
 
+#ifdef CONFIG_SMP
 	if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) {	/* symlink */
 		i = cpumask_first(cpu_llc_shared_mask(cpu));
 
@@ -553,6 +554,7 @@
 
 		goto out;
 	}
+#endif
 
 	b = kzalloc(sizeof(struct threshold_bank), GFP_KERNEL);
 	if (!b) {
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 8944062..c30c807 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -147,7 +147,9 @@
 	/*
 	 * AMD specific bits
 	 */
-	struct amd_nb		*amd_nb;
+	struct amd_nb			*amd_nb;
+	/* Inverted mask of bits to clear in the perf_ctr ctrl registers */
+	u64				perf_ctr_virt_mask;
 
 	void				*kfree_on_online;
 };
@@ -417,9 +419,11 @@
 static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
 					  u64 enable_mask)
 {
+	u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);
+
 	if (hwc->extra_reg.reg)
 		wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
-	wrmsrl(hwc->config_base, hwc->config | enable_mask);
+	wrmsrl(hwc->config_base, (hwc->config | enable_mask) & ~disable_mask);
 }
 
 void x86_pmu_enable_all(int added);
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 0397b23..67250a5 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -1,4 +1,5 @@
 #include <linux/perf_event.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -357,7 +358,9 @@
 	struct amd_nb *nb;
 	int i, nb_id;
 
-	if (boot_cpu_data.x86_max_cores < 2)
+	cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY;
+
+	if (boot_cpu_data.x86_max_cores < 2 || boot_cpu_data.x86 == 0x15)
 		return;
 
 	nb_id = amd_get_nb_id(cpu);
@@ -587,9 +590,9 @@
 	.put_event_constraints	= amd_put_event_constraints,
 
 	.cpu_prepare		= amd_pmu_cpu_prepare,
-	.cpu_starting		= amd_pmu_cpu_starting,
 	.cpu_dead		= amd_pmu_cpu_dead,
 #endif
+	.cpu_starting		= amd_pmu_cpu_starting,
 };
 
 __init int amd_pmu_init(void)
@@ -621,3 +624,33 @@
 
 	return 0;
 }
+
+void amd_pmu_enable_virt(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	cpuc->perf_ctr_virt_mask = 0;
+
+	/* Reload all events */
+	x86_pmu_disable_all();
+	x86_pmu_enable_all(0);
+}
+EXPORT_SYMBOL_GPL(amd_pmu_enable_virt);
+
+void amd_pmu_disable_virt(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	/*
+	 * We only mask out the Host-only bit so that host-only counting works
+	 * when SVM is disabled. If someone sets up a guest-only counter when
+	 * SVM is disabled the Guest-only bits still gets set and the counter
+	 * will not count anything.
+	 */
+	cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY;
+
+	/* Reload all events */
+	x86_pmu_disable_all();
+	x86_pmu_enable_all(0);
+}
+EXPORT_SYMBOL_GPL(amd_pmu_disable_virt);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 73da6b6..d6bd49f 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -439,7 +439,6 @@
 	hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
 
 	cpuc->pebs_enabled |= 1ULL << hwc->idx;
-	WARN_ON_ONCE(cpuc->enabled);
 
 	if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
 		intel_pmu_lbr_enable(event);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index 3fab3de..47a7e63 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -72,8 +72,6 @@
 	if (!x86_pmu.lbr_nr)
 		return;
 
-	WARN_ON_ONCE(cpuc->enabled);
-
 	/*
 	 * Reset the LBR stack if we changed task context to
 	 * avoid data leaks.
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 3fe8239..1333d98 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1532,10 +1532,17 @@
 	pushq_cfi %rdx
 
 	/*
+	 * If %cs was not the kernel segment, then the NMI triggered in user
+	 * space, which means it is definitely not nested.
+	 */
+	cmpl $__KERNEL_CS, 16(%rsp)
+	jne first_nmi
+
+	/*
 	 * Check the special variable on the stack to see if NMIs are
 	 * executing.
 	 */
-	cmp $1, -8(%rsp)
+	cmpl $1, -8(%rsp)
 	je nested_nmi
 
 	/*
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index ac0417b..73465aa 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -360,7 +360,6 @@
 static enum ucode_state
 request_microcode_user(int cpu, const void __user *buf, size_t size)
 {
-	pr_info("AMD microcode update via /dev/cpu/microcode not supported\n");
 	return UCODE_ERROR;
 }
 
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 485204f..c08d1ff 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -214,6 +214,7 @@
 
 	task_user_gs(p) = get_user_gs(regs);
 
+	p->fpu_counter = 0;
 	p->thread.io_bitmap_ptr = NULL;
 	tsk = current;
 	err = -ENOMEM;
@@ -299,22 +300,11 @@
 				 *next = &next_p->thread;
 	int cpu = smp_processor_id();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
-	bool preload_fpu;
+	fpu_switch_t fpu;
 
 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
-	/*
-	 * If the task has used fpu the last 5 timeslices, just do a full
-	 * restore of the math state immediately to avoid the trap; the
-	 * chances of needing FPU soon are obviously high now
-	 */
-	preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
-
-	__unlazy_fpu(prev_p);
-
-	/* we're going to use this soon, after a few expensive things */
-	if (preload_fpu)
-		prefetch(next->fpu.state);
+	fpu = switch_fpu_prepare(prev_p, next_p, cpu);
 
 	/*
 	 * Reload esp0.
@@ -354,11 +344,6 @@
 		     task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT))
 		__switch_to_xtra(prev_p, next_p, tss);
 
-	/* If we're going to preload the fpu context, make sure clts
-	   is run while we're batching the cpu state updates. */
-	if (preload_fpu)
-		clts();
-
 	/*
 	 * Leave lazy mode, flushing any hypercalls made here.
 	 * This must be done before restoring TLS segments so
@@ -368,15 +353,14 @@
 	 */
 	arch_end_context_switch(next_p);
 
-	if (preload_fpu)
-		__math_state_restore();
-
 	/*
 	 * Restore %gs if needed (which is common)
 	 */
 	if (prev->gs | next->gs)
 		lazy_load_gs(next->gs);
 
+	switch_fpu_finish(next_p, fpu);
+
 	percpu_write(current_task, next_p);
 
 	return prev_p;
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 9b9fe4a..cfa5c90 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -286,6 +286,7 @@
 
 	set_tsk_thread_flag(p, TIF_FORK);
 
+	p->fpu_counter = 0;
 	p->thread.io_bitmap_ptr = NULL;
 
 	savesegment(gs, p->thread.gsindex);
@@ -386,18 +387,9 @@
 	int cpu = smp_processor_id();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
 	unsigned fsindex, gsindex;
-	bool preload_fpu;
+	fpu_switch_t fpu;
 
-	/*
-	 * If the task has used fpu the last 5 timeslices, just do a full
-	 * restore of the math state immediately to avoid the trap; the
-	 * chances of needing FPU soon are obviously high now
-	 */
-	preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
-
-	/* we're going to use this soon, after a few expensive things */
-	if (preload_fpu)
-		prefetch(next->fpu.state);
+	fpu = switch_fpu_prepare(prev_p, next_p, cpu);
 
 	/*
 	 * Reload esp0, LDT and the page table pointer:
@@ -427,13 +419,6 @@
 
 	load_TLS(next, cpu);
 
-	/* Must be after DS reload */
-	__unlazy_fpu(prev_p);
-
-	/* Make sure cpu is ready for new context */
-	if (preload_fpu)
-		clts();
-
 	/*
 	 * Leave lazy mode, flushing any hypercalls made here.
 	 * This must be done before restoring TLS segments so
@@ -474,6 +459,8 @@
 		wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
 	prev->gsindex = gsindex;
 
+	switch_fpu_finish(next_p, fpu);
+
 	/*
 	 * Switch the PDA and FPU contexts.
 	 */
@@ -492,13 +479,6 @@
 		     task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
 		__switch_to_xtra(prev_p, next_p, tss);
 
-	/*
-	 * Preload the FPU context, now that we've determined that the
-	 * task is likely to be using it. 
-	 */
-	if (preload_fpu)
-		__math_state_restore();
-
 	return prev_p;
 }
 
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 482ec3a..4bbe04d 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -571,41 +571,18 @@
 }
 
 /*
- * __math_state_restore assumes that cr0.TS is already clear and the
- * fpu state is all ready for use.  Used during context switch.
- */
-void __math_state_restore(void)
-{
-	struct thread_info *thread = current_thread_info();
-	struct task_struct *tsk = thread->task;
-
-	/*
-	 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
-	 */
-	if (unlikely(restore_fpu_checking(tsk))) {
-		stts();
-		force_sig(SIGSEGV, tsk);
-		return;
-	}
-
-	thread->status |= TS_USEDFPU;	/* So we fnsave on switch_to() */
-	tsk->fpu_counter++;
-}
-
-/*
  * 'math_state_restore()' saves the current math information in the
  * old math state array, and gets the new ones from the current task
  *
  * Careful.. There are problems with IBM-designed IRQ13 behaviour.
  * Don't touch unless you *really* know how it works.
  *
- * Must be called with kernel preemption disabled (in this case,
- * local interrupts are disabled at the call-site in entry.S).
+ * Must be called with kernel preemption disabled (eg with local
+ * local interrupts as in the case of do_device_not_available).
  */
-asmlinkage void math_state_restore(void)
+void math_state_restore(void)
 {
-	struct thread_info *thread = current_thread_info();
-	struct task_struct *tsk = thread->task;
+	struct task_struct *tsk = current;
 
 	if (!tsk_used_math(tsk)) {
 		local_irq_enable();
@@ -622,9 +599,17 @@
 		local_irq_disable();
 	}
 
-	clts();				/* Allow maths ops (or we recurse) */
+	__thread_fpu_begin(tsk);
+	/*
+	 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
+	 */
+	if (unlikely(restore_fpu_checking(tsk))) {
+		__thread_fpu_end(tsk);
+		force_sig(SIGSEGV, tsk);
+		return;
+	}
 
-	__math_state_restore();
+	tsk->fpu_counter++;
 }
 EXPORT_SYMBOL_GPL(math_state_restore);
 
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index a391134..7110911 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -47,7 +47,7 @@
 	if (!fx)
 		return;
 
-	BUG_ON(task_thread_info(tsk)->status & TS_USEDFPU);
+	BUG_ON(__thread_has_fpu(tsk));
 
 	xstate_bv = tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv;
 
@@ -168,7 +168,7 @@
 	if (!used_math())
 		return 0;
 
-	if (task_thread_info(tsk)->status & TS_USEDFPU) {
+	if (user_has_fpu()) {
 		if (use_xsave())
 			err = xsave_user(buf);
 		else
@@ -176,8 +176,7 @@
 
 		if (err)
 			return err;
-		task_thread_info(tsk)->status &= ~TS_USEDFPU;
-		stts();
+		user_fpu_end();
 	} else {
 		sanitize_i387_state(tsk);
 		if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave,
@@ -292,10 +291,7 @@
 			return err;
 	}
 
-	if (!(task_thread_info(current)->status & TS_USEDFPU)) {
-		clts();
-		task_thread_info(current)->status |= TS_USEDFPU;
-	}
+	user_fpu_begin();
 	if (use_xsave())
 		err = restore_user_xstate(buf);
 	else
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 5fa553b..e385214 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -29,6 +29,7 @@
 #include <linux/ftrace_event.h>
 #include <linux/slab.h>
 
+#include <asm/perf_event.h>
 #include <asm/tlbflush.h>
 #include <asm/desc.h>
 #include <asm/kvm_para.h>
@@ -575,6 +576,8 @@
 		wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT);
 
 	cpu_svm_disable();
+
+	amd_pmu_disable_virt();
 }
 
 static int svm_hardware_enable(void *garbage)
@@ -622,6 +625,8 @@
 
 	svm_init_erratum_383();
 
+	amd_pmu_enable_virt();
+
 	return 0;
 }
 
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index d29216c..3b4c8d8 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1457,7 +1457,7 @@
 #ifdef CONFIG_X86_64
 	wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
 #endif
-	if (current_thread_info()->status & TS_USEDFPU)
+	if (__thread_has_fpu(current))
 		clts();
 	load_gdt(&__get_cpu_var(host_gdt));
 }
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 492ade8..d99346e 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -374,7 +374,7 @@
 
 int __init pci_xen_hvm_init(void)
 {
-	if (!xen_feature(XENFEAT_hvm_pirqs))
+	if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs))
 		return 0;
 
 #ifdef CONFIG_ACPI
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 12eb07b..4172af8 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1141,7 +1141,9 @@
 
 	/* Prevent unwanted bits from being set in PTEs. */
 	__supported_pte_mask &= ~_PAGE_GLOBAL;
+#if 0
 	if (!xen_initial_domain())
+#endif
 		__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
 
 	__supported_pte_mask |= _PAGE_IOMAP;
@@ -1204,10 +1206,6 @@
 
 	pgd = (pgd_t *)xen_start_info->pt_base;
 
-	if (!xen_initial_domain())
-		__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
-
-	__supported_pte_mask |= _PAGE_IOMAP;
 	/* Don't do the full vcpu_info placement stuff until we have a
 	   possible map and a non-dummy shared_info. */
 	per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 58a0e46..95c1cf6 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -415,13 +415,13 @@
 static pteval_t xen_pte_val(pte_t pte)
 {
 	pteval_t pteval = pte.pte;
-
+#if 0
 	/* If this is a WC pte, convert back from Xen WC to Linux WC */
 	if ((pteval & (_PAGE_PAT | _PAGE_PCD | _PAGE_PWT)) == _PAGE_PAT) {
 		WARN_ON(!pat_enabled);
 		pteval = (pteval & ~_PAGE_PAT) | _PAGE_PWT;
 	}
-
+#endif
 	if (xen_initial_domain() && (pteval & _PAGE_IOMAP))
 		return pteval;
 
@@ -463,7 +463,7 @@
 static pte_t xen_make_pte(pteval_t pte)
 {
 	phys_addr_t addr = (pte & PTE_PFN_MASK);
-
+#if 0
 	/* If Linux is trying to set a WC pte, then map to the Xen WC.
 	 * If _PAGE_PAT is set, then it probably means it is really
 	 * _PAGE_PSE, so avoid fiddling with the PAT mapping and hope
@@ -476,7 +476,7 @@
 		if ((pte & (_PAGE_PCD | _PAGE_PWT)) == _PAGE_PWT)
 			pte = (pte & ~(_PAGE_PCD | _PAGE_PWT)) | _PAGE_PAT;
 	}
-
+#endif
 	/*
 	 * Unprivileged domains are allowed to do IOMAPpings for
 	 * PCI passthrough, but not map ISA space.  The ISA
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 041d4fe..501d4e0 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -409,6 +409,13 @@
 	play_dead_common();
 	HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
 	cpu_bringup();
+	/*
+	 * Balance out the preempt calls - as we are running in cpu_idle
+	 * loop which has been called at bootup from cpu_bringup_and_idle.
+	 * The cpucpu_bringup_and_idle called cpu_bringup which made a
+	 * preempt_disable() So this preempt_enable will balance it out.
+	 */
+	preempt_enable();
 }
 
 #else /* !CONFIG_HOTPLUG_CPU */
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index fa8f263..75642a3 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -1659,7 +1659,7 @@
 		ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
 		if (ioc) {
 			ioc_cgroup_changed(ioc);
-			put_io_context(ioc, NULL);
+			put_io_context(ioc);
 		}
 	}
 }
diff --git a/block/blk-core.c b/block/blk-core.c
index e6c05a9..3a78b00 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -642,7 +642,7 @@
 	if (rq->cmd_flags & REQ_ELVPRIV) {
 		elv_put_request(q, rq);
 		if (rq->elv.icq)
-			put_io_context(rq->elv.icq->ioc, q);
+			put_io_context(rq->elv.icq->ioc);
 	}
 
 	mempool_free(rq, q->rq.rq_pool);
@@ -872,13 +872,15 @@
 	spin_unlock_irq(q->queue_lock);
 
 	/* create icq if missing */
-	if (unlikely(et->icq_cache && !icq))
+	if ((rw_flags & REQ_ELVPRIV) && unlikely(et->icq_cache && !icq)) {
 		icq = ioc_create_icq(q, gfp_mask);
+		if (!icq)
+			goto fail_icq;
+	}
 
-	/* rqs are guaranteed to have icq on elv_set_request() if requested */
-	if (likely(!et->icq_cache || icq))
-		rq = blk_alloc_request(q, icq, rw_flags, gfp_mask);
+	rq = blk_alloc_request(q, icq, rw_flags, gfp_mask);
 
+fail_icq:
 	if (unlikely(!rq)) {
 		/*
 		 * Allocation failed presumably due to memory. Undo anything
@@ -1210,7 +1212,6 @@
 	req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
 	drive_stat_acct(req, 0);
-	elv_bio_merged(q, req, bio);
 	return true;
 }
 
@@ -1241,7 +1242,6 @@
 	req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
 	drive_stat_acct(req, 0);
-	elv_bio_merged(q, req, bio);
 	return true;
 }
 
@@ -1255,13 +1255,12 @@
  * on %current's plugged list.  Returns %true if merge was successful,
  * otherwise %false.
  *
- * This function is called without @q->queue_lock; however, elevator is
- * accessed iff there already are requests on the plugged list which in
- * turn guarantees validity of the elevator.
- *
- * Note that, on successful merge, elevator operation
- * elevator_bio_merged_fn() will be called without queue lock.  Elevator
- * must be ready for this.
+ * Plugging coalesces IOs from the same issuer for the same purpose without
+ * going through @q->queue_lock.  As such it's more of an issuing mechanism
+ * than scheduling, and the request, while may have elvpriv data, is not
+ * added on the elevator at this point.  In addition, we don't have
+ * reliable access to the elevator outside queue lock.  Only check basic
+ * merging parameters without querying the elevator.
  */
 static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
 			       unsigned int *request_count)
@@ -1280,10 +1279,10 @@
 
 		(*request_count)++;
 
-		if (rq->q != q)
+		if (rq->q != q || !blk_rq_merge_ok(rq, bio))
 			continue;
 
-		el_ret = elv_try_merge(rq, bio);
+		el_ret = blk_try_merge(rq, bio);
 		if (el_ret == ELEVATOR_BACK_MERGE) {
 			ret = bio_attempt_back_merge(q, rq, bio);
 			if (ret)
@@ -1345,12 +1344,14 @@
 	el_ret = elv_merge(q, &req, bio);
 	if (el_ret == ELEVATOR_BACK_MERGE) {
 		if (bio_attempt_back_merge(q, req, bio)) {
+			elv_bio_merged(q, req, bio);
 			if (!attempt_back_merge(q, req))
 				elv_merged_request(q, req, el_ret);
 			goto out_unlock;
 		}
 	} else if (el_ret == ELEVATOR_FRONT_MERGE) {
 		if (bio_attempt_front_merge(q, req, bio)) {
+			elv_bio_merged(q, req, bio);
 			if (!attempt_front_merge(q, req))
 				elv_merged_request(q, req, el_ret);
 			goto out_unlock;
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 27a06e0..8b782a6 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -29,21 +29,6 @@
 }
 EXPORT_SYMBOL(get_io_context);
 
-/*
- * Releasing ioc may nest into another put_io_context() leading to nested
- * fast path release.  As the ioc's can't be the same, this is okay but
- * makes lockdep whine.  Keep track of nesting and use it as subclass.
- */
-#ifdef CONFIG_LOCKDEP
-#define ioc_release_depth(q)		((q) ? (q)->ioc_release_depth : 0)
-#define ioc_release_depth_inc(q)	(q)->ioc_release_depth++
-#define ioc_release_depth_dec(q)	(q)->ioc_release_depth--
-#else
-#define ioc_release_depth(q)		0
-#define ioc_release_depth_inc(q)	do { } while (0)
-#define ioc_release_depth_dec(q)	do { } while (0)
-#endif
-
 static void icq_free_icq_rcu(struct rcu_head *head)
 {
 	struct io_cq *icq = container_of(head, struct io_cq, __rcu_head);
@@ -75,11 +60,8 @@
 	if (rcu_dereference_raw(ioc->icq_hint) == icq)
 		rcu_assign_pointer(ioc->icq_hint, NULL);
 
-	if (et->ops.elevator_exit_icq_fn) {
-		ioc_release_depth_inc(q);
+	if (et->ops.elevator_exit_icq_fn)
 		et->ops.elevator_exit_icq_fn(icq);
-		ioc_release_depth_dec(q);
-	}
 
 	/*
 	 * @icq->q might have gone away by the time RCU callback runs
@@ -98,8 +80,15 @@
 	struct io_context *ioc = container_of(work, struct io_context,
 					      release_work);
 	struct request_queue *last_q = NULL;
+	unsigned long flags;
 
-	spin_lock_irq(&ioc->lock);
+	/*
+	 * Exiting icq may call into put_io_context() through elevator
+	 * which will trigger lockdep warning.  The ioc's are guaranteed to
+	 * be different, use a different locking subclass here.  Use
+	 * irqsave variant as there's no spin_lock_irq_nested().
+	 */
+	spin_lock_irqsave_nested(&ioc->lock, flags, 1);
 
 	while (!hlist_empty(&ioc->icq_list)) {
 		struct io_cq *icq = hlist_entry(ioc->icq_list.first,
@@ -121,15 +110,15 @@
 			 */
 			if (last_q) {
 				spin_unlock(last_q->queue_lock);
-				spin_unlock_irq(&ioc->lock);
+				spin_unlock_irqrestore(&ioc->lock, flags);
 				blk_put_queue(last_q);
 			} else {
-				spin_unlock_irq(&ioc->lock);
+				spin_unlock_irqrestore(&ioc->lock, flags);
 			}
 
 			last_q = this_q;
-			spin_lock_irq(this_q->queue_lock);
-			spin_lock(&ioc->lock);
+			spin_lock_irqsave(this_q->queue_lock, flags);
+			spin_lock_nested(&ioc->lock, 1);
 			continue;
 		}
 		ioc_exit_icq(icq);
@@ -137,10 +126,10 @@
 
 	if (last_q) {
 		spin_unlock(last_q->queue_lock);
-		spin_unlock_irq(&ioc->lock);
+		spin_unlock_irqrestore(&ioc->lock, flags);
 		blk_put_queue(last_q);
 	} else {
-		spin_unlock_irq(&ioc->lock);
+		spin_unlock_irqrestore(&ioc->lock, flags);
 	}
 
 	kmem_cache_free(iocontext_cachep, ioc);
@@ -149,79 +138,29 @@
 /**
  * put_io_context - put a reference of io_context
  * @ioc: io_context to put
- * @locked_q: request_queue the caller is holding queue_lock of (hint)
  *
  * Decrement reference count of @ioc and release it if the count reaches
- * zero.  If the caller is holding queue_lock of a queue, it can indicate
- * that with @locked_q.  This is an optimization hint and the caller is
- * allowed to pass in %NULL even when it's holding a queue_lock.
+ * zero.
  */
-void put_io_context(struct io_context *ioc, struct request_queue *locked_q)
+void put_io_context(struct io_context *ioc)
 {
-	struct request_queue *last_q = locked_q;
 	unsigned long flags;
 
 	if (ioc == NULL)
 		return;
 
 	BUG_ON(atomic_long_read(&ioc->refcount) <= 0);
-	if (locked_q)
-		lockdep_assert_held(locked_q->queue_lock);
-
-	if (!atomic_long_dec_and_test(&ioc->refcount))
-		return;
 
 	/*
-	 * Destroy @ioc.  This is a bit messy because icq's are chained
-	 * from both ioc and queue, and ioc->lock nests inside queue_lock.
-	 * The inner ioc->lock should be held to walk our icq_list and then
-	 * for each icq the outer matching queue_lock should be grabbed.
-	 * ie. We need to do reverse-order double lock dancing.
-	 *
-	 * Another twist is that we are often called with one of the
-	 * matching queue_locks held as indicated by @locked_q, which
-	 * prevents performing double-lock dance for other queues.
-	 *
-	 * So, we do it in two stages.  The fast path uses the queue_lock
-	 * the caller is holding and, if other queues need to be accessed,
-	 * uses trylock to avoid introducing locking dependency.  This can
-	 * handle most cases, especially if @ioc was performing IO on only
-	 * single device.
-	 *
-	 * If trylock doesn't cut it, we defer to @ioc->release_work which
-	 * can do all the double-locking dancing.
+	 * Releasing ioc requires reverse order double locking and we may
+	 * already be holding a queue_lock.  Do it asynchronously from wq.
 	 */
-	spin_lock_irqsave_nested(&ioc->lock, flags,
-				 ioc_release_depth(locked_q));
-
-	while (!hlist_empty(&ioc->icq_list)) {
-		struct io_cq *icq = hlist_entry(ioc->icq_list.first,
-						struct io_cq, ioc_node);
-		struct request_queue *this_q = icq->q;
-
-		if (this_q != last_q) {
-			if (last_q && last_q != locked_q)
-				spin_unlock(last_q->queue_lock);
-			last_q = NULL;
-
-			if (!spin_trylock(this_q->queue_lock))
-				break;
-			last_q = this_q;
-			continue;
-		}
-		ioc_exit_icq(icq);
+	if (atomic_long_dec_and_test(&ioc->refcount)) {
+		spin_lock_irqsave(&ioc->lock, flags);
+		if (!hlist_empty(&ioc->icq_list))
+			schedule_work(&ioc->release_work);
+		spin_unlock_irqrestore(&ioc->lock, flags);
 	}
-
-	if (last_q && last_q != locked_q)
-		spin_unlock(last_q->queue_lock);
-
-	spin_unlock_irqrestore(&ioc->lock, flags);
-
-	/* if no icq is left, we're done; otherwise, kick release_work */
-	if (hlist_empty(&ioc->icq_list))
-		kmem_cache_free(iocontext_cachep, ioc);
-	else
-		schedule_work(&ioc->release_work);
 }
 EXPORT_SYMBOL(put_io_context);
 
@@ -236,7 +175,7 @@
 	task_unlock(task);
 
 	atomic_dec(&ioc->nr_tasks);
-	put_io_context(ioc, NULL);
+	put_io_context(ioc);
 }
 
 /**
diff --git a/block/blk-merge.c b/block/blk-merge.c
index cfcc37c..160035f 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -471,3 +471,40 @@
 {
 	return attempt_merge(q, rq, next);
 }
+
+bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
+{
+	if (!rq_mergeable(rq))
+		return false;
+
+	/* don't merge file system requests and discard requests */
+	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
+		return false;
+
+	/* don't merge discard requests and secure discard requests */
+	if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
+		return false;
+
+	/* different data direction or already started, don't merge */
+	if (bio_data_dir(bio) != rq_data_dir(rq))
+		return false;
+
+	/* must be same device and not a special request */
+	if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
+		return false;
+
+	/* only merge integrity protected bio into ditto rq */
+	if (bio_integrity(bio) != blk_integrity_rq(rq))
+		return false;
+
+	return true;
+}
+
+int blk_try_merge(struct request *rq, struct bio *bio)
+{
+	if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_sector)
+		return ELEVATOR_BACK_MERGE;
+	else if (blk_rq_pos(rq) - bio_sectors(bio) == bio->bi_sector)
+		return ELEVATOR_FRONT_MERGE;
+	return ELEVATOR_NO_MERGE;
+}
diff --git a/block/blk.h b/block/blk.h
index 7efd772..9c12f80 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -137,6 +137,8 @@
 				struct request *next);
 void blk_recalc_rq_segments(struct request *rq);
 void blk_rq_set_mixed_merge(struct request *rq);
+bool blk_rq_merge_ok(struct request *rq, struct bio *bio);
+int blk_try_merge(struct request *rq, struct bio *bio);
 
 void blk_queue_congestion_threshold(struct request_queue *q);
 
diff --git a/block/bsg.c b/block/bsg.c
index 4cf703f..ff64ae3 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -983,7 +983,8 @@
 
 	mutex_lock(&bsg_mutex);
 	idr_remove(&bsg_minor_idr, bcd->minor);
-	sysfs_remove_link(&q->kobj, "bsg");
+	if (q->kobj.sd)
+		sysfs_remove_link(&q->kobj, "bsg");
 	device_unregister(bcd->class_dev);
 	bcd->class_dev = NULL;
 	kref_put(&bcd->ref, bsg_kref_release_function);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index ee55019..d0ba505 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1699,18 +1699,11 @@
 
 	/*
 	 * Lookup the cfqq that this bio will be queued with and allow
-	 * merge only if rq is queued there.  This function can be called
-	 * from plug merge without queue_lock.  In such cases, ioc of @rq
-	 * and %current are guaranteed to be equal.  Avoid lookup which
-	 * requires queue_lock by using @rq's cic.
+	 * merge only if rq is queued there.
 	 */
-	if (current->io_context == RQ_CIC(rq)->icq.ioc) {
-		cic = RQ_CIC(rq);
-	} else {
-		cic = cfq_cic_lookup(cfqd, current->io_context);
-		if (!cic)
-			return false;
-	}
+	cic = cfq_cic_lookup(cfqd, current->io_context);
+	if (!cic)
+		return false;
 
 	cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio));
 	return cfqq == RQ_CFQQ(rq);
@@ -1794,7 +1787,7 @@
 		cfqd->active_queue = NULL;
 
 	if (cfqd->active_cic) {
-		put_io_context(cfqd->active_cic->icq.ioc, cfqd->queue);
+		put_io_context(cfqd->active_cic->icq.ioc);
 		cfqd->active_cic = NULL;
 	}
 }
@@ -3117,17 +3110,18 @@
  */
 static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
+	enum wl_type_t old_type = cfqq_type(cfqd->active_queue);
+
 	cfq_log_cfqq(cfqd, cfqq, "preempt");
+	cfq_slice_expired(cfqd, 1);
 
 	/*
 	 * workload type is changed, don't save slice, otherwise preempt
 	 * doesn't happen
 	 */
-	if (cfqq_type(cfqd->active_queue) != cfqq_type(cfqq))
+	if (old_type != cfqq_type(cfqq))
 		cfqq->cfqg->saved_workload_slice = 0;
 
-	cfq_slice_expired(cfqd, 1);
-
 	/*
 	 * Put the new queue at the front of the of the current list,
 	 * so we know that it will be selected next.
diff --git a/block/elevator.c b/block/elevator.c
index 91e18f8..f016855 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -70,39 +70,9 @@
 /*
  * can we safely merge with this request?
  */
-int elv_rq_merge_ok(struct request *rq, struct bio *bio)
+bool elv_rq_merge_ok(struct request *rq, struct bio *bio)
 {
-	if (!rq_mergeable(rq))
-		return 0;
-
-	/*
-	 * Don't merge file system requests and discard requests
-	 */
-	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
-		return 0;
-
-	/*
-	 * Don't merge discard requests and secure discard requests
-	 */
-	if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
-		return 0;
-
-	/*
-	 * different data direction or already started, don't merge
-	 */
-	if (bio_data_dir(bio) != rq_data_dir(rq))
-		return 0;
-
-	/*
-	 * must be same device and not a special request
-	 */
-	if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
-		return 0;
-
-	/*
-	 * only merge integrity protected bio into ditto rq
-	 */
-	if (bio_integrity(bio) != blk_integrity_rq(rq))
+	if (!blk_rq_merge_ok(rq, bio))
 		return 0;
 
 	if (!elv_iosched_allow_merge(rq, bio))
@@ -112,23 +82,6 @@
 }
 EXPORT_SYMBOL(elv_rq_merge_ok);
 
-int elv_try_merge(struct request *__rq, struct bio *bio)
-{
-	int ret = ELEVATOR_NO_MERGE;
-
-	/*
-	 * we can merge and sequence is ok, check if it's possible
-	 */
-	if (elv_rq_merge_ok(__rq, bio)) {
-		if (blk_rq_pos(__rq) + blk_rq_sectors(__rq) == bio->bi_sector)
-			ret = ELEVATOR_BACK_MERGE;
-		else if (blk_rq_pos(__rq) - bio_sectors(bio) == bio->bi_sector)
-			ret = ELEVATOR_FRONT_MERGE;
-	}
-
-	return ret;
-}
-
 static struct elevator_type *elevator_find(const char *name)
 {
 	struct elevator_type *e;
@@ -478,8 +431,8 @@
 	/*
 	 * First try one-hit cache.
 	 */
-	if (q->last_merge) {
-		ret = elv_try_merge(q->last_merge, bio);
+	if (q->last_merge && elv_rq_merge_ok(q->last_merge, bio)) {
+		ret = blk_try_merge(q->last_merge, bio);
 		if (ret != ELEVATOR_NO_MERGE) {
 			*req = q->last_merge;
 			return ret;
diff --git a/block/partitions/ldm.c b/block/partitions/ldm.c
index bd8ae78..e507cfb 100644
--- a/block/partitions/ldm.c
+++ b/block/partitions/ldm.c
@@ -2,7 +2,7 @@
  * ldm - Support for Windows Logical Disk Manager (Dynamic Disks)
  *
  * Copyright (C) 2001,2002 Richard Russon <ldm@flatcap.org>
- * Copyright (c) 2001-2007 Anton Altaparmakov
+ * Copyright (c) 2001-2012 Anton Altaparmakov
  * Copyright (C) 2001,2002 Jakob Kemi <jakob.kemi@telia.com>
  *
  * Documentation is available at http://www.linux-ntfs.org/doku.php?id=downloads 
@@ -1341,20 +1341,17 @@
 		ldm_error("REC value (%d) exceeds NUM value (%d)", rec, f->num);
 		return false;
 	}
-
 	if (f->map & (1 << rec)) {
 		ldm_error ("Duplicate VBLK, part %d.", rec);
 		f->map &= 0x7F;			/* Mark the group as broken */
 		return false;
 	}
-
 	f->map |= (1 << rec);
-
+	if (!rec)
+		memcpy(f->data, data, VBLK_SIZE_HEAD);
 	data += VBLK_SIZE_HEAD;
 	size -= VBLK_SIZE_HEAD;
-
-	memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size);
-
+	memcpy(f->data + VBLK_SIZE_HEAD + rec * size, data, size);
 	return true;
 }
 
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
index 88f160b..107f6f7 100644
--- a/crypto/sha512_generic.c
+++ b/crypto/sha512_generic.c
@@ -31,11 +31,6 @@
         return (x & y) | (z & (x | y));
 }
 
-static inline u64 RORu64(u64 x, u64 y)
-{
-        return (x >> y) | (x << (64 - y));
-}
-
 static const u64 sha512_K[80] = {
         0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
         0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
@@ -66,10 +61,10 @@
         0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
 };
 
-#define e0(x)       (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
-#define e1(x)       (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
-#define s0(x)       (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
-#define s1(x)       (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
+#define e0(x)       (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39))
+#define e1(x)       (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41))
+#define s0(x)       (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
+#define s1(x)       (ror64(x,19) ^ ror64(x,61) ^ (x >> 6))
 
 static inline void LOAD_OP(int I, u64 *W, const u8 *input)
 {
@@ -78,7 +73,7 @@
 
 static inline void BLEND_OP(int I, u64 *W)
 {
-	W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
+	W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]);
 }
 
 static void
@@ -89,46 +84,42 @@
 	int i;
 	u64 W[16];
 
-	/* load the input */
-        for (i = 0; i < 16; i++)
-                LOAD_OP(i, W, input);
-
 	/* load the state into our registers */
 	a=state[0];   b=state[1];   c=state[2];   d=state[3];
 	e=state[4];   f=state[5];   g=state[6];   h=state[7];
 
-#define SHA512_0_15(i, a, b, c, d, e, f, g, h)			\
-	t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i];	\
-	t2 = e0(a) + Maj(a, b, c);				\
-	d += t1;						\
-	h = t1 + t2
+	/* now iterate */
+	for (i=0; i<80; i+=8) {
+		if (!(i & 8)) {
+			int j;
 
-#define SHA512_16_79(i, a, b, c, d, e, f, g, h)			\
-	BLEND_OP(i, W);						\
-	t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16];	\
-	t2 = e0(a) + Maj(a, b, c);				\
-	d += t1;						\
-	h = t1 + t2
+			if (i < 16) {
+				/* load the input */
+				for (j = 0; j < 16; j++)
+					LOAD_OP(i + j, W, input);
+			} else {
+				for (j = 0; j < 16; j++) {
+					BLEND_OP(i + j, W);
+				}
+			}
+		}
 
-	for (i = 0; i < 16; i += 8) {
-		SHA512_0_15(i, a, b, c, d, e, f, g, h);
-		SHA512_0_15(i + 1, h, a, b, c, d, e, f, g);
-		SHA512_0_15(i + 2, g, h, a, b, c, d, e, f);
-		SHA512_0_15(i + 3, f, g, h, a, b, c, d, e);
-		SHA512_0_15(i + 4, e, f, g, h, a, b, c, d);
-		SHA512_0_15(i + 5, d, e, f, g, h, a, b, c);
-		SHA512_0_15(i + 6, c, d, e, f, g, h, a, b);
-		SHA512_0_15(i + 7, b, c, d, e, f, g, h, a);
-	}
-	for (i = 16; i < 80; i += 8) {
-		SHA512_16_79(i, a, b, c, d, e, f, g, h);
-		SHA512_16_79(i + 1, h, a, b, c, d, e, f, g);
-		SHA512_16_79(i + 2, g, h, a, b, c, d, e, f);
-		SHA512_16_79(i + 3, f, g, h, a, b, c, d, e);
-		SHA512_16_79(i + 4, e, f, g, h, a, b, c, d);
-		SHA512_16_79(i + 5, d, e, f, g, h, a, b, c);
-		SHA512_16_79(i + 6, c, d, e, f, g, h, a, b);
-		SHA512_16_79(i + 7, b, c, d, e, f, g, h, a);
+		t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i  ] + W[(i & 15)];
+		t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+		t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1];
+		t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+		t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2];
+		t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+		t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3];
+		t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+		t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4];
+		t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+		t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5];
+		t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+		t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6];
+		t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+		t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7];
+		t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
 	}
 
 	state[0] += a; state[1] += b; state[2] += c; state[3] += d;
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c
index a7d91a7..53d3770 100644
--- a/drivers/ata/pata_at91.c
+++ b/drivers/ata/pata_at91.c
@@ -207,11 +207,11 @@
 {
 	int ret = 0;
 	int use_iordy;
+	struct sam9_smc_config smc;
 	unsigned int t6z;         /* data tristate time in ns */
 	unsigned int cycle;       /* SMC Cycle width in MCK ticks */
 	unsigned int setup;       /* SMC Setup width in MCK ticks */
 	unsigned int pulse;       /* CFIOR and CFIOW pulse width in MCK ticks */
-	unsigned int cs_setup = 0;/* CS4 or CS5 setup width in MCK ticks */
 	unsigned int cs_pulse;    /* CS4 or CS5 pulse width in MCK ticks*/
 	unsigned int tdf_cycles;  /* SMC TDF MCK ticks */
 	unsigned long mck_hz;     /* MCK frequency in Hz */
@@ -244,26 +244,20 @@
 	}
 
 	dev_dbg(dev, "Use IORDY=%u, TDF Cycles=%u\n", use_iordy, tdf_cycles);
-	info->mode |= AT91_SMC_TDF_(tdf_cycles);
 
-	/* write SMC Setup Register */
-	at91_sys_write(AT91_SMC_SETUP(info->cs),
-			AT91_SMC_NWESETUP_(setup) |
-			AT91_SMC_NRDSETUP_(setup) |
-			AT91_SMC_NCS_WRSETUP_(cs_setup) |
-			AT91_SMC_NCS_RDSETUP_(cs_setup));
-	/* write SMC Pulse Register */
-	at91_sys_write(AT91_SMC_PULSE(info->cs),
-			AT91_SMC_NWEPULSE_(pulse) |
-			AT91_SMC_NRDPULSE_(pulse) |
-			AT91_SMC_NCS_WRPULSE_(cs_pulse) |
-			AT91_SMC_NCS_RDPULSE_(cs_pulse));
-	/* write SMC Cycle Register */
-	at91_sys_write(AT91_SMC_CYCLE(info->cs),
-			AT91_SMC_NWECYCLE_(cycle) |
-			AT91_SMC_NRDCYCLE_(cycle));
-	/* write SMC Mode Register*/
-	at91_sys_write(AT91_SMC_MODE(info->cs), info->mode);
+	/* SMC Setup Register */
+	smc.nwe_setup = smc.nrd_setup = setup;
+	smc.ncs_write_setup = smc.ncs_read_setup = 0;
+	/* SMC Pulse Register */
+	smc.nwe_pulse = smc.nrd_pulse = pulse;
+	smc.ncs_write_pulse = smc.ncs_read_pulse = cs_pulse;
+	/* SMC Cycle Register */
+	smc.write_cycle = smc.read_cycle = cycle;
+	/* SMC Mode Register*/
+	smc.tdf_cycles = tdf_cycles;
+	smc.mode = info->mode;
+
+	sam9_smc_configure(0, info->cs, &smc);
 }
 
 static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev)
@@ -288,20 +282,20 @@
 	struct at91_ide_info *info = dev->link->ap->host->private_data;
 	unsigned int consumed;
 	unsigned long flags;
-	unsigned int mode;
+	struct sam9_smc_config smc;
 
 	local_irq_save(flags);
-	mode = at91_sys_read(AT91_SMC_MODE(info->cs));
+	sam9_smc_read_mode(0, info->cs, &smc);
 
 	/* set 16bit mode before writing data */
-	at91_sys_write(AT91_SMC_MODE(info->cs),
-			(mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_16);
+	smc.mode = (smc.mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_16;
+	sam9_smc_write_mode(0, info->cs, &smc);
 
 	consumed = ata_sff_data_xfer(dev, buf, buflen, rw);
 
 	/* restore 8bit mode after data is written */
-	at91_sys_write(AT91_SMC_MODE(info->cs),
-			(mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_8);
+	smc.mode = (smc.mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_8;
+	sam9_smc_write_mode(0, info->cs, &smc);
 
 	local_irq_restore(flags);
 	return consumed;
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 5d1d076..e8cd652 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1206,9 +1206,9 @@
 	
  out_unmap_both:
 	pci_set_drvdata(dev, NULL);
-	pci_iounmap(dev, card->config_regs);
- out_unmap_config:
 	pci_iounmap(dev, card->buffers);
+ out_unmap_config:
+	pci_iounmap(dev, card->config_regs);
  out_release_regions:
 	pci_release_regions(dev);
  out:
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index db87e78..4dabf50 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -208,6 +208,25 @@
 }
 static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
 
+static void cpu_device_release(struct device *dev)
+{
+	/*
+	 * This is an empty function to prevent the driver core from spitting a
+	 * warning at us.  Yes, I know this is directly opposite of what the
+	 * documentation for the driver core and kobjects say, and the author
+	 * of this code has already been publically ridiculed for doing
+	 * something as foolish as this.  However, at this point in time, it is
+	 * the only way to handle the issue of statically allocated cpu
+	 * devices.  The different architectures will have their cpu device
+	 * code reworked to properly handle this in the near future, so this
+	 * function will then be changed to correctly free up the memory held
+	 * by the cpu device.
+	 *
+	 * Never copy this way of doing things, or you too will be made fun of
+	 * on the linux-kerenl list, you have been warned.
+	 */
+}
+
 /*
  * register_cpu - Setup a sysfs device for a CPU.
  * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -221,8 +240,10 @@
 	int error;
 
 	cpu->node_id = cpu_to_node(num);
+	memset(&cpu->dev, 0x00, sizeof(struct device));
 	cpu->dev.id = num;
 	cpu->dev.bus = &cpu_subsys;
+	cpu->dev.release = cpu_device_release;
 	error = device_register(&cpu->dev);
 	if (!error && cpu->hotpluggable)
 		register_cpu_control(cpu);
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index ed5de58..9e60dbe 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -572,19 +572,36 @@
 }
 
 static int add_memory_section(int nid, struct mem_section *section,
+			struct memory_block **mem_p,
 			unsigned long state, enum mem_add_context context)
 {
-	struct memory_block *mem;
+	struct memory_block *mem = NULL;
+	int scn_nr = __section_nr(section);
 	int ret = 0;
 
 	mutex_lock(&mem_sysfs_mutex);
 
-	mem = find_memory_block(section);
+	if (context == BOOT) {
+		/* same memory block ? */
+		if (mem_p && *mem_p)
+			if (scn_nr >= (*mem_p)->start_section_nr &&
+			    scn_nr <= (*mem_p)->end_section_nr) {
+				mem = *mem_p;
+				kobject_get(&mem->dev.kobj);
+			}
+	} else
+		mem = find_memory_block(section);
+
 	if (mem) {
 		mem->section_count++;
 		kobject_put(&mem->dev.kobj);
-	} else
+	} else {
 		ret = init_memory_block(&mem, section, state);
+		/* store memory_block pointer for next loop */
+		if (!ret && context == BOOT)
+			if (mem_p)
+				*mem_p = mem;
+	}
 
 	if (!ret) {
 		if (context == HOTPLUG &&
@@ -627,7 +644,7 @@
  */
 int register_new_memory(int nid, struct mem_section *section)
 {
-	return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG);
+	return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG);
 }
 
 int unregister_memory_section(struct mem_section *section)
@@ -647,6 +664,7 @@
 	int ret;
 	int err;
 	unsigned long block_sz;
+	struct memory_block *mem = NULL;
 
 	ret = subsys_system_register(&memory_subsys, NULL);
 	if (ret)
@@ -662,7 +680,10 @@
 	for (i = 0; i < NR_MEM_SECTIONS; i++) {
 		if (!present_section_nr(i))
 			continue;
-		err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE,
+		/* don't need to reuse memory_block if only one per block */
+		err = add_memory_section(0, __nr_to_section(i),
+				 (sections_per_block == 1) ? NULL : &mem,
+					 MEM_ONLINE,
 					 BOOT);
 		if (!ret)
 			ret = err;
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 44f427a..90aa2a1 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -456,7 +456,15 @@
 		if (!present_section_nr(section_nr))
 			continue;
 		mem_sect = __nr_to_section(section_nr);
+
+		/* same memblock ? */
+		if (mem_blk)
+			if ((section_nr >= mem_blk->start_section_nr) &&
+			    (section_nr <= mem_blk->end_section_nr))
+				continue;
+
 		mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
+
 		ret = register_mem_sect_under_node(mem_blk, nid);
 		if (!err)
 			err = ret;
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index 1ead661..d1daa5e 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -53,7 +53,7 @@
 	for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) {
 		val = regcache_get_val(map->reg_defaults_raw,
 				       i, map->cache_word_size);
-		if (!val)
+		if (regmap_volatile(map, i))
 			continue;
 		count++;
 	}
@@ -70,7 +70,7 @@
 	for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
 		val = regcache_get_val(map->reg_defaults_raw,
 				       i, map->cache_word_size);
-		if (!val)
+		if (regmap_volatile(map, i))
 			continue;
 		map->reg_defaults[j].reg = i;
 		map->reg_defaults[j].def = val;
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index febbc0a..ec31f7d 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -169,10 +169,8 @@
 	err = bcma_sprom_get(bus);
 	if (err == -ENOENT) {
 		pr_err("No SPROM available\n");
-	} else if (err) {
+	} else if (err)
 		pr_err("Failed to get SPROM: %d\n", err);
-		return -ENOENT;
-	}
 
 	/* Register found cores */
 	bcma_register_cores(bus);
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index cad9948..3a2f672 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -399,15 +399,18 @@
 		core->bus = bus;
 
 		err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
-		if (err == -ENODEV) {
-			core_num++;
-			continue;
-		} else if (err == -ENXIO)
-			continue;
-		else if (err == -ESPIPE)
-			break;
-		else if (err < 0)
+		if (err < 0) {
+			kfree(core);
+			if (err == -ENODEV) {
+				core_num++;
+				continue;
+			} else if (err == -ENXIO) {
+				continue;
+			} else if (err == -ESPIPE) {
+				break;
+			}
 			return err;
+		}
 
 		core->core_index = core_num++;
 		bus->nr_cores++;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 510fb10..9baf11e 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4368,8 +4368,14 @@
 out_put_disk:
 	while (dr--) {
 		del_timer_sync(&motor_off_timer[dr]);
-		if (disks[dr]->queue)
+		if (disks[dr]->queue) {
 			blk_cleanup_queue(disks[dr]->queue);
+			/*
+			 * put_disk() is not paired with add_disk() and
+			 * will put queue reference one extra time. fix it.
+			 */
+			disks[dr]->queue = NULL;
+		}
 		put_disk(disks[dr]);
 	}
 	return err;
@@ -4579,6 +4585,15 @@
 			platform_device_unregister(&floppy_device[drive]);
 		}
 		blk_cleanup_queue(disks[drive]->queue);
+
+		/*
+		 * These disks have not called add_disk().  Don't put down
+		 * queue reference in put_disk().
+		 */
+		if (!(allowed_drive_mask & (1 << drive)) ||
+		    fdc_state[FDC(drive)].version == FDC_NONE)
+			disks[drive]->queue = NULL;
+
 		put_disk(disks[drive]);
 	}
 
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index f002577..cd50435 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -356,14 +356,14 @@
 	return __splice_from_pipe(pipe, sd, lo_splice_actor);
 }
 
-static int
+static ssize_t
 do_lo_receive(struct loop_device *lo,
 	      struct bio_vec *bvec, int bsize, loff_t pos)
 {
 	struct lo_read_data cookie;
 	struct splice_desc sd;
 	struct file *file;
-	long retval;
+	ssize_t retval;
 
 	cookie.lo = lo;
 	cookie.page = bvec->bv_page;
@@ -379,26 +379,28 @@
 	file = lo->lo_backing_file;
 	retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
 
-	if (retval < 0)
-		return retval;
-	if (retval != bvec->bv_len)
-		return -EIO;
-	return 0;
+	return retval;
 }
 
 static int
 lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
 {
 	struct bio_vec *bvec;
-	int i, ret = 0;
+	ssize_t s;
+	int i;
 
 	bio_for_each_segment(bvec, bio, i) {
-		ret = do_lo_receive(lo, bvec, bsize, pos);
-		if (ret < 0)
+		s = do_lo_receive(lo, bvec, bsize, pos);
+		if (s < 0)
+			return s;
+
+		if (s != bvec->bv_len) {
+			zero_fill_bio(bio);
 			break;
+		}
 		pos += bvec->bv_len;
 	}
-	return ret;
+	return 0;
 }
 
 static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index b74eab7..8eb81c9 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -2068,8 +2068,6 @@
  *	     when the read completes.
  * @data     Callback data passed to the callback function
  *	     when the read completes.
- * @barrier  If non-zero, this command must be completed before
- *	     issuing any other commands.
  * @dir      Direction (read or write)
  *
  * return value
@@ -2077,7 +2075,7 @@
  */
 static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
 			      int nsect, int nents, int tag, void *callback,
-			      void *data, int barrier, int dir)
+			      void *data, int dir)
 {
 	struct host_to_dev_fis	*fis;
 	struct mtip_port *port = dd->port;
@@ -2108,8 +2106,6 @@
 	*((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF);
 	*((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF);
 	fis->device	 = 1 << 6;
-	if (barrier)
-		fis->device |= FUA_BIT;
 	fis->features    = nsect & 0xFF;
 	fis->features_ex = (nsect >> 8) & 0xFF;
 	fis->sect_count  = ((tag << 3) | (tag >> 5));
@@ -3087,7 +3083,6 @@
 				tag,
 				bio_endio,
 				bio,
-				bio->bi_rw & REQ_FUA,
 				bio_data_dir(bio));
 	} else
 		bio_io_error(bio);
@@ -3187,6 +3182,10 @@
 	blk_queue_max_segments(dd->queue, MTIP_MAX_SG);
 	blk_queue_physical_block_size(dd->queue, 4096);
 	blk_queue_io_min(dd->queue, 4096);
+	/*
+	 * write back cache is not supported in the device. FUA depends on
+	 * write back cache support, hence setting flush support to zero.
+	 */
 	blk_queue_flush(dd->queue, 0);
 
 	/* Set the capacity of the device in 512 byte sectors. */
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index 723d7c4..e0554a8 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -104,9 +104,6 @@
 /* BAR number used to access the HBA registers. */
 #define MTIP_ABAR		5
 
-/* Forced Unit Access Bit */
-#define FUA_BIT			0x80
-
 #ifdef DEBUG
  #define dbg_printk(format, arg...)	\
 	printk(pr_fmt(format), ##arg);
@@ -415,8 +412,6 @@
 
 	atomic_t resumeflag; /* Atomic variable to track suspend/resume */
 
-	atomic_t eh_active; /* Flag for error handling tracking */
-
 	struct task_struct *mtip_svc_handler; /* task_struct of svc thd */
 };
 
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index c1dc4d8..1f3c1a7 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -41,6 +41,8 @@
 #include <linux/types.h>
 #include <linux/version.h>
 
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
 #define NVME_Q_DEPTH 1024
 #define SQ_SIZE(depth)		(depth * sizeof(struct nvme_command))
 #define CQ_SIZE(depth)		(depth * sizeof(struct nvme_completion))
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f00f596..789c9b5 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -102,6 +102,7 @@
 
 	/* Broadcom BCM20702A0 */
 	{ USB_DEVICE(0x0a5c, 0x21e3) },
+	{ USB_DEVICE(0x0a5c, 0x21f3) },
 	{ USB_DEVICE(0x413c, 0x8197) },
 
 	{ }	/* Terminating entry */
@@ -726,9 +727,6 @@
 		usb_fill_bulk_urb(urb, data->udev, pipe,
 				skb->data, skb->len, btusb_tx_complete, skb);
 
-		if (skb->priority >= HCI_PRIO_MAX - 1)
-			urb->transfer_flags  = URB_ISO_ASAP;
-
 		hdev->stat.acl_tx++;
 		break;
 
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 55eaf47..d620b44 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -286,8 +286,6 @@
 
 /* used to tell the module to turn on full debugging messages */
 static bool debug;
-/* used to keep tray locked at all times */
-static int keeplocked;
 /* default compatibility mode */
 static bool autoclose=1;
 static bool autoeject;
@@ -1204,7 +1202,7 @@
 		cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
 		cdrom_dvd_rw_close_write(cdi);
 
-		if ((cdo->capability & CDC_LOCK) && !keeplocked) {
+		if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) {
 			cdinfo(CD_CLOSE, "Unlocking door!\n");
 			cdo->lock_door(cdi, 0);
 		}
@@ -1371,7 +1369,7 @@
 	curslot = info->hdr.curslot;
 	kfree(info);
 
-	if (cdi->use_count > 1 || keeplocked) {
+	if (cdi->use_count > 1 || cdi->keeplocked) {
 		if (slot == CDSL_CURRENT) {
 	    		return curslot;
 		} else {
@@ -2119,11 +2117,6 @@
 	if (!nr)
 		return -ENOMEM;
 
-	if (!access_ok(VERIFY_WRITE, ubuf, nframes * CD_FRAMESIZE_RAW)) {
-		ret = -EFAULT;
-		goto out;
-	}
-
 	cgc.data_direction = CGC_DATA_READ;
 	while (nframes > 0) {
 		if (nr > nframes)
@@ -2132,7 +2125,7 @@
 		ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW);
 		if (ret)
 			break;
-		if (__copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
+		if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
 			ret = -EFAULT;
 			break;
 		}
@@ -2140,7 +2133,6 @@
 		nframes -= nr;
 		lba += nr;
 	}
-out:
 	kfree(cgc.buffer);
 	return ret;
 }
@@ -2295,7 +2287,7 @@
 
 	if (!CDROM_CAN(CDC_OPEN_TRAY))
 		return -ENOSYS;
-	if (cdi->use_count != 1 || keeplocked)
+	if (cdi->use_count != 1 || cdi->keeplocked)
 		return -EBUSY;
 	if (CDROM_CAN(CDC_LOCK)) {
 		int ret = cdi->ops->lock_door(cdi, 0);
@@ -2322,7 +2314,7 @@
 
 	if (!CDROM_CAN(CDC_OPEN_TRAY))
 		return -ENOSYS;
-	if (keeplocked)
+	if (cdi->keeplocked)
 		return -EBUSY;
 
 	cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
@@ -2453,7 +2445,7 @@
 	if (!CDROM_CAN(CDC_LOCK))
 		return -EDRIVE_CANT_DO_THIS;
 
-	keeplocked = arg ? 1 : 0;
+	cdi->keeplocked = arg ? 1 : 0;
 
 	/*
 	 * Don't unlock the door on multiple opens by default, but allow
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 7dbc4a8..78a666d 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -1,7 +1,7 @@
 
 config CPU_IDLE
 	bool "CPU idle PM support"
-	default ACPI
+	default y if ACPI || PPC_PSERIES
 	help
 	  CPU idle is a generic framework for supporting software-controlled
 	  idle processor power management.  It includes modular cross-platform
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 597235a..0d40cf6 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -714,6 +714,7 @@
 {
 	struct mv_req_hash_ctx *ctx = ahash_request_ctx(req);
 
+	ahash_request_set_crypt(req, NULL, req->result, 0);
 	mv_update_hash_req_ctx(ctx, 1, 0);
 	return mv_handle_req(&req->base);
 }
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c
index aa08497..73f55e200 100644
--- a/drivers/edac/i3200_edac.c
+++ b/drivers/edac/i3200_edac.c
@@ -15,6 +15,8 @@
 #include <linux/io.h>
 #include "edac_core.h"
 
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
 #define I3200_REVISION        "1.1"
 
 #define EDAC_MOD_STR        "i3200_edac"
@@ -101,19 +103,6 @@
 
 static int nr_channels;
 
-#ifndef readq
-static inline __u64 readq(const volatile void __iomem *addr)
-{
-	const volatile u32 __iomem *p = addr;
-	u32 low, high;
-
-	low = readl(p);
-	high = readl(p + 1);
-
-	return low + ((u64)high << 32);
-}
-#endif
-
 static int how_many_channels(struct pci_dev *pdev)
 {
 	unsigned char capid0_8b; /* 8th byte of CAPID0 */
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index ddd70db..637fcc3 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -315,7 +315,8 @@
 	if (err)
 		return err;
 
-	if (__get_user(c32.auth, &client->auth)
+	if (__get_user(c32.idx, &client->idx)
+	    || __get_user(c32.auth, &client->auth)
 	    || __get_user(c32.pid, &client->pid)
 	    || __get_user(c32.uid, &client->uid)
 	    || __get_user(c32.magic, &client->magic)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index d620b07..618bd4d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -28,6 +28,7 @@
 #include "drmP.h"
 #include "drm_crtc_helper.h"
 
+#include <drm/exynos_drm.h>
 #include "exynos_drm_drv.h"
 #include "exynos_drm_encoder.h"
 
@@ -44,8 +45,9 @@
 /* convert exynos_video_timings to drm_display_mode */
 static inline void
 convert_to_display_mode(struct drm_display_mode *mode,
-			struct fb_videomode *timing)
+			struct exynos_drm_panel_info *panel)
 {
+	struct fb_videomode *timing = &panel->timing;
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
 	mode->clock = timing->pixclock / 1000;
@@ -60,6 +62,8 @@
 	mode->vsync_start = mode->vdisplay + timing->upper_margin;
 	mode->vsync_end = mode->vsync_start + timing->vsync_len;
 	mode->vtotal = mode->vsync_end + timing->lower_margin;
+	mode->width_mm = panel->width_mm;
+	mode->height_mm = panel->height_mm;
 
 	if (timing->vmode & FB_VMODE_INTERLACED)
 		mode->flags |= DRM_MODE_FLAG_INTERLACE;
@@ -148,16 +152,18 @@
 		connector->display_info.raw_edid = edid;
 	} else {
 		struct drm_display_mode *mode = drm_mode_create(connector->dev);
-		struct fb_videomode *timing;
+		struct exynos_drm_panel_info *panel;
 
-		if (display_ops->get_timing)
-			timing = display_ops->get_timing(manager->dev);
+		if (display_ops->get_panel)
+			panel = display_ops->get_panel(manager->dev);
 		else {
 			drm_mode_destroy(connector->dev, mode);
 			return 0;
 		}
 
-		convert_to_display_mode(mode, timing);
+		convert_to_display_mode(mode, panel);
+		connector->display_info.width_mm = mode->width_mm;
+		connector->display_info.height_mm = mode->height_mm;
 
 		mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 		drm_mode_set_name(mode);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 661a035..d08a558 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -193,6 +193,9 @@
 			return err;
 		}
 
+		/* setup possible_clones. */
+		exynos_drm_encoder_setup(drm_dev);
+
 		/*
 		 * if any specific driver such as fimd or hdmi driver called
 		 * exynos_drm_subdrv_register() later than drm_load(),
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index e3861ac..de81883 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -307,9 +307,6 @@
 		 */
 		event->pipe = exynos_crtc->pipe;
 
-		list_add_tail(&event->base.link,
-				&dev_priv->pageflip_event_list);
-
 		ret = drm_vblank_get(dev, exynos_crtc->pipe);
 		if (ret) {
 			DRM_DEBUG("failed to acquire vblank counter\n");
@@ -318,6 +315,9 @@
 			goto out;
 		}
 
+		list_add_tail(&event->base.link,
+				&dev_priv->pageflip_event_list);
+
 		crtc->fb = fb;
 		ret = exynos_drm_crtc_update(crtc);
 		if (ret) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 35889ca..58820eb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -33,6 +33,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
+#include "exynos_drm_encoder.h"
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
@@ -99,6 +100,9 @@
 	if (ret)
 		goto err_vblank;
 
+	/* setup possible_clones. */
+	exynos_drm_encoder_setup(dev);
+
 	/*
 	 * create and configure fb helper and also exynos specific
 	 * fbdev object.
@@ -141,16 +145,21 @@
 }
 
 static void exynos_drm_preclose(struct drm_device *dev,
-					struct drm_file *file_priv)
+					struct drm_file *file)
 {
-	struct exynos_drm_private *dev_priv = dev->dev_private;
+	DRM_DEBUG_DRIVER("%s\n", __FILE__);
 
-	/*
-	 * drm framework frees all events at release time,
-	 * so private event list should be cleared.
-	 */
-	if (!list_empty(&dev_priv->pageflip_event_list))
-		INIT_LIST_HEAD(&dev_priv->pageflip_event_list);
+}
+
+static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
+{
+	DRM_DEBUG_DRIVER("%s\n", __FILE__);
+
+	if (!file->driver_priv)
+		return;
+
+	kfree(file->driver_priv);
+	file->driver_priv = NULL;
 }
 
 static void exynos_drm_lastclose(struct drm_device *dev)
@@ -195,6 +204,7 @@
 	.unload			= exynos_drm_unload,
 	.preclose		= exynos_drm_preclose,
 	.lastclose		= exynos_drm_lastclose,
+	.postclose		= exynos_drm_postclose,
 	.get_vblank_counter	= drm_vblank_count,
 	.enable_vblank		= exynos_drm_crtc_enable_vblank,
 	.disable_vblank		= exynos_drm_crtc_disable_vblank,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index e685e1e..13540de 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -136,7 +136,7 @@
  * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
  * @is_connected: check for that display is connected or not.
  * @get_edid: get edid modes from display driver.
- * @get_timing: get timing object from display driver.
+ * @get_panel: get panel object from display driver.
  * @check_timing: check if timing is valid or not.
  * @power_on: display device on or off.
  */
@@ -145,7 +145,7 @@
 	bool (*is_connected)(struct device *dev);
 	int (*get_edid)(struct device *dev, struct drm_connector *connector,
 				u8 *edid, int len);
-	void *(*get_timing)(struct device *dev);
+	void *(*get_panel)(struct device *dev);
 	int (*check_timing)(struct device *dev, void *timing);
 	int (*power_on)(struct device *dev, int mode);
 };
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 86b93dd..ef4754f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -195,6 +195,40 @@
 	.destroy = exynos_drm_encoder_destroy,
 };
 
+static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder)
+{
+	struct drm_encoder *clone;
+	struct drm_device *dev = encoder->dev;
+	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
+	struct exynos_drm_display_ops *display_ops =
+				exynos_encoder->manager->display_ops;
+	unsigned int clone_mask = 0;
+	int cnt = 0;
+
+	list_for_each_entry(clone, &dev->mode_config.encoder_list, head) {
+		switch (display_ops->type) {
+		case EXYNOS_DISPLAY_TYPE_LCD:
+		case EXYNOS_DISPLAY_TYPE_HDMI:
+			clone_mask |= (1 << (cnt++));
+			break;
+		default:
+			continue;
+		}
+	}
+
+	return clone_mask;
+}
+
+void exynos_drm_encoder_setup(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+
+	DRM_DEBUG_KMS("%s\n", __FILE__);
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+		encoder->possible_clones = exynos_drm_encoder_clones(encoder);
+}
+
 struct drm_encoder *
 exynos_drm_encoder_create(struct drm_device *dev,
 			   struct exynos_drm_manager *manager,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
index 97b087a..eb7d231 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
@@ -30,6 +30,7 @@
 
 struct exynos_drm_manager;
 
+void exynos_drm_encoder_setup(struct drm_device *dev);
 struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev,
 					       struct exynos_drm_manager *mgr,
 					       unsigned int possible_crtcs);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index d7ae29d..3508700 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -195,66 +195,6 @@
 	return ret;
 }
 
-static bool
-exynos_drm_fbdev_is_samefb(struct drm_framebuffer *fb,
-			    struct drm_fb_helper_surface_size *sizes)
-{
-	if (fb->width != sizes->surface_width)
-		return false;
-	if (fb->height != sizes->surface_height)
-		return false;
-	if (fb->bits_per_pixel != sizes->surface_bpp)
-		return false;
-	if (fb->depth != sizes->surface_depth)
-		return false;
-
-	return true;
-}
-
-static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper,
-				      struct drm_fb_helper_surface_size *sizes)
-{
-	struct drm_device *dev = helper->dev;
-	struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper);
-	struct exynos_drm_gem_obj *exynos_gem_obj;
-	struct drm_framebuffer *fb = helper->fb;
-	struct drm_mode_fb_cmd2 mode_cmd = { 0 };
-	unsigned long size;
-
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
-	if (exynos_drm_fbdev_is_samefb(fb, sizes))
-		return 0;
-
-	mode_cmd.width = sizes->surface_width;
-	mode_cmd.height = sizes->surface_height;
-	mode_cmd.pitches[0] = sizes->surface_width * (sizes->surface_bpp >> 3);
-	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
-							  sizes->surface_depth);
-
-	if (exynos_fbdev->exynos_gem_obj)
-		exynos_drm_gem_destroy(exynos_fbdev->exynos_gem_obj);
-
-	if (fb->funcs->destroy)
-		fb->funcs->destroy(fb);
-
-	size = mode_cmd.pitches[0] * mode_cmd.height;
-	exynos_gem_obj = exynos_drm_gem_create(dev, size);
-	if (IS_ERR(exynos_gem_obj))
-		return PTR_ERR(exynos_gem_obj);
-
-	exynos_fbdev->exynos_gem_obj = exynos_gem_obj;
-
-	helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd,
-			&exynos_gem_obj->base);
-	if (IS_ERR_OR_NULL(helper->fb)) {
-		DRM_ERROR("failed to create drm framebuffer.\n");
-		return PTR_ERR(helper->fb);
-	}
-
-	return exynos_drm_fbdev_update(helper, helper->fb);
-}
-
 static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
 				   struct drm_fb_helper_surface_size *sizes)
 {
@@ -262,6 +202,10 @@
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
+	/*
+	 * with !helper->fb, it means that this funcion is called first time
+	 * and after that, the helper->fb would be used as clone mode.
+	 */
 	if (!helper->fb) {
 		ret = exynos_drm_fbdev_create(helper, sizes);
 		if (ret < 0) {
@@ -274,12 +218,6 @@
 		 * because register_framebuffer() should be called.
 		 */
 		ret = 1;
-	} else {
-		ret = exynos_drm_fbdev_recreate(helper, sizes);
-		if (ret < 0) {
-			DRM_ERROR("failed to reconfigure fbdev\n");
-			return ret;
-		}
 	}
 
 	return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index b6a737d..360adf2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -89,7 +89,7 @@
 	bool				suspended;
 	struct mutex			lock;
 
-	struct fb_videomode		*timing;
+	struct exynos_drm_panel_info *panel;
 };
 
 static bool fimd_display_is_connected(struct device *dev)
@@ -101,13 +101,13 @@
 	return true;
 }
 
-static void *fimd_get_timing(struct device *dev)
+static void *fimd_get_panel(struct device *dev)
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	return ctx->timing;
+	return ctx->panel;
 }
 
 static int fimd_check_timing(struct device *dev, void *timing)
@@ -131,7 +131,7 @@
 static struct exynos_drm_display_ops fimd_display_ops = {
 	.type = EXYNOS_DISPLAY_TYPE_LCD,
 	.is_connected = fimd_display_is_connected,
-	.get_timing = fimd_get_timing,
+	.get_panel = fimd_get_panel,
 	.check_timing = fimd_check_timing,
 	.power_on = fimd_display_power_on,
 };
@@ -193,7 +193,8 @@
 static void fimd_commit(struct device *dev)
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
-	struct fb_videomode *timing = ctx->timing;
+	struct exynos_drm_panel_info *panel = ctx->panel;
+	struct fb_videomode *timing = &panel->timing;
 	u32 val;
 
 	if (ctx->suspended)
@@ -604,7 +605,12 @@
 	}
 
 	if (is_checked) {
-		drm_vblank_put(drm_dev, crtc);
+		/*
+		 * call drm_vblank_put only in case that drm_vblank_get was
+		 * called.
+		 */
+		if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0)
+			drm_vblank_put(drm_dev, crtc);
 
 		/*
 		 * don't off vblank if vblank_disable_allowed is 1,
@@ -781,7 +787,7 @@
 	struct fimd_context *ctx;
 	struct exynos_drm_subdrv *subdrv;
 	struct exynos_drm_fimd_pdata *pdata;
-	struct fb_videomode *timing;
+	struct exynos_drm_panel_info *panel;
 	struct resource *res;
 	int win;
 	int ret = -EINVAL;
@@ -794,9 +800,9 @@
 		return -EINVAL;
 	}
 
-	timing = &pdata->timing;
-	if (!timing) {
-		dev_err(dev, "timing is null.\n");
+	panel = &pdata->panel;
+	if (!panel) {
+		dev_err(dev, "panel is null.\n");
 		return -EINVAL;
 	}
 
@@ -858,16 +864,16 @@
 		goto err_req_irq;
 	}
 
-	ctx->clkdiv = fimd_calc_clkdiv(ctx, timing);
+	ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing);
 	ctx->vidcon0 = pdata->vidcon0;
 	ctx->vidcon1 = pdata->vidcon1;
 	ctx->default_win = pdata->default_win;
-	ctx->timing = timing;
+	ctx->panel = panel;
 
-	timing->pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv;
+	panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv;
 
 	DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n",
-			timing->pixclock, ctx->clkdiv);
+			panel->timing.pixclock, ctx->clkdiv);
 
 	subdrv = &ctx->subdrv;
 
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index ac24cff..93846e8 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -712,7 +712,12 @@
 	}
 
 	if (is_checked)
-		drm_vblank_put(drm_dev, crtc);
+		/*
+		 * call drm_vblank_put only in case that drm_vblank_get was
+		 * called.
+		 */
+		if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0)
+			drm_vblank_put(drm_dev, crtc);
 
 	spin_unlock_irqrestore(&drm_dev->event_lock, flags);
 }
@@ -779,15 +784,15 @@
 	mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
 		MXR_STATUS_BURST_MASK);
 
-	/* setting default layer priority: layer1 > video > layer0
+	/* setting default layer priority: layer1 > layer0 > video
 	 * because typical usage scenario would be
+	 * layer1 - OSD
 	 * layer0 - framebuffer
 	 * video - video overlay
-	 * layer1 - OSD
 	 */
-	val  = MXR_LAYER_CFG_GRP0_VAL(1);
-	val |= MXR_LAYER_CFG_VP_VAL(2);
-	val |= MXR_LAYER_CFG_GRP1_VAL(3);
+	val = MXR_LAYER_CFG_GRP1_VAL(3);
+	val |= MXR_LAYER_CFG_GRP0_VAL(2);
+	val |= MXR_LAYER_CFG_VP_VAL(1);
 	mixer_reg_write(res, MXR_LAYER_CFG, val);
 
 	/* setting background color */
@@ -1044,7 +1049,7 @@
 					platform_get_drvdata(pdev);
 	struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx;
 
-	dev_info(dev, "remove sucessful\n");
+	dev_info(dev, "remove successful\n");
 
 	mixer_resource_poweroff(ctx);
 	mixer_resources_cleanup(ctx);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c3afb78..03c53fc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3028,6 +3028,20 @@
 #define  DISP_TILE_SURFACE_SWIZZLING	(1<<13)
 #define  DISP_FBC_WM_DIS		(1<<15)
 
+/* GEN7 chicken */
+#define GEN7_COMMON_SLICE_CHICKEN1		0x7010
+# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC	((1<<10) | (1<<26))
+
+#define GEN7_L3CNTLREG1				0xB01C
+#define  GEN7_WA_FOR_GEN7_L3_CONTROL			0x3C4FFF8C
+
+#define GEN7_L3_CHICKEN_MODE_REGISTER		0xB030
+#define  GEN7_WA_L3_CHICKEN_MODE				0x20000000
+
+/* WaCatErrorRejectionIssue */
+#define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG		0x9030
+#define  GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB	(1<<11)
+
 /* PCH */
 
 /* south display engine interrupt */
@@ -3618,6 +3632,7 @@
 #define    GT_FIFO_NUM_RESERVED_ENTRIES		20
 
 #define GEN6_UCGCTL2				0x9404
+# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE		(1 << 13)
 # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE		(1 << 12)
 # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE		(1 << 11)
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b3b51c4..f851db7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1872,7 +1872,7 @@
 	if (enable_fbc < 0) {
 		DRM_DEBUG_KMS("fbc set to per-chip default\n");
 		enable_fbc = 1;
-		if (INTEL_INFO(dev)->gen <= 5)
+		if (INTEL_INFO(dev)->gen <= 6)
 			enable_fbc = 0;
 	}
 	if (!enable_fbc) {
@@ -4680,8 +4680,17 @@
 
 	crtc = intel_get_crtc_for_plane(dev, plane);
 	clock = crtc->mode.clock;
+	if (!clock) {
+		*sprite_wm = 0;
+		return false;
+	}
 
 	line_time_us = (sprite_width * 1000) / clock;
+	if (!line_time_us) {
+		*sprite_wm = 0;
+		return false;
+	}
+
 	line_count = (latency_ns / line_time_us + 1000) / 1000;
 	line_size = sprite_width * pixel_size;
 
@@ -5307,6 +5316,7 @@
 		}
 	}
 
+	pipeconf &= ~PIPECONF_INTERLACE_MASK;
 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
 		pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
 		/* the chip adds 2 halflines automatically */
@@ -5317,7 +5327,7 @@
 		adjusted_mode->crtc_vsync_end -= 1;
 		adjusted_mode->crtc_vsync_start -= 1;
 	} else
-		pipeconf &= ~PIPECONF_INTERLACE_MASK; /* progressive */
+		pipeconf |= PIPECONF_PROGRESSIVE;
 
 	I915_WRITE(HTOTAL(pipe),
 		   (adjusted_mode->crtc_hdisplay - 1) |
@@ -5902,6 +5912,7 @@
 		}
 	}
 
+	pipeconf &= ~PIPECONF_INTERLACE_MASK;
 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
 		pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
 		/* the chip adds 2 halflines automatically */
@@ -5912,7 +5923,7 @@
 		adjusted_mode->crtc_vsync_end -= 1;
 		adjusted_mode->crtc_vsync_start -= 1;
 	} else
-		pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */
+		pipeconf |= PIPECONF_PROGRESSIVE;
 
 	I915_WRITE(HTOTAL(pipe),
 		   (adjusted_mode->crtc_hdisplay - 1) |
@@ -6173,7 +6184,7 @@
 	int i;
 
 	/* The clocks have to be on to load the palette. */
-	if (!crtc->enabled)
+	if (!crtc->enabled || !intel_crtc->active)
 		return;
 
 	/* use legacy palette for Ironlake */
@@ -6559,7 +6570,7 @@
 	mode_cmd.height = mode->vdisplay;
 	mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
 								bpp);
-	mode_cmd.pixel_format = 0;
+	mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
 
 	return intel_framebuffer_create(dev, &mode_cmd, obj);
 }
@@ -8182,8 +8193,8 @@
 	I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
 	if (intel_enable_rc6(dev_priv->dev))
-		rc6_mask = GEN6_RC_CTL_RC6p_ENABLE |
-			GEN6_RC_CTL_RC6_ENABLE;
+		rc6_mask = GEN6_RC_CTL_RC6_ENABLE |
+			((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0);
 
 	I915_WRITE(GEN6_RC_CONTROL,
 		   rc6_mask |
@@ -8461,12 +8472,32 @@
 	I915_WRITE(WM2_LP_ILK, 0);
 	I915_WRITE(WM1_LP_ILK, 0);
 
+	/* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
+	 * This implements the WaDisableRCZUnitClockGating workaround.
+	 */
+	I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
+
 	I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
 
 	I915_WRITE(IVB_CHICKEN3,
 		   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
 		   CHICKEN3_DGMG_DONE_FIX_DISABLE);
 
+	/* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
+	I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
+		   GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
+
+	/* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
+	I915_WRITE(GEN7_L3CNTLREG1,
+			GEN7_WA_FOR_GEN7_L3_CONTROL);
+	I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
+			GEN7_WA_L3_CHICKEN_MODE);
+
+	/* This is required by WaCatErrorRejectionIssue */
+	I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
+			I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
+			GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
+
 	for_each_pipe(pipe) {
 		I915_WRITE(DSPCNTR(pipe),
 			   I915_READ(DSPCNTR(pipe)) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index db3b461..94f860c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -208,17 +208,8 @@
  */
 
 static int
-intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock, int check_bpp)
+intel_dp_link_required(int pixel_clock, int bpp)
 {
-	struct drm_crtc *crtc = intel_dp->base.base.crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	int bpp = 24;
-
-	if (check_bpp)
-		bpp = check_bpp;
-	else if (intel_crtc)
-		bpp = intel_crtc->bpp;
-
 	return (pixel_clock * bpp + 9) / 10;
 }
 
@@ -245,12 +236,11 @@
 			return MODE_PANEL;
 	}
 
-	mode_rate = intel_dp_link_required(intel_dp, mode->clock, 0);
+	mode_rate = intel_dp_link_required(mode->clock, 24);
 	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
 
 	if (mode_rate > max_rate) {
-			mode_rate = intel_dp_link_required(intel_dp,
-							   mode->clock, 18);
+			mode_rate = intel_dp_link_required(mode->clock, 18);
 			if (mode_rate > max_rate)
 				return MODE_CLOCK_HIGH;
 			else
@@ -683,7 +673,7 @@
 	int lane_count, clock;
 	int max_lane_count = intel_dp_max_lane_count(intel_dp);
 	int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
-	int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 0;
+	int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
 	if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
@@ -701,7 +691,7 @@
 		for (clock = 0; clock <= max_clock; clock++) {
 			int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
 
-			if (intel_dp_link_required(intel_dp, mode->clock, bpp)
+			if (intel_dp_link_required(mode->clock, bpp)
 					<= link_avail) {
 				intel_dp->link_bw = bws[clock];
 				intel_dp->lane_count = lane_count;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 798f6e1..aa84832 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -694,6 +694,14 @@
 	},
 	{
 		.callback = intel_no_lvds_dmi_callback,
+                .ident = "AOpen i45GMx-I",
+                .matches = {
+                        DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+                        DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
+                },
+        },
+	{
+		.callback = intel_no_lvds_dmi_callback,
 		.ident = "Aopen i945GTt-VFA",
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 1ab842c..5361915 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -301,7 +301,7 @@
 
 	I915_WRITE_CTL(ring,
 			((ring->size - PAGE_SIZE) & RING_NR_PAGES)
-			| RING_REPORT_64K | RING_VALID);
+			| RING_VALID);
 
 	/* If the head is still not zero, the ring is dead */
 	if ((I915_READ_CTL(ring) & RING_VALID) == 0 ||
@@ -1132,18 +1132,6 @@
 	struct drm_device *dev = ring->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long end;
-	u32 head;
-
-	/* If the reported head position has wrapped or hasn't advanced,
-	 * fallback to the slow and accurate path.
-	 */
-	head = intel_read_status_page(ring, 4);
-	if (head > ring->head) {
-		ring->head = head;
-		ring->space = ring_space(ring);
-		if (ring->space >= n)
-			return 0;
-	}
 
 	trace_i915_ring_wait_begin(ring);
 	if (drm_core_check_feature(dev, DRIVER_GEM))
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index ae09fe8..f58254a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3191,6 +3191,7 @@
 	if (r) {
 		DRM_ERROR("radeon: failed testing IB (%d).\n", r);
 		rdev->accel_working = false;
+		return r;
 	}
 
 	r = r600_audio_init(rdev);
@@ -3222,6 +3223,7 @@
 	r = evergreen_startup(rdev);
 	if (r) {
 		DRM_ERROR("evergreen startup failed on resume\n");
+		rdev->accel_working = false;
 		return r;
 	}
 
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index db09065..2509c50 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1547,6 +1547,7 @@
 	r = cayman_startup(rdev);
 	if (r) {
 		DRM_ERROR("cayman startup failed on resume\n");
+		rdev->accel_working = false;
 		return r;
 	}
 	return r;
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index bfd36ab..333cde9 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -789,9 +789,7 @@
 			WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM);
 			break;
 		default:
-			msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
-			WREG32(RADEON_MSI_REARM_EN, msi_rearm);
-			WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+			WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN);
 			break;
 		}
 	}
@@ -3930,6 +3928,8 @@
 
 int r100_resume(struct radeon_device *rdev)
 {
+	int r;
+
 	/* Make sur GART are not working */
 	if (rdev->flags & RADEON_IS_PCI)
 		r100_pci_gart_disable(rdev);
@@ -3949,7 +3949,11 @@
 	radeon_surface_init(rdev);
 
 	rdev->accel_working = true;
-	return r100_startup(rdev);
+	r = r100_startup(rdev);
+	if (r) {
+		rdev->accel_working = false;
+	}
+	return r;
 }
 
 int r100_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 3fc0d29..6829638 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -1431,6 +1431,8 @@
 
 int r300_resume(struct radeon_device *rdev)
 {
+	int r;
+
 	/* Make sur GART are not working */
 	if (rdev->flags & RADEON_IS_PCIE)
 		rv370_pcie_gart_disable(rdev);
@@ -1452,7 +1454,11 @@
 	radeon_surface_init(rdev);
 
 	rdev->accel_working = true;
-	return r300_startup(rdev);
+	r = r300_startup(rdev);
+	if (r) {
+		rdev->accel_working = false;
+	}
+	return r;
 }
 
 int r300_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 666e28f..b143230 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -291,6 +291,8 @@
 
 int r420_resume(struct radeon_device *rdev)
 {
+	int r;
+
 	/* Make sur GART are not working */
 	if (rdev->flags & RADEON_IS_PCIE)
 		rv370_pcie_gart_disable(rdev);
@@ -316,7 +318,11 @@
 	radeon_surface_init(rdev);
 
 	rdev->accel_working = true;
-	return r420_startup(rdev);
+	r = r420_startup(rdev);
+	if (r) {
+		rdev->accel_working = false;
+	}
+	return r;
 }
 
 int r420_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 4ae1615..25084e8 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -218,6 +218,8 @@
 
 int r520_resume(struct radeon_device *rdev)
 {
+	int r;
+
 	/* Make sur GART are not working */
 	if (rdev->flags & RADEON_IS_PCIE)
 		rv370_pcie_gart_disable(rdev);
@@ -237,7 +239,11 @@
 	radeon_surface_init(rdev);
 
 	rdev->accel_working = true;
-	return r520_startup(rdev);
+	r = r520_startup(rdev);
+	if (r) {
+		rdev->accel_working = false;
+	}
+	return r;
 }
 
 int r520_init(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 4f08e5e..fbcd848 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2529,6 +2529,7 @@
 	r = r600_startup(rdev);
 	if (r) {
 		DRM_ERROR("r600 startup failed on resume\n");
+		rdev->accel_working = false;
 		return r;
 	}
 
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 38ce5d0..387fcc9 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -1304,6 +1304,7 @@
 	h0 = G_038004_TEX_HEIGHT(word1) + 1;
 	d0 = G_038004_TEX_DEPTH(word1);
 	nfaces = 1;
+	array = 0;
 	switch (G_038000_DIM(word0)) {
 	case V_038000_SQ_TEX_DIM_1D:
 	case V_038000_SQ_TEX_DIM_2D:
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 5082d17..1f53ae7 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2931,6 +2931,20 @@
 			bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5;
 		}
 	}
+	if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) &&
+	    (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) {
+		if (connected) {
+			DRM_DEBUG_KMS("DFP6 connected\n");
+			bios_0_scratch |= ATOM_S0_DFP6;
+			bios_3_scratch |= ATOM_S3_DFP6_ACTIVE;
+			bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6;
+		} else {
+			DRM_DEBUG_KMS("DFP6 disconnected\n");
+			bios_0_scratch &= ~ATOM_S0_DFP6;
+			bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE;
+			bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6;
+		}
+	}
 
 	if (rdev->family >= CHIP_R600) {
 		WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch);
@@ -2951,6 +2965,9 @@
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	uint32_t bios_3_scratch;
 
+	if (ASIC_IS_DCE4(rdev))
+		return;
+
 	if (rdev->family >= CHIP_R600)
 		bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH);
 	else
@@ -3003,6 +3020,9 @@
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	uint32_t bios_2_scratch;
 
+	if (ASIC_IS_DCE4(rdev))
+		return;
+
 	if (rdev->family >= CHIP_R600)
 		bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
 	else
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index e7cb3ab..8b3d8ed 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1117,13 +1117,23 @@
 	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
 		struct drm_display_mode *mode;
 
-		if (!radeon_dig_connector->edp_on)
-			atombios_set_edp_panel_power(connector,
-						     ATOM_TRANSMITTER_ACTION_POWER_ON);
-		ret = radeon_ddc_get_modes(radeon_connector);
-		if (!radeon_dig_connector->edp_on)
-			atombios_set_edp_panel_power(connector,
-						     ATOM_TRANSMITTER_ACTION_POWER_OFF);
+		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+			if (!radeon_dig_connector->edp_on)
+				atombios_set_edp_panel_power(connector,
+							     ATOM_TRANSMITTER_ACTION_POWER_ON);
+			ret = radeon_ddc_get_modes(radeon_connector);
+			if (!radeon_dig_connector->edp_on)
+				atombios_set_edp_panel_power(connector,
+							     ATOM_TRANSMITTER_ACTION_POWER_OFF);
+		} else {
+			/* need to setup ddc on the bridge */
+			if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+			    ENCODER_OBJECT_ID_NONE) {
+				if (encoder)
+					radeon_atom_ext_encoder_setup_ddc(encoder);
+			}
+			ret = radeon_ddc_get_modes(radeon_connector);
+		}
 
 		if (ret > 0) {
 			if (encoder) {
@@ -1134,7 +1144,6 @@
 			return ret;
 		}
 
-		encoder = radeon_best_single_encoder(connector);
 		if (!encoder)
 			return 0;
 
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 435a3d9..e64bec4 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -453,6 +453,10 @@
 	int r;
 
 	radeon_mutex_lock(&rdev->cs_mutex);
+	if (!rdev->accel_working) {
+		radeon_mutex_unlock(&rdev->cs_mutex);
+		return -EBUSY;
+	}
 	/* initialize parser */
 	memset(&parser, 0, sizeof(struct radeon_cs_parser));
 	parser.filp = filp;
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 64ea3dd..4bd36a3 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -364,8 +364,10 @@
 	int not_processed = 0;
 
 	read_lock_irqsave(&rdev->fence_lock, irq_flags);
-	if (!rdev->fence_drv[ring].initialized)
+	if (!rdev->fence_drv[ring].initialized) {
+		read_unlock_irqrestore(&rdev->fence_lock, irq_flags);
 		return 0;
+	}
 
 	if (!list_empty(&rdev->fence_drv[ring].emitted)) {
 		struct list_head *ptr;
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 010dad8..c58a036 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -597,13 +597,13 @@
 	if (bo_va == NULL)
 		return 0;
 
-	list_del(&bo_va->bo_list);
 	mutex_lock(&vm->mutex);
 	radeon_mutex_lock(&rdev->cs_mutex);
 	radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
 	radeon_mutex_unlock(&rdev->cs_mutex);
 	list_del(&bo_va->vm_list);
 	mutex_unlock(&vm->mutex);
+	list_del(&bo_va->bo_list);
 
 	kfree(bo_va);
 	return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 30a4c50..92c9ea4 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -500,8 +500,11 @@
 int radeon_debugfs_ring_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list,
-					ARRAY_SIZE(radeon_debugfs_ring_info_list));
+	if (rdev->family >= CHIP_CAYMAN)
+		return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list,
+						ARRAY_SIZE(radeon_debugfs_ring_info_list));
+	else
+		return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1);
 #else
 	return 0;
 #endif
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index b0ce84a..866a05b 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -442,6 +442,8 @@
 
 int rs400_resume(struct radeon_device *rdev)
 {
+	int r;
+
 	/* Make sur GART are not working */
 	rs400_gart_disable(rdev);
 	/* Resume clock before doing reset */
@@ -462,7 +464,11 @@
 	radeon_surface_init(rdev);
 
 	rdev->accel_working = true;
-	return rs400_startup(rdev);
+	r = rs400_startup(rdev);
+	if (r) {
+		rdev->accel_working = false;
+	}
+	return r;
 }
 
 int rs400_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index ec46eb4..4fc7006 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -684,9 +684,7 @@
 			WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM);
 			break;
 		default:
-			msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
-			WREG32(RADEON_MSI_REARM_EN, msi_rearm);
-			WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+			WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN);
 			break;
 		}
 	}
@@ -878,6 +876,8 @@
 
 int rs600_resume(struct radeon_device *rdev)
 {
+	int r;
+
 	/* Make sur GART are not working */
 	rs600_gart_disable(rdev);
 	/* Resume clock before doing reset */
@@ -896,7 +896,11 @@
 	radeon_surface_init(rdev);
 
 	rdev->accel_working = true;
-	return rs600_startup(rdev);
+	r = rs600_startup(rdev);
+	if (r) {
+		rdev->accel_working = false;
+	}
+	return r;
 }
 
 int rs600_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 4f24a0f..f68dff2 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -659,6 +659,8 @@
 
 int rs690_resume(struct radeon_device *rdev)
 {
+	int r;
+
 	/* Make sur GART are not working */
 	rs400_gart_disable(rdev);
 	/* Resume clock before doing reset */
@@ -677,7 +679,11 @@
 	radeon_surface_init(rdev);
 
 	rdev->accel_working = true;
-	return rs690_startup(rdev);
+	r = rs690_startup(rdev);
+	if (r) {
+		rdev->accel_working = false;
+	}
+	return r;
 }
 
 int rs690_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 880637f..959bf44 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -424,6 +424,8 @@
 
 int rv515_resume(struct radeon_device *rdev)
 {
+	int r;
+
 	/* Make sur GART are not working */
 	if (rdev->flags & RADEON_IS_PCIE)
 		rv370_pcie_gart_disable(rdev);
@@ -443,7 +445,11 @@
 	radeon_surface_init(rdev);
 
 	rdev->accel_working = true;
-	return rv515_startup(rdev);
+	r =  rv515_startup(rdev);
+	if (r) {
+		rdev->accel_working = false;
+	}
+	return r;
 }
 
 int rv515_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index a1668b6..c049c0c 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1139,6 +1139,7 @@
 	r = rv770_startup(rdev);
 	if (r) {
 		DRM_ERROR("r600 startup failed on resume\n");
+		rdev->accel_working = false;
 		return r;
 	}
 
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index eedca3c..dd87ae9 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -271,7 +271,7 @@
 			continue;
 		err = device_create_file(&client->dev, &ads1015_in[k].dev_attr);
 		if (err)
-			goto exit_free;
+			goto exit_remove;
 	}
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -285,7 +285,6 @@
 exit_remove:
 	for (k = 0; k < ADS1015_CHANNELS; ++k)
 		device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
-exit_free:
 	kfree(data);
 exit:
 	return err;
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index eedf574..6aa5a9f 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -172,12 +172,22 @@
 static inline void f75375_write16(struct i2c_client *client, u8 reg,
 		u16 value)
 {
-	int err = i2c_smbus_write_byte_data(client, reg, (value << 8));
+	int err = i2c_smbus_write_byte_data(client, reg, (value >> 8));
 	if (err)
 		return;
 	i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
 }
 
+static void f75375_write_pwm(struct i2c_client *client, int nr)
+{
+	struct f75375_data *data = i2c_get_clientdata(client);
+	if (data->kind == f75387)
+		f75375_write16(client, F75375_REG_FAN_EXP(nr), data->pwm[nr]);
+	else
+		f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
+			      data->pwm[nr]);
+}
+
 static struct f75375_data *f75375_update_device(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
@@ -200,9 +210,6 @@
 				f75375_read16(client, F75375_REG_FAN_MIN(nr));
 			data->fan_target[nr] =
 				f75375_read16(client, F75375_REG_FAN_EXP(nr));
-			data->pwm[nr] =	f75375_read8(client,
-				F75375_REG_FAN_PWM_DUTY(nr));
-
 		}
 		for (nr = 0; nr < 4; nr++) {
 			data->in_max[nr] =
@@ -218,6 +225,8 @@
 	if (time_after(jiffies, data->last_updated + 2 * HZ)
 		|| !data->valid) {
 		for (nr = 0; nr < 2; nr++) {
+			data->pwm[nr] =	f75375_read8(client,
+				F75375_REG_FAN_PWM_DUTY(nr));
 			/* assign MSB, therefore shift it by 8 bits */
 			data->temp11[nr] =
 				f75375_read8(client, F75375_REG_TEMP(nr)) << 8;
@@ -255,6 +264,36 @@
 	return 1500000 / rpm;
 }
 
+static bool duty_mode_enabled(u8 pwm_enable)
+{
+	switch (pwm_enable) {
+	case 0: /* Manual, duty mode (full speed) */
+	case 1: /* Manual, duty mode */
+	case 4: /* Auto, duty mode */
+		return true;
+	case 2: /* Auto, speed mode */
+	case 3: /* Manual, speed mode */
+		return false;
+	default:
+		BUG();
+	}
+}
+
+static bool auto_mode_enabled(u8 pwm_enable)
+{
+	switch (pwm_enable) {
+	case 0: /* Manual, duty mode (full speed) */
+	case 1: /* Manual, duty mode */
+	case 3: /* Manual, speed mode */
+		return false;
+	case 2: /* Auto, speed mode */
+	case 4: /* Auto, duty mode */
+		return true;
+	default:
+		BUG();
+	}
+}
+
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
@@ -288,6 +327,11 @@
 	if (err < 0)
 		return err;
 
+	if (auto_mode_enabled(data->pwm_enable[nr]))
+		return -EINVAL;
+	if (data->kind == f75387 && duty_mode_enabled(data->pwm_enable[nr]))
+		return -EINVAL;
+
 	mutex_lock(&data->update_lock);
 	data->fan_target[nr] = rpm_to_reg(val);
 	f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]);
@@ -308,9 +352,13 @@
 	if (err < 0)
 		return err;
 
+	if (auto_mode_enabled(data->pwm_enable[nr]) ||
+	    !duty_mode_enabled(data->pwm_enable[nr]))
+		return -EINVAL;
+
 	mutex_lock(&data->update_lock);
 	data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
-	f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]);
+	f75375_write_pwm(client, nr);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -328,11 +376,15 @@
 	struct f75375_data *data = i2c_get_clientdata(client);
 	u8 fanmode;
 
-	if (val < 0 || val > 3)
+	if (val < 0 || val > 4)
 		return -EINVAL;
 
 	fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
 	if (data->kind == f75387) {
+		/* For now, deny dangerous toggling of duty mode */
+		if (duty_mode_enabled(data->pwm_enable[nr]) !=
+				duty_mode_enabled(val))
+			return -EOPNOTSUPP;
 		/* clear each fanX_mode bit before setting them properly */
 		fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr));
 		fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr));
@@ -341,19 +393,19 @@
 			fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
 			fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
 			data->pwm[nr] = 255;
-			f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
-					data->pwm[nr]);
 			break;
 		case 1: /* PWM */
 			fanmode  |= (1 << F75387_FAN_MANU_MODE(nr));
 			fanmode  |= (1 << F75387_FAN_DUTY_MODE(nr));
 			break;
-		case 2: /* AUTOMATIC*/
-			fanmode  |=  (1 << F75387_FAN_DUTY_MODE(nr));
+		case 2: /* Automatic, speed mode */
 			break;
 		case 3: /* fan speed */
 			fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
 			break;
+		case 4: /* Automatic, pwm */
+			fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
+			break;
 		}
 	} else {
 		/* clear each fanX_mode bit before setting them properly */
@@ -362,22 +414,24 @@
 		case 0: /* full speed */
 			fanmode  |= (3 << FAN_CTRL_MODE(nr));
 			data->pwm[nr] = 255;
-			f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
-					data->pwm[nr]);
 			break;
 		case 1: /* PWM */
 			fanmode  |= (3 << FAN_CTRL_MODE(nr));
 			break;
 		case 2: /* AUTOMATIC*/
-			fanmode  |= (2 << FAN_CTRL_MODE(nr));
+			fanmode  |= (1 << FAN_CTRL_MODE(nr));
 			break;
 		case 3: /* fan speed */
 			break;
+		case 4: /* Automatic pwm */
+			return -EINVAL;
 		}
 	}
 
 	f75375_write8(client, F75375_REG_FAN_TIMER, fanmode);
 	data->pwm_enable[nr] = val;
+	if (val == 0)
+		f75375_write_pwm(client, nr);
 	return 0;
 }
 
@@ -723,19 +777,22 @@
 			if (data->kind == f75387) {
 				bool manu, duty;
 
-				if (!(conf & (1 << F75387_FAN_CTRL_LINEAR(nr))))
+				if (!(mode & (1 << F75387_FAN_CTRL_LINEAR(nr))))
 					data->pwm_mode[nr] = 1;
 
 				manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1);
 				duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1);
-				if (manu && duty)
-					/* speed */
+				if (!manu && duty)
+					/* auto, pwm */
+					data->pwm_enable[nr] = 4;
+				else if (manu && !duty)
+					/* manual, speed */
 					data->pwm_enable[nr] = 3;
-				else if (!manu && duty)
-					/* automatic */
+				else if (!manu && !duty)
+					/* automatic, speed */
 					data->pwm_enable[nr] = 2;
 				else
-					/* manual */
+					/* manual, pwm */
 					data->pwm_enable[nr] = 1;
 			} else {
 				if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr))))
@@ -760,9 +817,11 @@
 	set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]);
 	set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]);
 	for (nr = 0; nr < 2; nr++) {
+		if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) ||
+		    !duty_mode_enabled(f75375s_pdata->pwm_enable[nr]))
+			continue;
 		data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255);
-		f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
-			data->pwm[nr]);
+		f75375_write_pwm(client, nr);
 	}
 
 }
@@ -789,7 +848,7 @@
 	if (err)
 		goto exit_free;
 
-	if (data->kind == f75375) {
+	if (data->kind != f75373) {
 		err = sysfs_chmod_file(&client->dev.kobj,
 			&sensor_dev_attr_pwm1_mode.dev_attr.attr,
 			S_IRUGO | S_IWUSR);
diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c
index e10a092..a6760ba 100644
--- a/drivers/hwmon/max6639.c
+++ b/drivers/hwmon/max6639.c
@@ -72,8 +72,8 @@
 
 static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 };
 
-#define FAN_FROM_REG(val, div, rpm_range)	((val) == 0 ? -1 : \
-	(val) == 255 ? 0 : (rpm_ranges[rpm_range] * 30) / ((div + 1) * (val)))
+#define FAN_FROM_REG(val, rpm_range)	((val) == 0 || (val) == 255 ? \
+				0 : (rpm_ranges[rpm_range] * 30) / (val))
 #define TEMP_LIMIT_TO_REG(val)	SENSORS_LIMIT((val) / 1000, 0, 255)
 
 /*
@@ -333,7 +333,7 @@
 		return PTR_ERR(data);
 
 	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index],
-		       data->ppr, data->rpm_range));
+		       data->rpm_range));
 }
 
 static ssize_t show_alarm(struct device *dev,
@@ -429,9 +429,9 @@
 	struct max6639_data *data = i2c_get_clientdata(client);
 	struct max6639_platform_data *max6639_info =
 		client->dev.platform_data;
-	int i = 0;
+	int i;
 	int rpm_range = 1; /* default: 4000 RPM */
-	int err = 0;
+	int err;
 
 	/* Reset chip to default values, see below for GCONFIG setup */
 	err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG,
@@ -446,11 +446,6 @@
 	else
 		data->ppr = 2;
 	data->ppr -= 1;
-	err = i2c_smbus_write_byte_data(client,
-			MAX6639_REG_FAN_PPR(i),
-			data->ppr << 5);
-	if (err)
-		goto exit;
 
 	if (max6639_info)
 		rpm_range = rpm_range_to_reg(max6639_info->rpm_range);
@@ -458,6 +453,13 @@
 
 	for (i = 0; i < 2; i++) {
 
+		/* Set Fan pulse per revolution */
+		err = i2c_smbus_write_byte_data(client,
+				MAX6639_REG_FAN_PPR(i),
+				data->ppr << 6);
+		if (err)
+			goto exit;
+
 		/* Fans config PWM, RPM */
 		err = i2c_smbus_write_byte_data(client,
 			MAX6639_REG_FAN_CONFIG1(i),
diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c
index beaf5a8..9b97a5b 100644
--- a/drivers/hwmon/pmbus/max34440.c
+++ b/drivers/hwmon/pmbus/max34440.c
@@ -82,7 +82,7 @@
 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
 		ret = pmbus_write_word_data(client, page,
 					    MAX34440_MFR_TEMPERATURE_PEAK,
-					    0xffff);
+					    0x8000);
 		break;
 	default:
 		ret = -ENODATA;
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 4d383e7..5276d19 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -2354,11 +2354,6 @@
 	for (i = 0; i < data->pwm_num; i++)
 		data->pwm_enable_orig[i] = data->pwm_enable[i];
 
-	/* Read pwm data to save original values */
-	w83627ehf_update_pwm_common(dev, data);
-	for (i = 0; i < data->pwm_num; i++)
-		data->pwm_enable_orig[i] = data->pwm_enable[i];
-
 	/* Register sysfs hooks */
 	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) {
 		err = device_create_file(dev, &sda_sf3_arrays[i].dev_attr);
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 7e78f7c..3d471d5 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -72,6 +72,7 @@
 
 #define MXS_I2C_QUEUESTAT	(0x70)
 #define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY        0x00002000
+#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK	0x0000001F
 
 #define MXS_I2C_QUEUECMD	(0x80)
 
@@ -219,14 +220,14 @@
 	int ret;
 	int flags;
 
-	init_completion(&i2c->cmd_complete);
-
 	dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
 		msg->addr, msg->len, msg->flags, stop);
 
 	if (msg->len == 0)
 		return -EINVAL;
 
+	init_completion(&i2c->cmd_complete);
+
 	flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
 
 	if (msg->flags & I2C_M_RD)
@@ -286,6 +287,7 @@
 {
 	struct mxs_i2c_dev *i2c = dev_id;
 	u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK;
+	bool is_last_cmd;
 
 	if (!stat)
 		return IRQ_NONE;
@@ -300,9 +302,14 @@
 	else
 		i2c->cmd_err = 0;
 
-	complete(&i2c->cmd_complete);
+	is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
+		MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
+
+	if (is_last_cmd || i2c->cmd_err)
+		complete(&i2c->cmd_complete);
 
 	writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 6381604..0ab4a95 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -755,7 +755,7 @@
 
 static struct platform_driver tegra_i2c_driver = {
 	.probe   = tegra_i2c_probe,
-	.remove  = tegra_i2c_remove,
+	.remove  = __devexit_p(tegra_i2c_remove),
 #ifdef CONFIG_PM
 	.suspend = tegra_i2c_suspend,
 	.resume  = tegra_i2c_resume,
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 7f879b2..af8d016 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -116,4 +116,3 @@
 
 obj-$(CONFIG_BLK_DEV_IDE_TX4938)	+= tx4938ide.o
 obj-$(CONFIG_BLK_DEV_IDE_TX4939)	+= tx4939ide.o
-obj-$(CONFIG_BLK_DEV_IDE_AT91)		+= at91_ide.o
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
deleted file mode 100644
index 41d4155..0000000
--- a/drivers/ide/at91_ide.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * IDE host driver for AT91 (SAM9, CAP9, AT572D940HF) Static Memory Controller
- * with Compact Flash True IDE logic
- *
- * Copyright (c) 2008, 2009 Kelvatek Ltd.
- *
- *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/ide.h>
-#include <linux/platform_device.h>
-
-#include <mach/board.h>
-#include <asm/gpio.h>
-#include <mach/at91sam9_smc.h>
-
-#define DRV_NAME "at91_ide"
-
-#define perr(fmt, args...) pr_err(DRV_NAME ": " fmt, ##args)
-#define pdbg(fmt, args...) pr_debug("%s " fmt, __func__, ##args)
-
-/*
- * Access to IDE device is possible through EBI Static Memory Controller
- * with Compact Flash logic. For details see EBI and SMC datasheet sections
- * of any microcontroller from AT91SAM9 family.
- *
- * Within SMC chip select address space, lines A[23:21] distinguish Compact
- * Flash modes (I/O, common memory, attribute memory, True IDE). IDE modes are:
- *   0x00c0000 - True IDE
- *   0x00e0000 - Alternate True IDE (Alt Status Register)
- *
- * On True IDE mode Task File and Data Register are mapped at the same address.
- * To distinguish access between these two different bus data width is used:
- * 8Bit for Task File, 16Bit for Data I/O.
- *
- * After initialization we do 8/16 bit flipping (changes in SMC MODE register)
- * only inside IDE callback routines which are serialized by IDE layer,
- * so no additional locking needed.
- */
-
-#define TASK_FILE	0x00c00000
-#define ALT_MODE	0x00e00000
-#define REGS_SIZE	8
-
-#define enter_16bit(cs, mode) do {					\
-	mode = at91_sys_read(AT91_SMC_MODE(cs));			\
-	at91_sys_write(AT91_SMC_MODE(cs), mode | AT91_SMC_DBW_16);	\
-} while (0)
-
-#define leave_16bit(cs, mode) at91_sys_write(AT91_SMC_MODE(cs), mode);
-
-static void set_smc_timings(const u8 chipselect, const u16 cycle,
-			    const u16 setup, const u16 pulse,
-			    const u16 data_float, int use_iordy)
-{
-	unsigned long mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
-			     AT91_SMC_BAT_SELECT;
-
-	/* disable or enable waiting for IORDY signal */
-	if (use_iordy)
-		mode |= AT91_SMC_EXNWMODE_READY;
-
-	/* add data float cycles if needed */
-	if (data_float)
-		mode |= AT91_SMC_TDF_(data_float);
-
-	at91_sys_write(AT91_SMC_MODE(chipselect), mode);
-
-	/* setup timings in SMC */
-	at91_sys_write(AT91_SMC_SETUP(chipselect), AT91_SMC_NWESETUP_(setup) |
-						   AT91_SMC_NCS_WRSETUP_(0) |
-						   AT91_SMC_NRDSETUP_(setup) |
-						   AT91_SMC_NCS_RDSETUP_(0));
-	at91_sys_write(AT91_SMC_PULSE(chipselect), AT91_SMC_NWEPULSE_(pulse) |
-						   AT91_SMC_NCS_WRPULSE_(cycle) |
-						   AT91_SMC_NRDPULSE_(pulse) |
-						   AT91_SMC_NCS_RDPULSE_(cycle));
-	at91_sys_write(AT91_SMC_CYCLE(chipselect), AT91_SMC_NWECYCLE_(cycle) |
-						   AT91_SMC_NRDCYCLE_(cycle));
-}
-
-static unsigned int calc_mck_cycles(unsigned int ns, unsigned int mck_hz)
-{
-	u64 tmp = ns;
-
-	tmp *= mck_hz;
-	tmp += 1000*1000*1000 - 1; /* round up */
-	do_div(tmp, 1000*1000*1000);
-	return (unsigned int) tmp;
-}
-
-static void apply_timings(const u8 chipselect, const u8 pio,
-			  const struct ide_timing *timing, int use_iordy)
-{
-	unsigned int t0, t1, t2, t6z;
-	unsigned int cycle, setup, pulse, data_float;
-	unsigned int mck_hz;
-	struct clk *mck;
-
-	/* see table 22 of Compact Flash standard 4.1 for the meaning,
-	 * we do not stretch active (t2) time, so setup (t1) + hold time (th)
-	 * assure at least minimal recovery (t2i) time */
-	t0 = timing->cyc8b;
-	t1 = timing->setup;
-	t2 = timing->act8b;
-	t6z = (pio < 5) ? 30 : 20;
-
-	pdbg("t0=%u t1=%u t2=%u t6z=%u\n", t0, t1, t2, t6z);
-
-	mck = clk_get(NULL, "mck");
-	BUG_ON(IS_ERR(mck));
-	mck_hz = clk_get_rate(mck);
-	pdbg("mck_hz=%u\n", mck_hz);
-
-	cycle = calc_mck_cycles(t0, mck_hz);
-	setup = calc_mck_cycles(t1, mck_hz);
-	pulse = calc_mck_cycles(t2, mck_hz);
-	data_float = calc_mck_cycles(t6z, mck_hz);
-
-	pdbg("cycle=%u setup=%u pulse=%u data_float=%u\n",
-	     cycle, setup, pulse, data_float);
-
-	set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy);
-}
-
-static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
-				void *buf, unsigned int len)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	u8 chipselect = hwif->select_data;
-	unsigned long mode;
-
-	pdbg("cs %u buf %p len %d\n", chipselect, buf, len);
-
-	len++;
-
-	enter_16bit(chipselect, mode);
-	readsw((void __iomem *)io_ports->data_addr, buf, len / 2);
-	leave_16bit(chipselect, mode);
-}
-
-static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
-				 void *buf, unsigned int len)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	u8 chipselect = hwif->select_data;
-	unsigned long mode;
-
-	pdbg("cs %u buf %p len %d\n", chipselect,  buf, len);
-
-	enter_16bit(chipselect, mode);
-	writesw((void __iomem *)io_ports->data_addr, buf, len / 2);
-	leave_16bit(chipselect, mode);
-}
-
-static void at91_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
-	struct ide_timing *timing;
-	u8 chipselect = hwif->select_data;
-	int use_iordy = 0;
-	const u8 pio = drive->pio_mode - XFER_PIO_0;
-
-	pdbg("chipselect %u pio %u\n", chipselect, pio);
-
-	timing = ide_timing_find_mode(XFER_PIO_0 + pio);
-	BUG_ON(!timing);
-
-	if (ide_pio_need_iordy(drive, pio))
-		use_iordy = 1;
-
-	apply_timings(chipselect, pio, timing, use_iordy);
-}
-
-static const struct ide_tp_ops at91_ide_tp_ops = {
-	.exec_command	= ide_exec_command,
-	.read_status	= ide_read_status,
-	.read_altstatus	= ide_read_altstatus,
-	.write_devctl	= ide_write_devctl,
-
-	.dev_select	= ide_dev_select,
-	.tf_load	= ide_tf_load,
-	.tf_read	= ide_tf_read,
-
-	.input_data	= at91_ide_input_data,
-	.output_data	= at91_ide_output_data,
-};
-
-static const struct ide_port_ops at91_ide_port_ops = {
-	.set_pio_mode	= at91_ide_set_pio_mode,
-};
-
-static const struct ide_port_info at91_ide_port_info __initdata = {
-	.port_ops	= &at91_ide_port_ops,
-	.tp_ops		= &at91_ide_tp_ops,
-	.host_flags 	= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE |
-			  IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS,
-	.pio_mask 	= ATA_PIO6,
-	.chipset	= ide_generic,
-};
-
-/*
- * If interrupt is delivered through GPIO, IRQ are triggered on falling
- * and rising edge of signal. Whereas IDE device request interrupt on high
- * level (rising edge in our case). This mean we have fake interrupts, so
- * we need to check interrupt pin and exit instantly from ISR when line
- * is on low level.
- */
-
-irqreturn_t at91_irq_handler(int irq, void *dev_id)
-{
-	int ntries = 8;
-	int pin_val1, pin_val2;
-
-	/* additional deglitch, line can be noisy in badly designed PCB */
-	do {
-		pin_val1 = at91_get_gpio_value(irq);
-		pin_val2 = at91_get_gpio_value(irq);
-	} while (pin_val1 != pin_val2 && --ntries > 0);
-
-	if (pin_val1 == 0 || ntries <= 0)
-		return IRQ_HANDLED;
-
-	return ide_intr(irq, dev_id);
-}
-
-static int __init at91_ide_probe(struct platform_device *pdev)
-{
-	int ret;
-	struct ide_hw hw, *hws[] = { &hw };
-	struct ide_host *host;
-	struct resource *res;
-	unsigned long tf_base = 0, ctl_base = 0;
-	struct at91_cf_data *board = pdev->dev.platform_data;
-
-	if (!board)
-		return -ENODEV;
-
-	if (board->det_pin && at91_get_gpio_value(board->det_pin) != 0) {
-		perr("no device detected\n");
-		return -ENODEV;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		perr("can't get memory resource\n");
-		return -ENODEV;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev, res->start + TASK_FILE,
-				     REGS_SIZE, "ide") ||
-	    !devm_request_mem_region(&pdev->dev, res->start + ALT_MODE,
-				     REGS_SIZE, "alt")) {
-		perr("memory resources in use\n");
-		return -EBUSY;
-	}
-
-	pdbg("chipselect %u irq %u res %08lx\n", board->chipselect,
-	     board->irq_pin, (unsigned long) res->start);
-
-	tf_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + TASK_FILE,
-					       REGS_SIZE);
-	ctl_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + ALT_MODE,
-						REGS_SIZE);
-	if (!tf_base || !ctl_base) {
-		perr("can't map memory regions\n");
-		return -EBUSY;
-	}
-
-	memset(&hw, 0, sizeof(hw));
-
-	if (board->flags & AT91_IDE_SWAP_A0_A2) {
-		/* workaround for stupid hardware bug */
-		hw.io_ports.data_addr	= tf_base + 0;
-		hw.io_ports.error_addr	= tf_base + 4;
-		hw.io_ports.nsect_addr	= tf_base + 2;
-		hw.io_ports.lbal_addr	= tf_base + 6;
-		hw.io_ports.lbam_addr	= tf_base + 1;
-		hw.io_ports.lbah_addr	= tf_base + 5;
-		hw.io_ports.device_addr = tf_base + 3;
-		hw.io_ports.command_addr = tf_base + 7;
-		hw.io_ports.ctl_addr	= ctl_base + 3;
-	} else
-		ide_std_init_ports(&hw, tf_base, ctl_base + 6);
-
-	hw.irq = board->irq_pin;
-	hw.dev = &pdev->dev;
-
-	host = ide_host_alloc(&at91_ide_port_info, hws, 1);
-	if (!host) {
-		perr("failed to allocate ide host\n");
-		return -ENOMEM;
-	}
-
-	/* setup Static Memory Controller - PIO 0 as default */
-	apply_timings(board->chipselect, 0, ide_timing_find_mode(XFER_PIO_0), 0);
-
-	/* with GPIO interrupt we have to do quirks in handler */
-	if (gpio_is_valid(board->irq_pin))
-		host->irq_handler = at91_irq_handler;
-
-	host->ports[0]->select_data = board->chipselect;
-
-	ret = ide_host_register(host, &at91_ide_port_info, hws);
-	if (ret) {
-		perr("failed to register ide host\n");
-		goto err_free_host;
-	}
-	platform_set_drvdata(pdev, host);
-	return 0;
-
-err_free_host:
-	ide_host_free(host);
-	return ret;
-}
-
-static int __exit at91_ide_remove(struct platform_device *pdev)
-{
-	struct ide_host *host = platform_get_drvdata(pdev);
-
-	ide_host_remove(host);
-	return 0;
-}
-
-static struct platform_driver at91_ide_driver = {
-	.driver	= {
-		.name = DRV_NAME,
-		.owner = THIS_MODULE,
-	},
-	.remove	= __exit_p(at91_ide_remove),
-};
-
-static int __init at91_ide_init(void)
-{
-	return platform_driver_probe(&at91_ide_driver, at91_ide_probe);
-}
-
-static void __exit at91_ide_exit(void)
-{
-	platform_driver_unregister(&at91_ide_driver);
-}
-
-module_init(at91_ide_init);
-module_exit(at91_ide_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Stanislaw Gruszka <stf_xl@wp.pl>");
-
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index b3cc1e0..86df632 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -44,6 +44,7 @@
 #include <linux/mutex.h>
 
 #include <net/neighbour.h>
+#include <net/sch_generic.h>
 
 #include <linux/atomic.h>
 
@@ -117,8 +118,9 @@
 	u16	reserved;
 };
 
-struct ipoib_pseudoheader {
-	u8  hwaddr[INFINIBAND_ALEN];
+struct ipoib_cb {
+	struct qdisc_skb_cb	qdisc_cb;
+	u8			hwaddr[INFINIBAND_ALEN];
 };
 
 /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 3514ca0..3974c29 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -653,7 +653,7 @@
 }
 
 static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
-			     struct ipoib_pseudoheader *phdr)
+			     struct ipoib_cb *cb)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ipoib_path *path;
@@ -661,17 +661,15 @@
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	path = __path_find(dev, phdr->hwaddr + 4);
+	path = __path_find(dev, cb->hwaddr + 4);
 	if (!path || !path->valid) {
 		int new_path = 0;
 
 		if (!path) {
-			path = path_rec_create(dev, phdr->hwaddr + 4);
+			path = path_rec_create(dev, cb->hwaddr + 4);
 			new_path = 1;
 		}
 		if (path) {
-			/* put pseudoheader back on for next time */
-			skb_push(skb, sizeof *phdr);
 			__skb_queue_tail(&path->queue, skb);
 
 			if (!path->query && path_rec_start(dev, path)) {
@@ -695,12 +693,10 @@
 			  be16_to_cpu(path->pathrec.dlid));
 
 		spin_unlock_irqrestore(&priv->lock, flags);
-		ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr));
+		ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr));
 		return;
 	} else if ((path->query || !path_rec_start(dev, path)) &&
 		   skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
-		/* put pseudoheader back on for next time */
-		skb_push(skb, sizeof *phdr);
 		__skb_queue_tail(&path->queue, skb);
 	} else {
 		++dev->stats.tx_dropped;
@@ -774,16 +770,14 @@
 			dev_kfree_skb_any(skb);
 		}
 	} else {
-		struct ipoib_pseudoheader *phdr =
-			(struct ipoib_pseudoheader *) skb->data;
-		skb_pull(skb, sizeof *phdr);
+		struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb;
 
-		if (phdr->hwaddr[4] == 0xff) {
+		if (cb->hwaddr[4] == 0xff) {
 			/* Add in the P_Key for multicast*/
-			phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff;
-			phdr->hwaddr[9] = priv->pkey & 0xff;
+			cb->hwaddr[8] = (priv->pkey >> 8) & 0xff;
+			cb->hwaddr[9] = priv->pkey & 0xff;
 
-			ipoib_mcast_send(dev, phdr->hwaddr + 4, skb);
+			ipoib_mcast_send(dev, cb->hwaddr + 4, skb);
 		} else {
 			/* unicast GID -- should be ARP or RARP reply */
 
@@ -792,14 +786,14 @@
 				ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
 					   skb_dst(skb) ? "neigh" : "dst",
 					   be16_to_cpup((__be16 *) skb->data),
-					   IPOIB_QPN(phdr->hwaddr),
-					   phdr->hwaddr + 4);
+					   IPOIB_QPN(cb->hwaddr),
+					   cb->hwaddr + 4);
 				dev_kfree_skb_any(skb);
 				++dev->stats.tx_dropped;
 				goto unlock;
 			}
 
-			unicast_arp_send(skb, dev, phdr);
+			unicast_arp_send(skb, dev, cb);
 		}
 	}
 unlock:
@@ -825,8 +819,6 @@
 			     const void *daddr, const void *saddr, unsigned len)
 {
 	struct ipoib_header *header;
-	struct dst_entry *dst;
-	struct neighbour *n;
 
 	header = (struct ipoib_header *) skb_push(skb, sizeof *header);
 
@@ -834,18 +826,13 @@
 	header->reserved = 0;
 
 	/*
-	 * If we don't have a neighbour structure, stuff the
-	 * destination address onto the front of the skb so we can
-	 * figure out where to send the packet later.
+	 * If we don't have a dst_entry structure, stuff the
+	 * destination address into skb->cb so we can figure out where
+	 * to send the packet later.
 	 */
-	dst = skb_dst(skb);
-	n = NULL;
-	if (dst)
-		n = dst_get_neighbour_noref_raw(dst);
-	if ((!dst || !n) && daddr) {
-		struct ipoib_pseudoheader *phdr =
-			(struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
-		memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
+	if (!skb_dst(skb)) {
+		struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb;
+		memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN);
 	}
 
 	return 0;
@@ -1021,11 +1008,7 @@
 
 	dev->flags		|= IFF_BROADCAST | IFF_MULTICAST;
 
-	/*
-	 * We add in INFINIBAND_ALEN to allow for the destination
-	 * address "pseudoheader" for skbs without neighbour struct.
-	 */
-	dev->hard_header_len	 = IPOIB_ENCAP_LEN + INFINIBAND_ALEN;
+	dev->hard_header_len	 = IPOIB_ENCAP_LEN;
 	dev->addr_len		 = INFINIBAND_ALEN;
 	dev->type		 = ARPHRD_INFINIBAND;
 	dev->tx_queue_len	 = ipoib_sendq_size * 2;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index f7ff9dd..20ebc6f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -262,21 +262,13 @@
 	netif_tx_lock_bh(dev);
 	while (!skb_queue_empty(&mcast->pkt_queue)) {
 		struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
-		struct dst_entry *dst = skb_dst(skb);
-		struct neighbour *n = NULL;
 
 		netif_tx_unlock_bh(dev);
 
 		skb->dev = dev;
-		if (dst)
-			n = dst_get_neighbour_noref_raw(dst);
-		if (!dst || !n) {
-			/* put pseudoheader back on for next time */
-			skb_push(skb, sizeof (struct ipoib_pseudoheader));
-		}
-
 		if (dev_queue_xmit(skb))
 			ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n");
+
 		netif_tx_lock_bh(dev);
 	}
 	netif_tx_unlock_bh(dev);
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index 288da5c..103dbd9 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -44,7 +44,8 @@
 static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
 			       size_t count, loff_t *ppos)
 {
-	struct omap_iommu *obj = file->private_data;
+	struct device *dev = file->private_data;
+	struct omap_iommu *obj = dev_to_omap_iommu(dev);
 	char *p, *buf;
 	ssize_t bytes;
 
@@ -67,7 +68,8 @@
 static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
 			      size_t count, loff_t *ppos)
 {
-	struct omap_iommu *obj = file->private_data;
+	struct device *dev = file->private_data;
+	struct omap_iommu *obj = dev_to_omap_iommu(dev);
 	char *p, *buf;
 	ssize_t bytes, rest;
 
@@ -97,7 +99,8 @@
 	struct iotlb_entry e;
 	struct cr_regs cr;
 	int err;
-	struct omap_iommu *obj = file->private_data;
+	struct device *dev = file->private_data;
+	struct omap_iommu *obj = dev_to_omap_iommu(dev);
 	char buf[MAXCOLUMN], *p = buf;
 
 	count = min(count, sizeof(buf));
@@ -184,7 +187,8 @@
 static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
 				    size_t count, loff_t *ppos)
 {
-	struct omap_iommu *obj = file->private_data;
+	struct device *dev = file->private_data;
+	struct omap_iommu *obj = dev_to_omap_iommu(dev);
 	char *p, *buf;
 	size_t bytes;
 
@@ -212,7 +216,8 @@
 static ssize_t debug_read_mmap(struct file *file, char __user *userbuf,
 			       size_t count, loff_t *ppos)
 {
-	struct omap_iommu *obj = file->private_data;
+	struct device *dev = file->private_data;
+	struct omap_iommu *obj = dev_to_omap_iommu(dev);
 	char *p, *buf;
 	struct iovm_struct *tmp;
 	int uninitialized_var(i);
@@ -254,7 +259,7 @@
 static ssize_t debug_read_mem(struct file *file, char __user *userbuf,
 			      size_t count, loff_t *ppos)
 {
-	struct omap_iommu *obj = file->private_data;
+	struct device *dev = file->private_data;
 	char *p, *buf;
 	struct iovm_struct *area;
 	ssize_t bytes;
@@ -268,8 +273,8 @@
 
 	mutex_lock(&iommu_debug_lock);
 
-	area = omap_find_iovm_area(obj, (u32)ppos);
-	if (IS_ERR(area)) {
+	area = omap_find_iovm_area(dev, (u32)ppos);
+	if (!area) {
 		bytes = -EINVAL;
 		goto err_out;
 	}
@@ -287,7 +292,7 @@
 static ssize_t debug_write_mem(struct file *file, const char __user *userbuf,
 			       size_t count, loff_t *ppos)
 {
-	struct omap_iommu *obj = file->private_data;
+	struct device *dev = file->private_data;
 	struct iovm_struct *area;
 	char *p, *buf;
 
@@ -305,8 +310,8 @@
 		goto err_out;
 	}
 
-	area = omap_find_iovm_area(obj, (u32)ppos);
-	if (IS_ERR(area)) {
+	area = omap_find_iovm_area(dev, (u32)ppos);
+	if (!area) {
 		count = -EINVAL;
 		goto err_out;
 	}
@@ -350,7 +355,7 @@
 	{								\
 		struct dentry *dent;					\
 		dent = debugfs_create_file(#attr, mode, parent,		\
-					   obj, &debug_##attr##_fops);	\
+					   dev, &debug_##attr##_fops);	\
 		if (!dent)						\
 			return -ENOMEM;					\
 	}
@@ -362,20 +367,29 @@
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct omap_iommu *obj = platform_get_drvdata(pdev);
+	struct omap_iommu_arch_data *arch_data;
 	struct dentry *d, *parent;
 
 	if (!obj || !obj->dev)
 		return -EINVAL;
 
+	arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL);
+	if (!arch_data)
+		return -ENOMEM;
+
+	arch_data->iommu_dev = obj;
+
+	dev->archdata.iommu = arch_data;
+
 	d = debugfs_create_dir(obj->name, iommu_debug_root);
 	if (!d)
-		return -ENOMEM;
+		goto nomem;
 	parent = d;
 
 	d = debugfs_create_u8("nr_tlb_entries", 400, parent,
 			      (u8 *)&obj->nr_tlb_entries);
 	if (!d)
-		return -ENOMEM;
+		goto nomem;
 
 	DEBUG_ADD_FILE_RO(ver);
 	DEBUG_ADD_FILE_RO(regs);
@@ -385,6 +399,22 @@
 	DEBUG_ADD_FILE(mem);
 
 	return 0;
+
+nomem:
+	kfree(arch_data);
+	return -ENOMEM;
+}
+
+static int iommu_debug_unregister(struct device *dev, void *data)
+{
+	if (!dev->archdata.iommu)
+		return 0;
+
+	kfree(dev->archdata.iommu);
+
+	dev->archdata.iommu = NULL;
+
+	return 0;
 }
 
 static int __init iommu_debug_init(void)
@@ -411,6 +441,7 @@
 static void __exit iommu_debugfs_exit(void)
 {
 	debugfs_remove_recursive(iommu_debug_root);
+	omap_foreach_iommu_device(NULL, iommu_debug_unregister);
 }
 module_exit(iommu_debugfs_exit)
 
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index d8edd97..6899dcd 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1223,7 +1223,8 @@
 
 	return platform_driver_register(&omap_iommu_driver);
 }
-module_init(omap_iommu_init);
+/* must be ready before omap3isp is probed */
+subsys_initcall(omap_iommu_init);
 
 static void __exit omap_iommu_exit(void)
 {
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 2339d73..802ab87 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1901,7 +1901,7 @@
 {
 	isdn_net_local *lp = netdev_priv(dev);
 	unsigned char *p;
-	ushort len = 0;
+	int len = 0;
 
 	switch (lp->p_encap) {
 		case ISDN_NET_ENCAP_ETHER:
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 75049e7..b026896 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -710,7 +710,7 @@
 	req = NULL;
 	spin_lock_irqsave(&state->lock, flags);
 	add_wait_queue(&state->wait_queue, &wait);
-	current->state = TASK_INTERRUPTIBLE;
+	set_current_state(TASK_INTERRUPTIBLE);
 
 	for (;;) {
 		req = state->completed;
@@ -734,7 +734,7 @@
 		spin_lock_irqsave(&state->lock, flags);
 	}
 
-	current->state = TASK_RUNNING;
+	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&state->wait_queue, &wait);
 	spin_unlock_irqrestore(&state->lock, flags);
 	
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
index 86b2857..ea1e654 100644
--- a/drivers/media/radio/wl128x/Kconfig
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -4,8 +4,8 @@
 menu "Texas Instruments WL128x FM driver (ST based)"
 config RADIO_WL128X
 	tristate "Texas Instruments WL128x FM Radio"
-	depends on VIDEO_V4L2 && RFKILL
-	select TI_ST if NET && GPIOLIB
+	depends on VIDEO_V4L2 && RFKILL && GPIOLIB
+	select TI_ST if NET
 	help
 	Choose Y here if you have this FM radio chip.
 
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 3aeb29a..7f26fdf 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -47,7 +47,7 @@
 #define MOD_AUTHOR	"Jarod Wilson <jarod@wilsonet.com>"
 #define MOD_DESC	"Driver for SoundGraph iMON MultiMedia IR/Display"
 #define MOD_NAME	"imon"
-#define MOD_VERSION	"0.9.3"
+#define MOD_VERSION	"0.9.4"
 
 #define DISPLAY_MINOR_BASE	144
 #define DEVICE_NAME	"lcd%d"
@@ -1658,9 +1658,17 @@
 		return;
 
 	ictx = (struct imon_context *)urb->context;
-	if (!ictx || !ictx->dev_present_intf0)
+	if (!ictx)
 		return;
 
+	/*
+	 * if we get a callback before we're done configuring the hardware, we
+	 * can't yet process the data, as there's nowhere to send it, but we
+	 * still need to submit a new rx URB to avoid wedging the hardware
+	 */
+	if (!ictx->dev_present_intf0)
+		goto out;
+
 	switch (urb->status) {
 	case -ENOENT:		/* usbcore unlink successful! */
 		return;
@@ -1678,6 +1686,7 @@
 		break;
 	}
 
+out:
 	usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
 }
 
@@ -1690,9 +1699,17 @@
 		return;
 
 	ictx = (struct imon_context *)urb->context;
-	if (!ictx || !ictx->dev_present_intf1)
+	if (!ictx)
 		return;
 
+	/*
+	 * if we get a callback before we're done configuring the hardware, we
+	 * can't yet process the data, as there's nowhere to send it, but we
+	 * still need to submit a new rx URB to avoid wedging the hardware
+	 */
+	if (!ictx->dev_present_intf1)
+		goto out;
+
 	switch (urb->status) {
 	case -ENOENT:		/* usbcore unlink successful! */
 		return;
@@ -1710,6 +1727,7 @@
 		break;
 	}
 
+out:
 	usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
 }
 
@@ -2242,7 +2260,7 @@
 	mutex_unlock(&ictx->lock);
 	usb_free_urb(rx_urb);
 rx_urb_alloc_failed:
-	dev_err(ictx->dev, "unable to initialize intf0, err %d\n", ret);
+	dev_err(ictx->dev, "unable to initialize intf1, err %d\n", ret);
 
 	return NULL;
 }
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index e5eb56a..6510110 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -154,10 +154,20 @@
 	}
 #endif
 
-	v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n",
-			  dev->usbc_buf[1], &dev->usbc_buf[2]);
+	dev->fw_ver = dev->usbc_buf[1];
 
-	switch (dev->usbc_buf[1]) {
+	v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n",
+			  dev->fw_ver, &dev->usbc_buf[2]);
+
+	if (dev->fw_ver > 0x15) {
+		dev->options.brightness	= 0x80;
+		dev->options.contrast	= 0x40;
+		dev->options.hue	= 0xf;
+		dev->options.saturation	= 0x40;
+		dev->options.sharpness	= 0x80;
+	}
+
+	switch (dev->fw_ver) {
 	case HDPVR_FIRMWARE_VERSION:
 		dev->flags &= ~HDPVR_FLAG_AC3_CAP;
 		break;
@@ -169,7 +179,7 @@
 	default:
 		v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might"
 			  " not work.\n");
-		if (dev->usbc_buf[1] >= HDPVR_FIRMWARE_VERSION_AC3)
+		if (dev->fw_ver >= HDPVR_FIRMWARE_VERSION_AC3)
 			dev->flags |= HDPVR_FLAG_AC3_CAP;
 		else
 			dev->flags &= ~HDPVR_FLAG_AC3_CAP;
@@ -270,6 +280,8 @@
 	.bitrate_mode	= HDPVR_CONSTANT,
 	.gop_mode	= HDPVR_SIMPLE_IDR_GOP,
 	.audio_codec	= V4L2_MPEG_AUDIO_ENCODING_AAC,
+	/* original picture controls for firmware version <= 0x15 */
+	/* updated in device_authorization() for newer firmware */
 	.brightness	= 0x86,
 	.contrast	= 0x80,
 	.hue		= 0x80,
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 087f7c0..11ffe9c 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -283,12 +283,13 @@
 
 		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
 
+		dev->status = STATUS_STREAMING;
+
 		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
 		queue_work(dev->workqueue, &dev->worker);
 
 		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
 			 "streaming started\n");
-		dev->status = STATUS_STREAMING;
 
 		return 0;
 	}
@@ -722,21 +723,39 @@
 };
 
 static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
-			  int ac3)
+			  int ac3, int fw_ver)
 {
 	int err;
 
+	if (fw_ver > 0x15) {
+		switch (qc->id) {
+		case V4L2_CID_BRIGHTNESS:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		case V4L2_CID_CONTRAST:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
+		case V4L2_CID_SATURATION:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
+		case V4L2_CID_HUE:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0x1e, 1, 0xf);
+		case V4L2_CID_SHARPNESS:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		}
+	} else {
+		switch (qc->id) {
+		case V4L2_CID_BRIGHTNESS:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
+		case V4L2_CID_CONTRAST:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		case V4L2_CID_SATURATION:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		case V4L2_CID_HUE:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		case V4L2_CID_SHARPNESS:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		}
+	}
+
 	switch (qc->id) {
-	case V4L2_CID_BRIGHTNESS:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
-	case V4L2_CID_CONTRAST:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
-	case V4L2_CID_SATURATION:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
-	case V4L2_CID_HUE:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
-	case V4L2_CID_SHARPNESS:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
 	case V4L2_CID_MPEG_AUDIO_ENCODING:
 		return v4l2_ctrl_query_fill(
 			qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
@@ -794,7 +813,8 @@
 
 		if (qc->id == supported_v4l2_ctrls[i])
 			return fill_queryctrl(&dev->options, qc,
-					      dev->flags & HDPVR_FLAG_AC3_CAP);
+					      dev->flags & HDPVR_FLAG_AC3_CAP,
+					      dev->fw_ver);
 
 		if (qc->id < supported_v4l2_ctrls[i])
 			break;
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index d6439db..fea3c69 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -113,6 +113,7 @@
 	/* usb control transfer buffer and lock */
 	struct mutex		usbc_mutex;
 	u8			*usbc_buf;
+	u8			fw_ver;
 };
 
 static inline struct hdpvr_device *to_hdpvr_dev(struct v4l2_device *v4l2_dev)
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index a74a797..eaabc27 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1407,7 +1407,7 @@
 static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
 {
 	struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
-	struct video_device *vdev = &ccdc->subdev.devnode;
+	struct video_device *vdev = ccdc->subdev.devnode;
 	struct v4l2_event event;
 
 	memset(&event, 0, sizeof(event));
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index cd13e9f..f147395 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -200,7 +200,7 @@
 
 config TWL4030_CORE
 	bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
-	depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN
+	depends on I2C=y && GENERIC_HARDIRQS
 	help
 	  Say yes here if you have TWL4030 / TWL6030 family chip on your board.
 	  This core driver provides register access and IRQ handling
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index e04e04d..8ce3959 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -263,7 +263,9 @@
 
 static struct twl_client twl_modules[TWL_NUM_SLAVES];
 
+#ifdef CONFIG_IRQ_DOMAIN
 static struct irq_domain domain;
+#endif
 
 /* mapping the module id to slave id and base address */
 struct twl_mapping {
@@ -1226,13 +1228,13 @@
 	pdata->irq_base = status;
 	pdata->irq_end = pdata->irq_base + nr_irqs;
 
+#ifdef CONFIG_IRQ_DOMAIN
 	domain.irq_base = pdata->irq_base;
 	domain.nr_irq = nr_irqs;
-#ifdef CONFIG_OF_IRQ
 	domain.of_node = of_node_get(node);
 	domain.ops = &irq_domain_simple_ops;
-#endif
 	irq_domain_add(&domain);
+#endif
 
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
 		dev_dbg(&client->dev, "can't talk I2C?\n");
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index d905f51..79ca33d 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -124,7 +124,7 @@
 	[RES_MAIN_REF]	= 0x94,
 };
 
-static int __init twl4030_write_script_byte(u8 address, u8 byte)
+static int __devinit twl4030_write_script_byte(u8 address, u8 byte)
 {
 	int err;
 
@@ -138,7 +138,7 @@
 	return err;
 }
 
-static int __init twl4030_write_script_ins(u8 address, u16 pmb_message,
+static int __devinit twl4030_write_script_ins(u8 address, u16 pmb_message,
 					   u8 delay, u8 next)
 {
 	int err;
@@ -158,7 +158,7 @@
 	return err;
 }
 
-static int __init twl4030_write_script(u8 address, struct twl4030_ins *script,
+static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script,
 				       int len)
 {
 	int err;
@@ -183,7 +183,7 @@
 	return err;
 }
 
-static int __init twl4030_config_wakeup3_sequence(u8 address)
+static int __devinit twl4030_config_wakeup3_sequence(u8 address)
 {
 	int err;
 	u8 data;
@@ -208,7 +208,7 @@
 	return err;
 }
 
-static int __init twl4030_config_wakeup12_sequence(u8 address)
+static int __devinit twl4030_config_wakeup12_sequence(u8 address)
 {
 	int err = 0;
 	u8 data;
@@ -262,7 +262,7 @@
 	return err;
 }
 
-static int __init twl4030_config_sleep_sequence(u8 address)
+static int __devinit twl4030_config_sleep_sequence(u8 address)
 {
 	int err;
 
@@ -276,7 +276,7 @@
 	return err;
 }
 
-static int __init twl4030_config_warmreset_sequence(u8 address)
+static int __devinit twl4030_config_warmreset_sequence(u8 address)
 {
 	int err;
 	u8 rd_data;
@@ -324,7 +324,7 @@
 	return err;
 }
 
-static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
+static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfig)
 {
 	int rconfig_addr;
 	int err;
@@ -416,7 +416,7 @@
 	return 0;
 }
 
-static int __init load_twl4030_script(struct twl4030_script *tscript,
+static int __devinit load_twl4030_script(struct twl4030_script *tscript,
 	       u8 address)
 {
 	int err;
@@ -527,7 +527,7 @@
 		pr_err("TWL4030 Unable to power off\n");
 }
 
-void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
+void __devinit twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
 {
 	int err = 0;
 	int i;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6a1a092..c779509 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -2,24 +2,14 @@
 # Misc strange devices
 #
 
-# This one has to live outside of the MISC_DEVICES conditional,
-# because it may be selected by drivers/platform/x86/hp_accel.
+menu "Misc devices"
+
 config SENSORS_LIS3LV02D
 	tristate
 	depends on INPUT
 	select INPUT_POLLDEV
 	default n
 
-menuconfig MISC_DEVICES
-	bool "Misc devices"
-	---help---
-	  Say Y here to get to see options for device drivers from various
-	  different categories. This option alone does not add any kernel code.
-
-	  If you say N, all options in this submenu will be skipped and disabled.
-
-if MISC_DEVICES
-
 config AD525X_DPOT
 	tristate "Analog Devices Digital Potentiometers"
 	depends on (I2C || SPI) && SYSFS
@@ -516,5 +506,4 @@
 source "drivers/misc/lis3lv02d/Kconfig"
 source "drivers/misc/carma/Kconfig"
 source "drivers/misc/altera-stapl/Kconfig"
-
-endif # MISC_DEVICES
+endmenu
diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c
index 778fc3f..5484301 100644
--- a/drivers/misc/c2port/c2port-duramar2150.c
+++ b/drivers/misc/c2port/c2port-duramar2150.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/c2port.h>
 
 #define DATA_PORT	0x325
diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c
index 68cd05b..85cc771 100644
--- a/drivers/misc/cb710/core.c
+++ b/drivers/misc/cb710/core.c
@@ -245,6 +245,7 @@
 	if (err)
 		return err;
 
+	spin_lock_init(&chip->irq_lock);
 	chip->pdev = pdev;
 	chip->iobase = pcim_iomap_table(pdev)[0];
 
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c
index bc685bf..87a390d 100644
--- a/drivers/misc/cs5535-mfgpt.c
+++ b/drivers/misc/cs5535-mfgpt.c
@@ -262,7 +262,7 @@
  * In other cases (such as with VSAless OpenFirmware), the system firmware
  * leaves timers available for us to use.
  */
-static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt)
+static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt)
 {
 	struct cs5535_mfgpt_timer timer = { .chip = mfgpt };
 	unsigned long flags;
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index cd41d40..cb56e27 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -314,7 +314,7 @@
  * fear that guest will need it. Host may reject some pages, we need to
  * check the return value and maybe submit a different page.
  */
-static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
+static int vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
 				     unsigned int *hv_status)
 {
 	unsigned long status, dummy;
@@ -322,17 +322,17 @@
 
 	pfn32 = (u32)pfn;
 	if (pfn32 != pfn)
-		return false;
+		return -1;
 
 	STATS_INC(b->stats.lock);
 
 	*hv_status = status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
 	if (vmballoon_check_status(b, status))
-		return true;
+		return 0;
 
 	pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
 	STATS_INC(b->stats.lock_fail);
-	return false;
+	return 1;
 }
 
 /*
@@ -411,7 +411,7 @@
 	struct page *page;
 	gfp_t flags;
 	unsigned int hv_status;
-	bool locked = false;
+	int locked;
 	flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
 
 	do {
@@ -431,7 +431,7 @@
 
 		/* inform monitor */
 		locked = vmballoon_send_lock_page(b, page_to_pfn(page), &hv_status);
-		if (!locked) {
+		if (locked > 0) {
 			STATS_INC(b->stats.refused_alloc);
 
 			if (hv_status == VMW_BALLOON_ERROR_RESET ||
@@ -449,7 +449,7 @@
 			if (++b->n_refused_pages >= VMW_BALLOON_MAX_REFUSED)
 				return -EIO;
 		}
-	} while (!locked);
+	} while (locked != 0);
 
 	/* track allocated page */
 	list_add(&page->lru, &b->pages);
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 0cad48a..c6a383d 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1694,6 +1694,7 @@
 
 		md->power_ro_lock.show = power_ro_lock_show;
 		md->power_ro_lock.store = power_ro_lock_store;
+		sysfs_attr_init(&md->power_ro_lock.attr);
 		md->power_ro_lock.attr.mode = mode;
 		md->power_ro_lock.attr.name =
 					"ro_lock_until_next_power_on";
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index f545a3e..690255c 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -290,8 +290,11 @@
 static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
 		 bool is_first_req)
 {
-	if (host->ops->pre_req)
+	if (host->ops->pre_req) {
+		mmc_host_clk_hold(host);
 		host->ops->pre_req(host, mrq, is_first_req);
+		mmc_host_clk_release(host);
+	}
 }
 
 /**
@@ -306,8 +309,11 @@
 static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
 			 int err)
 {
-	if (host->ops->post_req)
+	if (host->ops->post_req) {
+		mmc_host_clk_hold(host);
 		host->ops->post_req(host, mrq, err);
+		mmc_host_clk_release(host);
+	}
 }
 
 /**
@@ -620,7 +626,9 @@
 		int err;
 
 		host->en_dis_recurs = 1;
+		mmc_host_clk_hold(host);
 		err = host->ops->enable(host);
+		mmc_host_clk_release(host);
 		host->en_dis_recurs = 0;
 
 		if (err) {
@@ -640,7 +648,9 @@
 		int err;
 
 		host->en_dis_recurs = 1;
+		mmc_host_clk_hold(host);
 		err = host->ops->disable(host, lazy);
+		mmc_host_clk_release(host);
 		host->en_dis_recurs = 0;
 
 		if (err < 0) {
@@ -1121,6 +1131,10 @@
 		 * might not allow this operation
 		 */
 		voltage = regulator_get_voltage(supply);
+
+		if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE)
+			min_uV = max_uV = voltage;
+
 		if (voltage < 0)
 			result = voltage;
 		else if (voltage < min_uV || voltage > max_uV)
@@ -1203,8 +1217,11 @@
 
 	host->ios.signal_voltage = signal_voltage;
 
-	if (host->ops->start_signal_voltage_switch)
+	if (host->ops->start_signal_voltage_switch) {
+		mmc_host_clk_hold(host);
 		err = host->ops->start_signal_voltage_switch(host, &host->ios);
+		mmc_host_clk_release(host);
+	}
 
 	return err;
 }
@@ -1239,6 +1256,7 @@
 	int err = 0;
 
 	card = host->card;
+	mmc_claim_host(host);
 
 	/*
 	 * Send power notify command only if card
@@ -1269,6 +1287,7 @@
 		/* Set the card state to no notification after the poweroff */
 		card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
 	}
+	mmc_release_host(host);
 }
 
 /*
@@ -1327,12 +1346,28 @@
 
 void mmc_power_off(struct mmc_host *host)
 {
+	int err = 0;
 	mmc_host_clk_hold(host);
 
 	host->ios.clock = 0;
 	host->ios.vdd = 0;
 
-	mmc_poweroff_notify(host);
+	/*
+	 * For eMMC 4.5 device send AWAKE command before
+	 * POWER_OFF_NOTIFY command, because in sleep state
+	 * eMMC 4.5 devices respond to only RESET and AWAKE cmd
+	 */
+	if (host->card && mmc_card_is_sleep(host->card) &&
+	    host->bus_ops->resume) {
+		err = host->bus_ops->resume(host);
+
+		if (!err)
+			mmc_poweroff_notify(host);
+		else
+			pr_warning("%s: error %d during resume "
+				   "(continue with poweroff sequence)\n",
+				   mmc_hostname(host), err);
+	}
 
 	/*
 	 * Reset ocr mask to be the highest possible voltage supported for
@@ -2386,12 +2421,6 @@
 		 */
 		if (mmc_try_claim_host(host)) {
 			if (host->bus_ops->suspend) {
-				/*
-				 * For eMMC 4.5 device send notify command
-				 * before sleep, because in sleep state eMMC 4.5
-				 * devices respond to only RESET and AWAKE cmd
-				 */
-				mmc_poweroff_notify(host);
 				err = host->bus_ops->suspend(host);
 			}
 			mmc_do_release_host(host);
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
index fb8a5cd..08a7852 100644
--- a/drivers/mmc/core/host.h
+++ b/drivers/mmc/core/host.h
@@ -14,27 +14,6 @@
 
 int mmc_register_host_class(void);
 void mmc_unregister_host_class(void);
-
-#ifdef CONFIG_MMC_CLKGATE
-void mmc_host_clk_hold(struct mmc_host *host);
-void mmc_host_clk_release(struct mmc_host *host);
-unsigned int mmc_host_clk_rate(struct mmc_host *host);
-
-#else
-static inline void mmc_host_clk_hold(struct mmc_host *host)
-{
-}
-
-static inline void mmc_host_clk_release(struct mmc_host *host)
-{
-}
-
-static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
-{
-	return host->ios.clock;
-}
-#endif
-
 void mmc_host_deeper_disable(struct work_struct *work);
 
 #endif
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 59b9ba5..a480663 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -376,7 +376,7 @@
 	}
 
 	card->ext_csd.raw_hc_erase_gap_size =
-		ext_csd[EXT_CSD_PARTITION_ATTRIBUTE];
+		ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
 	card->ext_csd.raw_sec_trim_mult =
 		ext_csd[EXT_CSD_SEC_TRIM_MULT];
 	card->ext_csd.raw_sec_erase_mult =
@@ -551,7 +551,7 @@
 		goto out;
 
 	/* only compare read only fields */
-	err = (!(card->ext_csd.raw_partition_support ==
+	err = !((card->ext_csd.raw_partition_support ==
 			bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
 		(card->ext_csd.raw_erased_mem_count ==
 			bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
@@ -1006,7 +1006,8 @@
 			err = mmc_select_hs200(card);
 		else if	(host->caps & MMC_CAP_MMC_HIGHSPEED)
 			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-					 EXT_CSD_HS_TIMING, 1, 0);
+					 EXT_CSD_HS_TIMING, 1,
+					 card->ext_csd.generic_cmd6_time);
 
 		if (err && err != -EBADMSG)
 			goto free_card;
@@ -1116,7 +1117,7 @@
 	 * Activate wide bus and DDR (if supported).
 	 */
 	if (!mmc_card_hs200(card) &&
-	    (card->csd.mmca_vsn >= CSD_SPEC_VER_3) &&
+	    (card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
 	    (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
 		static unsigned ext_csd_bits[][2] = {
 			{ EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
@@ -1315,11 +1316,13 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_can_sleep(host))
+	if (mmc_card_can_sleep(host)) {
 		err = mmc_card_sleep(host);
-	else if (!mmc_host_is_spi(host))
+		if (!err)
+			mmc_card_set_sleep(host->card);
+	} else if (!mmc_host_is_spi(host))
 		mmc_deselect_cards(host);
-	host->card->state &= ~MMC_STATE_HIGHSPEED;
+	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 	mmc_release_host(host);
 
 	return err;
@@ -1339,7 +1342,11 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	err = mmc_init_card(host, host->ocr, host->card);
+	if (mmc_card_is_sleep(host->card)) {
+		err = mmc_card_awake(host);
+		mmc_card_clr_sleep(host->card);
+	} else
+		err = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
 	return err;
@@ -1349,7 +1356,8 @@
 {
 	int ret;
 
-	host->card->state &= ~MMC_STATE_HIGHSPEED;
+	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
+	mmc_card_clr_sleep(host->card);
 	mmc_claim_host(host);
 	ret = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index c63ad03..5017f93 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -451,9 +451,11 @@
 	 * information and let the hardware specific code
 	 * return what is possible given the options
 	 */
+	mmc_host_clk_hold(card->host);
 	drive_strength = card->host->ops->select_drive_strength(
 		card->sw_caps.uhs_max_dtr,
 		host_drv_type, card_drv_type);
+	mmc_host_clk_release(card->host);
 
 	err = mmc_sd_switch(card, 1, 2, drive_strength, status);
 	if (err)
@@ -660,9 +662,12 @@
 		goto out;
 
 	/* SPI mode doesn't define CMD19 */
-	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
+	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) {
+		mmc_host_clk_hold(card->host);
 		err = card->host->ops->execute_tuning(card->host,
 						      MMC_SEND_TUNING_BLOCK);
+		mmc_host_clk_release(card->host);
+	}
 
 out:
 	kfree(status);
@@ -850,8 +855,11 @@
 	if (!reinit) {
 		int ro = -1;
 
-		if (host->ops->get_ro)
+		if (host->ops->get_ro) {
+			mmc_host_clk_hold(card->host);
 			ro = host->ops->get_ro(host);
+			mmc_host_clk_release(card->host);
+		}
 
 		if (ro < 0) {
 			pr_warning("%s: host does not "
@@ -967,8 +975,11 @@
 		 * Since initialization is now complete, enable preset
 		 * value registers for UHS-I cards.
 		 */
-		if (host->ops->enable_preset_value)
+		if (host->ops->enable_preset_value) {
+			mmc_host_clk_hold(card->host);
 			host->ops->enable_preset_value(host, true);
+			mmc_host_clk_release(card->host);
+		}
 	} else {
 		/*
 		 * Attempt to change to high-speed (if supported)
@@ -1151,8 +1162,11 @@
 		return err;
 
 	/* Disable preset value enable if already set since last time */
-	if (host->ops->enable_preset_value)
+	if (host->ops->enable_preset_value) {
+		mmc_host_clk_hold(host);
 		host->ops->enable_preset_value(host, false);
+		mmc_host_clk_release(host);
+	}
 
 	err = mmc_send_app_op_cond(host, 0, &ocr);
 	if (err)
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index bd7bacc..12cde6e 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -98,10 +98,11 @@
 	return ret;
 }
 
-static int sdio_read_cccr(struct mmc_card *card)
+static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
 {
 	int ret;
 	int cccr_vsn;
+	int uhs = ocr & R4_18V_PRESENT;
 	unsigned char data;
 	unsigned char speed;
 
@@ -149,7 +150,7 @@
 		card->scr.sda_spec3 = 0;
 		card->sw_caps.sd3_bus_mode = 0;
 		card->sw_caps.sd3_drv_type = 0;
-		if (cccr_vsn >= SDIO_CCCR_REV_3_00) {
+		if (cccr_vsn >= SDIO_CCCR_REV_3_00 && uhs) {
 			card->scr.sda_spec3 = 1;
 			ret = mmc_io_rw_direct(card, 0, 0,
 				SDIO_CCCR_UHS, 0, &data);
@@ -712,7 +713,7 @@
 	/*
 	 * Read the common registers.
 	 */
-	err = sdio_read_cccr(card);
+	err = sdio_read_cccr(card, ocr);
 	if (err)
 		goto remove;
 
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index 68f81b9..f573e7f 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -146,15 +146,21 @@
 		}
 
 		set_current_state(TASK_INTERRUPTIBLE);
-		if (host->caps & MMC_CAP_SDIO_IRQ)
+		if (host->caps & MMC_CAP_SDIO_IRQ) {
+			mmc_host_clk_hold(host);
 			host->ops->enable_sdio_irq(host, 1);
+			mmc_host_clk_release(host);
+		}
 		if (!kthread_should_stop())
 			schedule_timeout(period);
 		set_current_state(TASK_RUNNING);
 	} while (!kthread_should_stop());
 
-	if (host->caps & MMC_CAP_SDIO_IRQ)
+	if (host->caps & MMC_CAP_SDIO_IRQ) {
+		mmc_host_clk_hold(host);
 		host->ops->enable_sdio_irq(host, 0);
+		mmc_host_clk_release(host);
+	}
 
 	pr_debug("%s: IRQ thread exiting with code %d\n",
 		 mmc_hostname(host), ret);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index cf444b0..00fcbed 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -477,7 +477,6 @@
 config MMC_CB710
 	tristate "ENE CB710 MMC/SD Interface support"
 	depends on PCI
-	select MISC_DEVICES
 	select CB710_CORE
 	help
 	  This option enables support for MMC/SD part of ENE CB710/720 Flash
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index fcfe1eb..6985cdb 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -969,11 +969,14 @@
 	host->data_status = 0;
 
 	if (host->need_reset) {
+		iflags = atmci_readl(host, ATMCI_IMR);
+		iflags &= (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB);
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
 		atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
 		atmci_writel(host, ATMCI_MR, host->mode_reg);
 		if (host->caps.has_cfg_reg)
 			atmci_writel(host, ATMCI_CFG, host->cfg_reg);
+		atmci_writel(host, ATMCI_IER, iflags);
 		host->need_reset = false;
 	}
 	atmci_writel(host, ATMCI_SDCR, slot->sdc_reg);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0e34279..8bec1c3 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -22,7 +22,6 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/scatterlist.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
@@ -502,8 +501,14 @@
 		host->dir_status = DW_MCI_SEND_STATUS;
 
 	if (dw_mci_submit_data_dma(host, data)) {
+		int flags = SG_MITER_ATOMIC;
+		if (host->data->flags & MMC_DATA_READ)
+			flags |= SG_MITER_TO_SG;
+		else
+			flags |= SG_MITER_FROM_SG;
+
+		sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
 		host->sg = data->sg;
-		host->pio_offset = 0;
 		host->part_buf_start = 0;
 		host->part_buf_count = 0;
 
@@ -972,6 +977,7 @@
 				 * generates a block interrupt, hence setting
 				 * the scatter-gather pointer to NULL.
 				 */
+				sg_miter_stop(&host->sg_miter);
 				host->sg = NULL;
 				ctrl = mci_readl(host, CTRL);
 				ctrl |= SDMMC_CTRL_FIFO_RESET;
@@ -1311,54 +1317,44 @@
 
 static void dw_mci_read_data_pio(struct dw_mci *host)
 {
-	struct scatterlist *sg = host->sg;
-	void *buf = sg_virt(sg);
-	unsigned int offset = host->pio_offset;
+	struct sg_mapping_iter *sg_miter = &host->sg_miter;
+	void *buf;
+	unsigned int offset;
 	struct mmc_data	*data = host->data;
 	int shift = host->data_shift;
 	u32 status;
 	unsigned int nbytes = 0, len;
+	unsigned int remain, fcnt;
 
 	do {
-		len = host->part_buf_count +
-			(SDMMC_GET_FCNT(mci_readl(host, STATUS)) << shift);
-		if (offset + len <= sg->length) {
-			dw_mci_pull_data(host, (void *)(buf + offset), len);
+		if (!sg_miter_next(sg_miter))
+			goto done;
 
+		host->sg = sg_miter->__sg;
+		buf = sg_miter->addr;
+		remain = sg_miter->length;
+		offset = 0;
+
+		do {
+			fcnt = (SDMMC_GET_FCNT(mci_readl(host, STATUS))
+					<< shift) + host->part_buf_count;
+			len = min(remain, fcnt);
+			if (!len)
+				break;
+			dw_mci_pull_data(host, (void *)(buf + offset), len);
 			offset += len;
 			nbytes += len;
-
-			if (offset == sg->length) {
-				flush_dcache_page(sg_page(sg));
-				host->sg = sg = sg_next(sg);
-				if (!sg)
-					goto done;
-
-				offset = 0;
-				buf = sg_virt(sg);
-			}
-		} else {
-			unsigned int remaining = sg->length - offset;
-			dw_mci_pull_data(host, (void *)(buf + offset),
-					 remaining);
-			nbytes += remaining;
-
-			flush_dcache_page(sg_page(sg));
-			host->sg = sg = sg_next(sg);
-			if (!sg)
-				goto done;
-
-			offset = len - remaining;
-			buf = sg_virt(sg);
-			dw_mci_pull_data(host, buf, offset);
-			nbytes += offset;
-		}
+			remain -= len;
+		} while (remain);
+		sg_miter->consumed = offset;
 
 		status = mci_readl(host, MINTSTS);
 		mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
 		if (status & DW_MCI_DATA_ERROR_FLAGS) {
 			host->data_status = status;
 			data->bytes_xfered += nbytes;
+			sg_miter_stop(sg_miter);
+			host->sg = NULL;
 			smp_wmb();
 
 			set_bit(EVENT_DATA_ERROR, &host->pending_events);
@@ -1367,65 +1363,66 @@
 			return;
 		}
 	} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
-	host->pio_offset = offset;
 	data->bytes_xfered += nbytes;
+
+	if (!remain) {
+		if (!sg_miter_next(sg_miter))
+			goto done;
+		sg_miter->consumed = 0;
+	}
+	sg_miter_stop(sg_miter);
 	return;
 
 done:
 	data->bytes_xfered += nbytes;
+	sg_miter_stop(sg_miter);
+	host->sg = NULL;
 	smp_wmb();
 	set_bit(EVENT_XFER_COMPLETE, &host->pending_events);
 }
 
 static void dw_mci_write_data_pio(struct dw_mci *host)
 {
-	struct scatterlist *sg = host->sg;
-	void *buf = sg_virt(sg);
-	unsigned int offset = host->pio_offset;
+	struct sg_mapping_iter *sg_miter = &host->sg_miter;
+	void *buf;
+	unsigned int offset;
 	struct mmc_data	*data = host->data;
 	int shift = host->data_shift;
 	u32 status;
 	unsigned int nbytes = 0, len;
+	unsigned int fifo_depth = host->fifo_depth;
+	unsigned int remain, fcnt;
 
 	do {
-		len = ((host->fifo_depth -
-			SDMMC_GET_FCNT(mci_readl(host, STATUS))) << shift)
-			- host->part_buf_count;
-		if (offset + len <= sg->length) {
-			host->push_data(host, (void *)(buf + offset), len);
+		if (!sg_miter_next(sg_miter))
+			goto done;
 
+		host->sg = sg_miter->__sg;
+		buf = sg_miter->addr;
+		remain = sg_miter->length;
+		offset = 0;
+
+		do {
+			fcnt = ((fifo_depth -
+				 SDMMC_GET_FCNT(mci_readl(host, STATUS)))
+					<< shift) - host->part_buf_count;
+			len = min(remain, fcnt);
+			if (!len)
+				break;
+			host->push_data(host, (void *)(buf + offset), len);
 			offset += len;
 			nbytes += len;
-			if (offset == sg->length) {
-				host->sg = sg = sg_next(sg);
-				if (!sg)
-					goto done;
-
-				offset = 0;
-				buf = sg_virt(sg);
-			}
-		} else {
-			unsigned int remaining = sg->length - offset;
-
-			host->push_data(host, (void *)(buf + offset),
-					remaining);
-			nbytes += remaining;
-
-			host->sg = sg = sg_next(sg);
-			if (!sg)
-				goto done;
-
-			offset = len - remaining;
-			buf = sg_virt(sg);
-			host->push_data(host, (void *)buf, offset);
-			nbytes += offset;
-		}
+			remain -= len;
+		} while (remain);
+		sg_miter->consumed = offset;
 
 		status = mci_readl(host, MINTSTS);
 		mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
 		if (status & DW_MCI_DATA_ERROR_FLAGS) {
 			host->data_status = status;
 			data->bytes_xfered += nbytes;
+			sg_miter_stop(sg_miter);
+			host->sg = NULL;
 
 			smp_wmb();
 
@@ -1435,12 +1432,20 @@
 			return;
 		}
 	} while (status & SDMMC_INT_TXDR); /* if TXDR write again */
-	host->pio_offset = offset;
 	data->bytes_xfered += nbytes;
+
+	if (!remain) {
+		if (!sg_miter_next(sg_miter))
+			goto done;
+		sg_miter->consumed = 0;
+	}
+	sg_miter_stop(sg_miter);
 	return;
 
 done:
 	data->bytes_xfered += nbytes;
+	sg_miter_stop(sg_miter);
+	host->sg = NULL;
 	smp_wmb();
 	set_bit(EVENT_XFER_COMPLETE, &host->pending_events);
 }
@@ -1643,6 +1648,7 @@
 				 * block interrupt, hence setting the
 				 * scatter-gather pointer to NULL.
 				 */
+				sg_miter_stop(&host->sg_miter);
 				host->sg = NULL;
 
 				ctrl = mci_readl(host, CTRL);
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index ab66f24..1534b58 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -113,8 +113,8 @@
 		const int j = i * 2;
 		u32 mask;
 
-		mask = mmc_vddrange_to_ocrmask(voltage_ranges[j],
-					       voltage_ranges[j + 1]);
+		mask = mmc_vddrange_to_ocrmask(be32_to_cpu(voltage_ranges[j]),
+					       be32_to_cpu(voltage_ranges[j + 1]));
 		if (!mask) {
 			ret = -EINVAL;
 			dev_err(dev, "OF: voltage-range #%d is invalid\n", i);
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index ff4adc0..5d876ff 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -38,6 +38,23 @@
 	int base = reg & ~0x3;
 	int shift = (reg & 0x3) * 8;
 	u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff;
+
+	/*
+	 * "DMA select" locates at offset 0x28 in SD specification, but on
+	 * P5020 or P3041, it locates at 0x29.
+	 */
+	if (reg == SDHCI_HOST_CONTROL) {
+		u32 dma_bits;
+
+		dma_bits = in_be32(host->ioaddr + reg);
+		/* DMA select is 22,23 bits in Protocol Control Register */
+		dma_bits = (dma_bits >> 5) & SDHCI_CTRL_DMA_MASK;
+
+		/* fixup the result */
+		ret &= ~SDHCI_CTRL_DMA_MASK;
+		ret |= dma_bits;
+	}
+
 	return ret;
 }
 
@@ -56,6 +73,21 @@
 
 static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
 {
+	/*
+	 * "DMA select" location is offset 0x28 in SD specification, but on
+	 * P5020 or P3041, it's located at 0x29.
+	 */
+	if (reg == SDHCI_HOST_CONTROL) {
+		u32 dma_bits;
+
+		/* DMA select is 22,23 bits in Protocol Control Register */
+		dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5;
+		clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5,
+			dma_bits);
+		val &= ~SDHCI_CTRL_DMA_MASK;
+		val |= in_be32(host->ioaddr + reg) & SDHCI_CTRL_DMA_MASK;
+	}
+
 	/* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
 	if (reg == SDHCI_HOST_CONTROL)
 		val &= ~ESDHC_HOST_CONTROL_RES;
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 7165e6a..6ebdc40 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -250,7 +250,7 @@
 
 static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
-	slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD;
+	slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
 	return 0;
 }
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 03970bc..c5c2a48 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -2,7 +2,7 @@
  * sdhci-pltfm.c Support for SDHCI platform devices
  * Copyright (c) 2009 Intel Corporation
  *
- * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2007, 2011 Freescale Semiconductor, Inc.
  * Copyright (c) 2009 MontaVista Software, Inc.
  *
  * Authors: Xiaobo Xie <X.Xie@freescale.com>
@@ -71,6 +71,14 @@
 		if (sdhci_of_wp_inverted(np))
 			host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
 
+		if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
+			host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
+
+		if (of_device_is_compatible(np, "fsl,p2020-esdhc") ||
+		    of_device_is_compatible(np, "fsl,p1010-esdhc") ||
+		    of_device_is_compatible(np, "fsl,mpc8536-esdhc"))
+			host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+
 		clk = of_get_property(np, "clock-frequency", &size);
 		if (clk && size == sizeof(*clk) && *clk)
 			pltfm_host->clock = be32_to_cpup(clk);
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index f5d8b53..352d479 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1327,7 +1327,7 @@
 	if (ret < 0)
 		goto clean_up2;
 
-	mmc_add_host(mmc);
+	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
 
 	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
 
@@ -1338,22 +1338,24 @@
 	}
 	ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
 	if (ret) {
-		free_irq(irq[0], host);
 		dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
-		goto clean_up3;
+		goto clean_up4;
 	}
 
-	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
-
-	mmc_detect_change(host->mmc, 0);
+	ret = mmc_add_host(mmc);
+	if (ret < 0)
+		goto clean_up5;
 
 	dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
 	dev_dbg(&pdev->dev, "chip ver H'%04x\n",
 		sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
 	return ret;
 
+clean_up5:
+	free_irq(irq[1], host);
+clean_up4:
+	free_irq(irq[0], host);
 clean_up3:
-	mmc_remove_host(mmc);
 	pm_runtime_suspend(&pdev->dev);
 clean_up2:
 	pm_runtime_disable(&pdev->dev);
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index a95e6d9..f96c536 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -20,8 +20,8 @@
 #include <linux/mmc/tmio.h>
 #include <linux/mutex.h>
 #include <linux/pagemap.h>
-#include <linux/spinlock.h>
 #include <linux/scatterlist.h>
+#include <linux/spinlock.h>
 
 /* Definitions for values the CTRL_SDIO_STATUS register can take. */
 #define TMIO_SDIO_STAT_IOIRQ	0x0001
@@ -120,6 +120,7 @@
 void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable);
 void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata);
 void tmio_mmc_release_dma(struct tmio_mmc_host *host);
+void tmio_mmc_abort_dma(struct tmio_mmc_host *host);
 #else
 static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host,
 			       struct mmc_data *data)
@@ -140,6 +141,10 @@
 static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host)
 {
 }
+
+static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
+{
+}
 #endif
 
 #ifdef CONFIG_PM
diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
index 7a6e6cc..8253ec1 100644
--- a/drivers/mmc/host/tmio_mmc_dma.c
+++ b/drivers/mmc/host/tmio_mmc_dma.c
@@ -34,6 +34,18 @@
 #endif
 }
 
+void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
+{
+	tmio_mmc_enable_dma(host, false);
+
+	if (host->chan_rx)
+		dmaengine_terminate_all(host->chan_rx);
+	if (host->chan_tx)
+		dmaengine_terminate_all(host->chan_tx);
+
+	tmio_mmc_enable_dma(host, true);
+}
+
 static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
 {
 	struct scatterlist *sg = host->sg_ptr, *sg_tmp;
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index abad01b..5f9ad74 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -41,8 +41,8 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
-#include <linux/workqueue.h>
 #include <linux/spinlock.h>
+#include <linux/workqueue.h>
 
 #include "tmio_mmc.h"
 
@@ -246,6 +246,7 @@
 	/* Ready for new calls */
 	host->mrq = NULL;
 
+	tmio_mmc_abort_dma(host);
 	mmc_request_done(host->mmc, mrq);
 }
 
@@ -272,6 +273,9 @@
 	host->mrq = NULL;
 	spin_unlock_irqrestore(&host->lock, flags);
 
+	if (mrq->cmd->error || (mrq->data && mrq->data->error))
+		tmio_mmc_abort_dma(host);
+
 	mmc_request_done(host->mmc, mrq);
 }
 
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index 7668967..c30f0e6 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -440,12 +440,14 @@
 	for (i = 0; i < dlc; i++)
 		cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
 
+	/* Store echo skb before starting the transfer */
+	can_put_echo_skb(skb, dev, 0);
+
 	cc770_write_reg(priv, msgobj[mo].ctrl1,
 			RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
 
 	stats->tx_bytes += dlc;
 
-	can_put_echo_skb(skb, dev, 0);
 
 	/*
 	 * HM: We had some cases of repeated IRQs so make sure the
diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
index 4be5fe2..9f3a25c 100644
--- a/drivers/net/can/cc770/cc770_isa.c
+++ b/drivers/net/can/cc770/cc770_isa.c
@@ -110,6 +110,11 @@
 #define CC770_IOSIZE          0x20
 #define CC770_IOSIZE_INDIRECT 0x02
 
+/* Spinlock for cc770_isa_port_write_reg_indirect
+ * and cc770_isa_port_read_reg_indirect
+ */
+static DEFINE_SPINLOCK(cc770_isa_port_lock);
+
 static struct platform_device *cc770_isa_devs[MAXDEV];
 
 static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
@@ -138,18 +143,27 @@
 					     int reg)
 {
 	unsigned long base = (unsigned long)priv->reg_base;
+	unsigned long flags;
+	u8 val;
 
+	spin_lock_irqsave(&cc770_isa_port_lock, flags);
 	outb(reg, base);
-	return inb(base + 1);
+	val = inb(base + 1);
+	spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
+
+	return val;
 }
 
 static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
 						int reg, u8 val)
 {
 	unsigned long base = (unsigned long)priv->reg_base;
+	unsigned long flags;
 
+	spin_lock_irqsave(&cc770_isa_port_lock, flags);
 	outb(reg, base);
 	outb(val, base + 1);
+	spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
 }
 
 static int __devinit cc770_isa_probe(struct platform_device *pdev)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 7fd8089..96d2357 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -118,6 +118,9 @@
 	(FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT)
 #define FLEXCAN_ESR_ERR_ALL \
 	(FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE)
+#define FLEXCAN_ESR_ALL_INT \
+	(FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \
+	 FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
 
 /* FLEXCAN interrupt flag register (IFLAG) bits */
 #define FLEXCAN_TX_BUF_ID		8
@@ -577,7 +580,9 @@
 
 	reg_iflag1 = flexcan_read(&regs->iflag1);
 	reg_esr = flexcan_read(&regs->esr);
-	flexcan_write(FLEXCAN_ESR_ERR_INT, &regs->esr);	/* ACK err IRQ */
+	/* ACK all bus error and state change IRQ sources */
+	if (reg_esr & FLEXCAN_ESR_ALL_INT)
+		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
 
 	/*
 	 * schedule NAPI in case of:
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index d11fbb2..6edc25e 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -66,6 +66,7 @@
 #define PCH_IF_CREQ_BUSY	BIT(15)
 
 #define PCH_STATUS_INT		0x8000
+#define PCH_RP			0x00008000
 #define PCH_REC			0x00007f00
 #define PCH_TEC			0x000000ff
 
@@ -527,7 +528,7 @@
 		priv->can.can_stats.error_passive++;
 		state = CAN_STATE_ERROR_PASSIVE;
 		cf->can_id |= CAN_ERR_CRTL;
-		if (((errc & PCH_REC) >> 8) > 127)
+		if (errc & PCH_RP)
 			cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
 		if ((errc & PCH_TEC) > 127)
 			cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c
index 2c7f503..2147959 100644
--- a/drivers/net/can/sja1000/peak_pci.c
+++ b/drivers/net/can/sja1000/peak_pci.c
@@ -39,9 +39,9 @@
 #define DRV_NAME  "peak_pci"
 
 struct peak_pci_chan {
-	void __iomem *cfg_base;	     /* Common for all channels */
-	struct net_device *next_dev; /* Chain of network devices */
-	u16 icr_mask;		     /* Interrupt mask for fast ack */
+	void __iomem *cfg_base;		/* Common for all channels */
+	struct net_device *prev_dev;	/* Chain of network devices */
+	u16 icr_mask;			/* Interrupt mask for fast ack */
 };
 
 #define PEAK_PCI_CAN_CLOCK	(16000000 / 2)
@@ -98,7 +98,7 @@
 {
 	struct sja1000_priv *priv;
 	struct peak_pci_chan *chan;
-	struct net_device *dev, *dev0 = NULL;
+	struct net_device *dev;
 	void __iomem *cfg_base, *reg_base;
 	u16 sub_sys_id, icr;
 	int i, err, channels;
@@ -196,18 +196,14 @@
 		}
 
 		/* Create chain of SJA1000 devices */
-		if (i == 0)
-			dev0 = dev;
-		else
-			chan->next_dev = dev;
+		chan->prev_dev = pci_get_drvdata(pdev);
+		pci_set_drvdata(pdev, dev);
 
 		dev_info(&pdev->dev,
 			 "%s at reg_base=0x%p cfg_base=0x%p irq=%d\n",
 			 dev->name, priv->reg_base, chan->cfg_base, dev->irq);
 	}
 
-	pci_set_drvdata(pdev, dev0);
-
 	/* Enable interrupts */
 	writew(icr, cfg_base + PITA_ICR + 2);
 
@@ -217,12 +213,11 @@
 	/* Disable interrupts */
 	writew(0x0, cfg_base + PITA_ICR + 2);
 
-	for (dev = dev0; dev; dev = chan->next_dev) {
+	for (dev = pci_get_drvdata(pdev); dev; dev = chan->prev_dev) {
 		unregister_sja1000dev(dev);
 		free_sja1000dev(dev);
 		priv = netdev_priv(dev);
 		chan = priv->priv;
-		dev = chan->next_dev;
 	}
 
 	pci_iounmap(pdev, reg_base);
@@ -241,7 +236,7 @@
 
 static void __devexit peak_pci_remove(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev); /* First device */
+	struct net_device *dev = pci_get_drvdata(pdev); /* Last device */
 	struct sja1000_priv *priv = netdev_priv(dev);
 	struct peak_pci_chan *chan = priv->priv;
 	void __iomem *cfg_base = chan->cfg_base;
@@ -255,7 +250,7 @@
 		dev_info(&pdev->dev, "removing device %s\n", dev->name);
 		unregister_sja1000dev(dev);
 		free_sja1000dev(dev);
-		dev = chan->next_dev;
+		dev = chan->prev_dev;
 		if (!dev)
 			break;
 		priv = netdev_priv(dev);
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 04a3f1b..192b0d1 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -95,11 +95,16 @@
 	spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
 }
 
+static int sja1000_is_absent(struct sja1000_priv *priv)
+{
+	return (priv->read_reg(priv, REG_MOD) == 0xFF);
+}
+
 static int sja1000_probe_chip(struct net_device *dev)
 {
 	struct sja1000_priv *priv = netdev_priv(dev);
 
-	if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
+	if (priv->reg_base && sja1000_is_absent(priv)) {
 		printk(KERN_INFO "%s: probing @0x%lX failed\n",
 		       DRV_NAME, dev->base_addr);
 		return 0;
@@ -493,6 +498,9 @@
 	while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
 		n++;
 		status = priv->read_reg(priv, REG_SR);
+		/* check for absent controller due to hw unplug */
+		if (status == 0xFF && sja1000_is_absent(priv))
+			return IRQ_NONE;
 
 		if (isrc & IRQ_WUI)
 			dev_warn(dev->dev.parent, "wakeup interrupt\n");
@@ -509,6 +517,9 @@
 			while (status & SR_RBS) {
 				sja1000_rx(dev);
 				status = priv->read_reg(priv, REG_SR);
+				/* check for absent controller */
+				if (status == 0xFF && sja1000_is_absent(priv))
+					return IRQ_NONE;
 			}
 		}
 		if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index df809e3..5a2e1e3 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -745,9 +745,10 @@
 		}
 	}
 
-	netif_receive_skb(skb);
+	netif_rx(skb);
 	stats->rx_packets++;
 	stats->rx_bytes += cf->can_dlc;
+
 	return 0;
 }
 
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 9697c14..7dae64d 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -627,9 +627,6 @@
 
 		err = usb_submit_urb(urb, GFP_KERNEL);
 		if (err) {
-			if (err == -ENODEV)
-				netif_device_detach(dev->netdev);
-
 			usb_unanchor_urb(urb);
 			usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
 					  urb->transfer_dma);
@@ -659,9 +656,6 @@
 
 	err = usb_submit_urb(dev->intr_urb, GFP_KERNEL);
 	if (err) {
-		if (err == -ENODEV)
-			netif_device_detach(dev->netdev);
-
 		dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n",
 			 err);
 
@@ -692,9 +686,6 @@
 	return 0;
 
 failed:
-	if (err == -ENODEV)
-		netif_device_detach(dev->netdev);
-
 	dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err);
 
 	return err;
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 8153a3e..f9b74c0 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -1842,7 +1842,7 @@
 		ok = 1;
 	}
 
-	if (!netif_carrier_ok(dev))
+	if (dev->flags & IFF_SLAVE || !netif_carrier_ok(dev))
 		next_tick = 5*HZ;
 
 	if (vp->medialock)
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index b859124..1ff3c6d 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2244,10 +2244,6 @@
 			dev_info(&adapter->pdev->dev, "tx locked\n");
 		return NETDEV_TX_LOCKED;
 	}
-	if (skb->mark == 0x01)
-		type = atl1c_trans_high;
-	else
-		type = atl1c_trans_normal;
 
 	if (atl1c_tpd_avail(adapter, type) < tpd_req) {
 		/* no enough descriptor, just stop queue */
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 3fb66d0..cab8745 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2339,7 +2339,7 @@
 	return err;
 }
 
-static inline void __exit b44_pci_exit(void)
+static inline void b44_pci_exit(void)
 {
 #ifdef CONFIG_B44_PCI
 	ssb_pcihost_unregister(&b44_pci_driver);
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index 986019b2..c7ca7ec 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -797,7 +797,7 @@
 	if (priv->has_phy) {
 		/* connect to PHY */
 		snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
-			 priv->mac_id ? "1" : "0", priv->phy_id);
+			 priv->mii_bus->id, priv->phy_id);
 
 		phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0,
 				     PHY_INTERFACE_MODE_MII);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 03f3935..7aee469 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -523,7 +523,6 @@
 		skb = build_skb(data);
 
 	if (likely(skb)) {
-
 #ifdef BNX2X_STOP_ON_ERROR
 		if (pad + len > fp->rx_buf_size) {
 			BNX2X_ERR("skb_put is about to fail...  "
@@ -557,7 +556,7 @@
 
 		return;
 	}
-
+	kfree(new_data);
 drop:
 	/* drop the packet and keep the buffer in the bin */
 	DP(NETIF_MSG_RX_STATUS,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 1e3f978..2545213 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -117,10 +117,6 @@
 module_param(dropless_fc, int, 0);
 MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring");
 
-static int poll;
-module_param(poll, int, 0);
-MODULE_PARM_DESC(poll, " Use polling (for debug)");
-
 static int mrrs = -1;
 module_param(mrrs, int, 0);
 MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)");
@@ -4834,20 +4830,11 @@
 
 static void bnx2x_timer(unsigned long data)
 {
-	u8 cos;
 	struct bnx2x *bp = (struct bnx2x *) data;
 
 	if (!netif_running(bp->dev))
 		return;
 
-	if (poll) {
-		struct bnx2x_fastpath *fp = &bp->fp[0];
-
-		for_each_cos_in_tx_queue(fp, cos)
-			bnx2x_tx_int(bp, &fp->txdata[cos]);
-		bnx2x_rx_int(fp, 1000);
-	}
-
 	if (!BP_NOMCP(bp)) {
 		int mb_idx = BP_FW_MB_IDX(bp);
 		u32 drv_pulse;
@@ -10063,7 +10050,6 @@
 static int __devinit bnx2x_init_bp(struct bnx2x *bp)
 {
 	int func;
-	int timer_interval;
 	int rc;
 
 	mutex_init(&bp->port.phy_mutex);
@@ -10139,8 +10125,7 @@
 	bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR;
 	bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR;
 
-	timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
-	bp->current_interval = (poll ? poll : timer_interval);
+	bp->current_interval = CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ;
 
 	init_timer(&bp->timer);
 	bp->timer.expires = jiffies + bp->current_interval;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index bc0121a..1adef26 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -1081,17 +1081,17 @@
 	       estats->rx_stat_ifhcinbadoctets_lo);
 
 	ADD_64(fstats->total_bytes_received_hi,
-	       tfunc->rcv_error_bytes.hi,
+	       le32_to_cpu(tfunc->rcv_error_bytes.hi),
 	       fstats->total_bytes_received_lo,
-	       tfunc->rcv_error_bytes.lo);
+	       le32_to_cpu(tfunc->rcv_error_bytes.lo));
 
 	memcpy(estats, &(fstats->total_bytes_received_hi),
 	       sizeof(struct host_func_stats) - 2*sizeof(u32));
 
 	ADD_64(estats->error_bytes_received_hi,
-	       tfunc->rcv_error_bytes.hi,
+	       le32_to_cpu(tfunc->rcv_error_bytes.hi),
 	       estats->error_bytes_received_lo,
-	       tfunc->rcv_error_bytes.lo);
+	       le32_to_cpu(tfunc->rcv_error_bytes.lo));
 
 	ADD_64(estats->etherstatsoverrsizepkts_hi,
 	       estats->rx_stat_dot3statsframestoolong_hi,
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index dd3a0a2..818a573 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -3584,7 +3584,11 @@
 		fl6.flowi6_oif = dst_addr->sin6_scope_id;
 
 	*dst = ip6_route_output(&init_net, NULL, &fl6);
-	if (*dst)
+	if ((*dst)->error) {
+		dst_release(*dst);
+		*dst = NULL;
+		return -ENETUNREACH;
+	} else
 		return 0;
 #endif
 
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index 9b44ec8..803ea32 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -946,7 +946,7 @@
 
 	flash_attr = kzalloc(sizeof(struct bfa_flash_attr), GFP_KERNEL);
 	if (!flash_attr)
-		return -ENOMEM;
+		return 0;
 
 	fcomp.bnad = bnad;
 	fcomp.comp_status = 0;
@@ -958,7 +958,7 @@
 	if (ret != BFA_STATUS_OK) {
 		spin_unlock_irqrestore(&bnad->bna_lock, flags);
 		kfree(flash_attr);
-		goto out_err;
+		return 0;
 	}
 	spin_unlock_irqrestore(&bnad->bna_lock, flags);
 	wait_for_completion(&fcomp.comp);
@@ -978,8 +978,6 @@
 	}
 	kfree(flash_attr);
 	return flash_part;
-out_err:
-	return -EINVAL;
 }
 
 static int
@@ -1006,7 +1004,7 @@
 	/* Query the flash partition based on the offset */
 	flash_part = bnad_get_flash_partition_by_offset(bnad,
 				eeprom->offset, &base_offset);
-	if (flash_part <= 0)
+	if (flash_part == 0)
 		return -EFAULT;
 
 	fcomp.bnad = bnad;
@@ -1048,7 +1046,7 @@
 	/* Query the flash partition based on the offset */
 	flash_part = bnad_get_flash_partition_by_offset(bnad,
 				eeprom->offset, &base_offset);
-	if (flash_part <= 0)
+	if (flash_part == 0)
 		return -EFAULT;
 
 	fcomp.bnad = bnad;
diff --git a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
index c2c0680..ac37cac 100644
--- a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
+++ b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
@@ -157,7 +157,7 @@
 			CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0;
 		*fcoe_enc_error = (desc->flags &
 			CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0;
-		*fcoe_eof = (u8)((desc->checksum_fcoe >>
+		*fcoe_eof = (u8)((le16_to_cpu(desc->checksum_fcoe) >>
 			CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) &
 			CQ_ENET_RQ_DESC_FCOE_EOF_MASK);
 		*checksum = 0;
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
index 22bf03a..c347b62 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.c
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -72,7 +72,7 @@
 	struct enic_port_profile *pp;
 	struct vic_provinfo *vp;
 	const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
-	const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
+	const __be16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
 	char uuid_str[38];
 	char client_mac_str[18];
 	u8 *client_mac;
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 6db6b6a..802e5dd 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -716,12 +716,8 @@
 be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	char file_name[ETHTOOL_FLASH_MAX_FILENAME];
 
-	file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
-	strcpy(file_name, efl->data);
-
-	return be_load_fw(adapter, file_name);
+	return be_load_fw(adapter, efl->data);
 }
 
 static int
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 7b25e9c..e92ef1b 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -986,11 +986,11 @@
 		printk(KERN_INFO
 			"%s: no PHY, assuming direct connection to switch\n",
 			ndev->name);
-		strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE);
+		strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE);
 		phy_id = 0;
 	}
 
-	snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
+	snprintf(phy_name, sizeof(phy_name), PHY_ID_FMT, mdio_bus_id, phy_id);
 	phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0,
 			      fep->phy_interface);
 	if (IS_ERR(phy_dev)) {
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 669ca38..d94d64b 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -4740,12 +4740,14 @@
 		e1000_setup_rctl(adapter);
 		e1000_set_rx_mode(netdev);
 
+		rctl = er32(RCTL);
+
 		/* turn on all-multi mode if wake on multicast is enabled */
-		if (wufc & E1000_WUFC_MC) {
-			rctl = er32(RCTL);
+		if (wufc & E1000_WUFC_MC)
 			rctl |= E1000_RCTL_MPE;
-			ew32(RCTL, rctl);
-		}
+
+		/* enable receives in the hardware */
+		ew32(RCTL, rctl | E1000_RCTL_EN);
 
 		if (hw->mac_type >= e1000_82540) {
 			ctrl = er32(CTRL);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index e91d73c..94be6c3 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -5012,7 +5012,8 @@
 	vf_devfn = pdev->devfn + 0x80;
 	pvfdev = pci_get_device(hw->vendor_id, device_id, NULL);
 	while (pvfdev) {
-		if (pvfdev->devfn == vf_devfn)
+		if (pvfdev->devfn == vf_devfn &&
+		    (pvfdev->bus->number >= pdev->bus->number))
 			vfs_found++;
 		vf_devfn += vf_stride;
 		pvfdev = pci_get_device(hw->vendor_id,
diff --git a/drivers/net/ethernet/intel/igbvf/Makefile b/drivers/net/ethernet/intel/igbvf/Makefile
index 0fa3db3..044b0ad 100644
--- a/drivers/net/ethernet/intel/igbvf/Makefile
+++ b/drivers/net/ethernet/intel/igbvf/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel(R) 82576 Virtual Function Linux driver
-# Copyright(c) 2009 - 2010 Intel Corporation.
+# Copyright(c) 2009 - 2012 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igbvf/defines.h b/drivers/net/ethernet/intel/igbvf/defines.h
index 79f2604..33f40d3 100644
--- a/drivers/net/ethernet/intel/igbvf/defines.h
+++ b/drivers/net/ethernet/intel/igbvf/defines.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c
index 2dba534..db7dce2 100644
--- a/drivers/net/ethernet/intel/igbvf/ethtool.c
+++ b/drivers/net/ethernet/intel/igbvf/ethtool.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igbvf/igbvf.h b/drivers/net/ethernet/intel/igbvf/igbvf.h
index fd4a7b7..2c6d87e 100644
--- a/drivers/net/ethernet/intel/igbvf/igbvf.h
+++ b/drivers/net/ethernet/intel/igbvf/igbvf.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igbvf/mbx.c b/drivers/net/ethernet/intel/igbvf/mbx.c
index 048aae2..b4b65bc 100644
--- a/drivers/net/ethernet/intel/igbvf/mbx.c
+++ b/drivers/net/ethernet/intel/igbvf/mbx.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igbvf/mbx.h b/drivers/net/ethernet/intel/igbvf/mbx.h
index c2883c4..24370bc 100644
--- a/drivers/net/ethernet/intel/igbvf/mbx.h
+++ b/drivers/net/ethernet/intel/igbvf/mbx.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index a4b20c8..4e9141c 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -53,7 +53,7 @@
 static const char igbvf_driver_string[] =
 		  "Intel(R) Gigabit Virtual Function Network Driver";
 static const char igbvf_copyright[] =
-		  "Copyright (c) 2009 - 2011 Intel Corporation.";
+		  "Copyright (c) 2009 - 2012 Intel Corporation.";
 
 static int igbvf_poll(struct napi_struct *napi, int budget);
 static void igbvf_reset(struct igbvf_adapter *);
diff --git a/drivers/net/ethernet/intel/igbvf/regs.h b/drivers/net/ethernet/intel/igbvf/regs.h
index 77e18d3..7dc6341 100644
--- a/drivers/net/ethernet/intel/igbvf/regs.h
+++ b/drivers/net/ethernet/intel/igbvf/regs.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igbvf/vf.c b/drivers/net/ethernet/intel/igbvf/vf.c
index af3822f..1955197 100644
--- a/drivers/net/ethernet/intel/igbvf/vf.c
+++ b/drivers/net/ethernet/intel/igbvf/vf.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/igbvf/vf.h b/drivers/net/ethernet/intel/igbvf/vf.h
index d7ed58f..57db3c6 100644
--- a/drivers/net/ethernet/intel/igbvf/vf.h
+++ b/drivers/net/ethernet/intel/igbvf/vf.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) 82576 Virtual Function Linux driver
-  Copyright(c) 2009 - 2010 Intel Corporation.
+  Copyright(c) 2009 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile
index 7d7387f..7a16177 100644
--- a/drivers/net/ethernet/intel/ixgbe/Makefile
+++ b/drivers/net/ethernet/intel/ixgbe/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel 10 Gigabit PCI Express Linux driver
-# Copyright(c) 1999 - 2010 Intel Corporation.
+# Copyright(c) 1999 - 2012 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 258164d..e6aeb64 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index ef2afef..b406c36 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index 7720721..4e59083 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index a3aa633..383b941 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index 863f9c1..2c834c4 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -75,7 +75,7 @@
 s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
-s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num);
 s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
 
 s32 ixgbe_validate_mac_addr(u8 *mac_addr);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
index 318caf4..8bfaaee 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h
index e162775..24333b7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
index fcd0e47..d3695ed 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h
index 2f31893..ba83570 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
index 32cd97b..888a419 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h
index a59d5dc..4dec47f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index da31735..79a92fe 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -112,6 +112,8 @@
 static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 {
 	u8 err = 0;
+	u8 prio_tc[MAX_USER_PRIORITY] = {0};
+	int i;
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
 	/* Fail command if not in CEE mode */
@@ -122,10 +124,15 @@
 	if (!!state != !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
 		return err;
 
-	if (state > 0)
+	if (state > 0) {
 		err = ixgbe_setup_tc(netdev, adapter->dcb_cfg.num_tcs.pg_tcs);
-	else
+		ixgbe_dcb_unpack_map(&adapter->dcb_cfg, DCB_TX_CONFIG, prio_tc);
+	} else {
 		err = ixgbe_setup_tc(netdev, 0);
+	}
+
+	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
+		netdev_set_prio_tc_map(netdev, i, prio_tc[i]);
 
 	return err;
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index da7e580..a629754 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -58,7 +58,7 @@
 				sizeof(((struct rtnl_link_stats64 *)0)->m), \
 				offsetof(struct rtnl_link_stats64, m)
 
-static struct ixgbe_stats ixgbe_gstrings_stats[] = {
+static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
 	{"rx_packets", IXGBE_NETDEV_STAT(rx_packets)},
 	{"tx_packets", IXGBE_NETDEV_STAT(tx_packets)},
 	{"rx_bytes", IXGBE_NETDEV_STAT(rx_bytes)},
@@ -120,19 +120,23 @@
 #endif /* IXGBE_FCOE */
 };
 
-#define IXGBE_QUEUE_STATS_LEN \
-	((((struct ixgbe_adapter *)netdev_priv(netdev))->num_tx_queues + \
-	((struct ixgbe_adapter *)netdev_priv(netdev))->num_rx_queues) * \
+/* ixgbe allocates num_tx_queues and num_rx_queues symmetrically so
+ * we set the num_rx_queues to evaluate to num_tx_queues. This is
+ * used because we do not have a good way to get the max number of
+ * rx queues with CONFIG_RPS disabled.
+ */
+#define IXGBE_NUM_RX_QUEUES netdev->num_tx_queues
+
+#define IXGBE_QUEUE_STATS_LEN ( \
+	(netdev->num_tx_queues + IXGBE_NUM_RX_QUEUES) * \
 	(sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
 #define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
 #define IXGBE_PB_STATS_LEN ( \
-                 (((struct ixgbe_adapter *)netdev_priv(netdev))->flags & \
-                 IXGBE_FLAG_DCB_ENABLED) ? \
-                 (sizeof(((struct ixgbe_adapter *)0)->stats.pxonrxc) + \
-                  sizeof(((struct ixgbe_adapter *)0)->stats.pxontxc) + \
-                  sizeof(((struct ixgbe_adapter *)0)->stats.pxoffrxc) + \
-                  sizeof(((struct ixgbe_adapter *)0)->stats.pxofftxc)) \
-                  / sizeof(u64) : 0)
+			(sizeof(((struct ixgbe_adapter *)0)->stats.pxonrxc) + \
+			 sizeof(((struct ixgbe_adapter *)0)->stats.pxontxc) + \
+			 sizeof(((struct ixgbe_adapter *)0)->stats.pxoffrxc) + \
+			 sizeof(((struct ixgbe_adapter *)0)->stats.pxofftxc)) \
+			/ sizeof(u64))
 #define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + \
                          IXGBE_PB_STATS_LEN + \
                          IXGBE_QUEUE_STATS_LEN)
@@ -1078,8 +1082,15 @@
 		data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==
 		           sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
-	for (j = 0; j < adapter->num_tx_queues; j++) {
+	for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
 		ring = adapter->tx_ring[j];
+		if (!ring) {
+			data[i] = 0;
+			data[i+1] = 0;
+			i += 2;
+			continue;
+		}
+
 		do {
 			start = u64_stats_fetch_begin_bh(&ring->syncp);
 			data[i]   = ring->stats.packets;
@@ -1087,8 +1098,15 @@
 		} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
 		i += 2;
 	}
-	for (j = 0; j < adapter->num_rx_queues; j++) {
+	for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
 		ring = adapter->rx_ring[j];
+		if (!ring) {
+			data[i] = 0;
+			data[i+1] = 0;
+			i += 2;
+			continue;
+		}
+
 		do {
 			start = u64_stats_fetch_begin_bh(&ring->syncp);
 			data[i]   = ring->stats.packets;
@@ -1096,22 +1114,20 @@
 		} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
 		i += 2;
 	}
-	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-		for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) {
-			data[i++] = adapter->stats.pxontxc[j];
-			data[i++] = adapter->stats.pxofftxc[j];
-		}
-		for (j = 0; j < MAX_RX_PACKET_BUFFERS; j++) {
-			data[i++] = adapter->stats.pxonrxc[j];
-			data[i++] = adapter->stats.pxoffrxc[j];
-		}
+
+	for (j = 0; j < IXGBE_MAX_PACKET_BUFFERS; j++) {
+		data[i++] = adapter->stats.pxontxc[j];
+		data[i++] = adapter->stats.pxofftxc[j];
+	}
+	for (j = 0; j < IXGBE_MAX_PACKET_BUFFERS; j++) {
+		data[i++] = adapter->stats.pxonrxc[j];
+		data[i++] = adapter->stats.pxoffrxc[j];
 	}
 }
 
 static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
                               u8 *data)
 {
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	char *p = (char *)data;
 	int i;
 
@@ -1126,31 +1142,29 @@
 			       ETH_GSTRING_LEN);
 			p += ETH_GSTRING_LEN;
 		}
-		for (i = 0; i < adapter->num_tx_queues; i++) {
+		for (i = 0; i < netdev->num_tx_queues; i++) {
 			sprintf(p, "tx_queue_%u_packets", i);
 			p += ETH_GSTRING_LEN;
 			sprintf(p, "tx_queue_%u_bytes", i);
 			p += ETH_GSTRING_LEN;
 		}
-		for (i = 0; i < adapter->num_rx_queues; i++) {
+		for (i = 0; i < IXGBE_NUM_RX_QUEUES; i++) {
 			sprintf(p, "rx_queue_%u_packets", i);
 			p += ETH_GSTRING_LEN;
 			sprintf(p, "rx_queue_%u_bytes", i);
 			p += ETH_GSTRING_LEN;
 		}
-		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-			for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) {
-				sprintf(p, "tx_pb_%u_pxon", i);
-				p += ETH_GSTRING_LEN;
-				sprintf(p, "tx_pb_%u_pxoff", i);
-				p += ETH_GSTRING_LEN;
-			}
-			for (i = 0; i < MAX_RX_PACKET_BUFFERS; i++) {
-				sprintf(p, "rx_pb_%u_pxon", i);
-				p += ETH_GSTRING_LEN;
-				sprintf(p, "rx_pb_%u_pxoff", i);
-				p += ETH_GSTRING_LEN;
-			}
+		for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+			sprintf(p, "tx_pb_%u_pxon", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "tx_pb_%u_pxoff", i);
+			p += ETH_GSTRING_LEN;
+		}
+		for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+			sprintf(p, "rx_pb_%u_pxon", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_pb_%u_pxoff", i);
+			p += ETH_GSTRING_LEN;
 		}
 		/* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
 		break;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
index d18d615..4bc7942 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
index 261fd62..1dbed17 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 1ee5d0f..3dc6cef 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -64,7 +64,7 @@
 	__stringify(BUILD) "-k"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
-				"Copyright (c) 1999-2011 Intel Corporation.";
+				"Copyright (c) 1999-2012 Intel Corporation.";
 
 static const struct ixgbe_info *ixgbe_info_tbl[] = {
 	[board_82598] = &ixgbe_82598_info,
@@ -2633,22 +2633,22 @@
 	/*
 	 * we must limit the number of descriptors so that the
 	 * total size of max desc * buf_len is not greater
-	 * than 65535
+	 * than 65536
 	 */
 	if (ring_is_ps_enabled(ring)) {
-#if (MAX_SKB_FRAGS > 16)
+#if (PAGE_SIZE < 8192)
 		rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
-#elif (MAX_SKB_FRAGS > 8)
+#elif (PAGE_SIZE < 16384)
 		rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
-#elif (MAX_SKB_FRAGS > 4)
+#elif (PAGE_SIZE < 32768)
 		rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
 #else
 		rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
 #endif
 	} else {
-		if (rx_buf_len < IXGBE_RXBUFFER_4K)
+		if (rx_buf_len <= IXGBE_RXBUFFER_4K)
 			rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
-		else if (rx_buf_len < IXGBE_RXBUFFER_8K)
+		else if (rx_buf_len <= IXGBE_RXBUFFER_8K)
 			rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
 		else
 			rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
@@ -2830,7 +2830,7 @@
 	IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits);
 
 	vf_shift = adapter->num_vfs % 32;
-	reg_offset = (adapter->num_vfs > 32) ? 1 : 0;
+	reg_offset = (adapter->num_vfs >= 32) ? 1 : 0;
 
 	/* Enable only the PF's pool for Tx/Rx */
 	IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift));
@@ -4330,6 +4330,10 @@
 	adapter->num_tx_queues = 1;
 
 done:
+	if ((adapter->netdev->reg_state == NETREG_UNREGISTERED) ||
+	    (adapter->netdev->reg_state == NETREG_UNREGISTERING))
+		return 0;
+
 	/* Notify the stack of the (possibly) reduced queue counts. */
 	netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
 	return netif_set_real_num_rx_queues(adapter->netdev,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
index 3f725d4..1f3e32b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
index b239bda..310bdd9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index 7cf1e1f..b917735 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
index 197bdd1..cc18165 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index cf6812d..b01ecb4 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -67,7 +67,8 @@
 	vf_devfn = pdev->devfn + 0x80;
 	pvfdev = pci_get_device(IXGBE_INTEL_VENDOR_ID, device_id, NULL);
 	while (pvfdev) {
-		if (pvfdev->devfn == vf_devfn)
+		if (pvfdev->devfn == vf_devfn &&
+		    (pvfdev->bus->number >= pdev->bus->number))
 			vfs_found++;
 		vf_devfn += 2;
 		pvfdev = pci_get_device(IXGBE_INTEL_VENDOR_ID,
@@ -646,6 +647,9 @@
 			ixgbe_ndo_set_vf_spoofchk(adapter->netdev, vf, false);
 		retval = ixgbe_set_vf_macvlan(adapter, vf, index,
 					      (unsigned char *)(&msgbuf[1]));
+		if (retval == -ENOSPC)
+			e_warn(drv, "VF %d has requested a MACVLAN filter "
+				    "but there is no space for it\n", vf);
 		break;
 	default:
 		e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
index e8badab..2ab38d5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 775602e..9b95bef 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
index 8cc5ecc..f838a2b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbevf/Makefile b/drivers/net/ethernet/intel/ixgbevf/Makefile
index 1f35d22..4ce4c97 100644
--- a/drivers/net/ethernet/intel/ixgbevf/Makefile
+++ b/drivers/net/ethernet/intel/ixgbevf/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel 82599 Virtual Function driver
-# Copyright(c) 1999 - 2010 Intel Corporation.
+# Copyright(c) 1999 - 2012 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h b/drivers/net/ethernet/intel/ixgbevf/defines.h
index 2eb89cb..947b5c8 100644
--- a/drivers/net/ethernet/intel/ixgbevf/defines.h
+++ b/drivers/net/ethernet/intel/ixgbevf/defines.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index c857003..2bfe0d1 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 9075c1d..dfed420 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index bed411b..e51d552 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -60,7 +60,7 @@
 #define DRV_VERSION "2.2.0-k"
 const char ixgbevf_driver_version[] = DRV_VERSION;
 static char ixgbevf_copyright[] =
-	"Copyright (c) 2009 - 2010 Intel Corporation.";
+	"Copyright (c) 2009 - 2012 Intel Corporation.";
 
 static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
 	[board_82599_vf] = &ixgbevf_82599_vf_info,
@@ -935,7 +935,11 @@
 		if (msg & IXGBE_VT_MSGTYPE_NACK)
 			pr_warn("Last Request of type %2.2x to PF Nacked\n",
 				msg & 0xFF);
-		goto out;
+		/*
+		 * Restore the PFSTS bit in case someone is polling for a
+		 * return message from the PF
+		 */
+		hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFSTS;
 	}
 
 	/*
@@ -945,7 +949,7 @@
 	 */
 	if (got_ack)
 		hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
-out:
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.c b/drivers/net/ethernet/intel/ixgbevf/mbx.c
index 13532d9..9c95590 100644
--- a/drivers/net/ethernet/intel/ixgbevf/mbx.c
+++ b/drivers/net/ethernet/intel/ixgbevf/mbx.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h b/drivers/net/ethernet/intel/ixgbevf/mbx.h
index 9d38a94..cf9131c 100644
--- a/drivers/net/ethernet/intel/ixgbevf/mbx.h
+++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbevf/regs.h b/drivers/net/ethernet/intel/ixgbevf/regs.h
index 5e4d5e5..debd8c0 100644
--- a/drivers/net/ethernet/intel/ixgbevf/regs.h
+++ b/drivers/net/ethernet/intel/ixgbevf/regs.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c
index d0138d7..74be741 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -283,6 +283,17 @@
 	return ret_val;
 }
 
+static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
+					u32 *msg, u16 size)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	u32 retmsg[IXGBE_VFMAILBOX_SIZE];
+	s32 retval = mbx->ops.write_posted(hw, msg, size);
+
+	if (!retval)
+		mbx->ops.read_posted(hw, retmsg, size);
+}
+
 /**
  *  ixgbevf_update_mc_addr_list_vf - Update Multicast addresses
  *  @hw: pointer to the HW structure
@@ -294,7 +305,6 @@
 					  struct net_device *netdev)
 {
 	struct netdev_hw_addr *ha;
-	struct ixgbe_mbx_info *mbx = &hw->mbx;
 	u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
 	u16 *vector_list = (u16 *)&msgbuf[1];
 	u32 cnt, i;
@@ -321,7 +331,7 @@
 		vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr);
 	}
 
-	mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE);
+	ixgbevf_write_msg_read_ack(hw, msgbuf, IXGBE_VFMAILBOX_SIZE);
 
 	return 0;
 }
@@ -336,7 +346,6 @@
 static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
 			       bool vlan_on)
 {
-	struct ixgbe_mbx_info *mbx = &hw->mbx;
 	u32 msgbuf[2];
 
 	msgbuf[0] = IXGBE_VF_SET_VLAN;
@@ -344,7 +353,9 @@
 	/* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
 	msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT;
 
-	return mbx->ops.write_posted(hw, msgbuf, 2);
+	ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
+
+	return 0;
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h
index d556619..25c951d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 82599 Virtual Function driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 27d651a..55cbf65 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -2328,19 +2328,11 @@
 		((new_mtu) < IPV6_MIN_MTU))
 		return -EINVAL;
 
-	if (new_mtu > 4000) {
-		jme->reg_rxcs &= ~RXCS_FIFOTHNP;
-		jme->reg_rxcs |= RXCS_FIFOTHNP_64QW;
-		jme_restart_rx_engine(jme);
-	} else {
-		jme->reg_rxcs &= ~RXCS_FIFOTHNP;
-		jme->reg_rxcs |= RXCS_FIFOTHNP_128QW;
-		jme_restart_rx_engine(jme);
-	}
 
 	netdev->mtu = new_mtu;
 	netdev_update_features(netdev);
 
+	jme_restart_rx_engine(jme);
 	jme_reset_link(jme);
 
 	return 0;
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h
index 4304072..3efc897 100644
--- a/drivers/net/ethernet/jme.h
+++ b/drivers/net/ethernet/jme.h
@@ -730,7 +730,7 @@
 	RXCS_RETRYCNT_60	= 0x00000F00,
 
 	RXCS_DEFAULT		= RXCS_FIFOTHTP_128T |
-				  RXCS_FIFOTHNP_128QW |
+				  RXCS_FIFOTHNP_16QW |
 				  RXCS_DMAREQSZ_128B |
 				  RXCS_RETRYGAP_256ns |
 				  RXCS_RETRYCNT_32,
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index edb9bda..33947ac 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -931,20 +931,17 @@
 }
 
 /* Allocate and setup a new buffer for receiving */
-static int skge_rx_setup(struct pci_dev *pdev,
-			 struct skge_element *e,
-			 struct sk_buff *skb, unsigned int bufsize)
+static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
+			  struct sk_buff *skb, unsigned int bufsize)
 {
 	struct skge_rx_desc *rd = e->desc;
-	dma_addr_t map;
+	u64 map;
 
-	map = pci_map_single(pdev, skb->data, bufsize,
+	map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
 			     PCI_DMA_FROMDEVICE);
-	if (pci_dma_mapping_error(pdev, map))
-		goto mapping_error;
 
-	rd->dma_lo = lower_32_bits(map);
-	rd->dma_hi = upper_32_bits(map);
+	rd->dma_lo = map;
+	rd->dma_hi = map >> 32;
 	e->skb = skb;
 	rd->csum1_start = ETH_HLEN;
 	rd->csum2_start = ETH_HLEN;
@@ -956,13 +953,6 @@
 	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
 	dma_unmap_addr_set(e, mapaddr, map);
 	dma_unmap_len_set(e, maplen, bufsize);
-	return 0;
-
-mapping_error:
-	if (net_ratelimit())
-		dev_warn(&pdev->dev, "%s: rx mapping error\n",
-			 skb->dev->name);
-	return -EIO;
 }
 
 /* Resume receiving using existing skb,
@@ -1024,11 +1014,7 @@
 			return -ENOMEM;
 
 		skb_reserve(skb, NET_IP_ALIGN);
-		if (skge_rx_setup(skge->hw->pdev, e, skb, skge->rx_buf_size)) {
-			kfree_skb(skb);
-			return -ENOMEM;
-		}
-
+		skge_rx_setup(skge, e, skb, skge->rx_buf_size);
 	} while ((e = e->next) != ring->start);
 
 	ring->to_clean = ring->start;
@@ -2743,7 +2729,7 @@
 	struct skge_tx_desc *td;
 	int i;
 	u32 control, len;
-	dma_addr_t map;
+	u64 map;
 
 	if (skb_padto(skb, ETH_ZLEN))
 		return NETDEV_TX_OK;
@@ -2757,14 +2743,11 @@
 	e->skb = skb;
 	len = skb_headlen(skb);
 	map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(hw->pdev, map))
-		goto mapping_error;
-
 	dma_unmap_addr_set(e, mapaddr, map);
 	dma_unmap_len_set(e, maplen, len);
 
-	td->dma_lo = lower_32_bits(map);
-	td->dma_hi = upper_32_bits(map);
+	td->dma_lo = map;
+	td->dma_hi = map >> 32;
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		const int offset = skb_checksum_start_offset(skb);
@@ -2795,16 +2778,14 @@
 
 			map = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
 					       skb_frag_size(frag), DMA_TO_DEVICE);
-			if (dma_mapping_error(&hw->pdev->dev, map))
-				goto mapping_unwind;
 
 			e = e->next;
 			e->skb = skb;
 			tf = e->desc;
 			BUG_ON(tf->control & BMU_OWN);
 
-			tf->dma_lo = lower_32_bits(map);
-			tf->dma_hi = upper_32_bits(map);
+			tf->dma_lo = map;
+			tf->dma_hi = (u64) map >> 32;
 			dma_unmap_addr_set(e, mapaddr, map);
 			dma_unmap_len_set(e, maplen, skb_frag_size(frag));
 
@@ -2834,28 +2815,6 @@
 	}
 
 	return NETDEV_TX_OK;
-
-mapping_unwind:
-	/* unroll any pages that were already mapped.  */
-	if (e != skge->tx_ring.to_use) {
-		struct skge_element *u;
-
-		for (u = skge->tx_ring.to_use->next; u != e; u = u->next)
-			pci_unmap_page(hw->pdev, dma_unmap_addr(u, mapaddr),
-				       dma_unmap_len(u, maplen),
-				       PCI_DMA_TODEVICE);
-		e = skge->tx_ring.to_use;
-	}
-	/* undo the mapping for the skb header */
-	pci_unmap_single(hw->pdev, dma_unmap_addr(e, mapaddr),
-			 dma_unmap_len(e, maplen),
-			 PCI_DMA_TODEVICE);
-mapping_error:
-	/* mapping error causes error message and packet to be discarded. */
-	if (net_ratelimit())
-		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
-	dev_kfree_skb(skb);
-	return NETDEV_TX_OK;
 }
 
 
@@ -3099,17 +3058,13 @@
 		if (!nskb)
 			goto resubmit;
 
-		if (unlikely(skge_rx_setup(skge->hw->pdev, e, nskb, skge->rx_buf_size))) {
-			dev_kfree_skb(nskb);
-			goto resubmit;
-		}
-
 		pci_unmap_single(skge->hw->pdev,
 				 dma_unmap_addr(e, mapaddr),
 				 dma_unmap_len(e, maplen),
 				 PCI_DMA_FROMDEVICE);
 		skb = e->skb;
 		prefetch(skb->data);
+		skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
 	}
 
 	skb_put(skb, len);
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 405e6ac..eaf09d4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1616,12 +1616,12 @@
 				kfree(priv->mfunc.master.slave_state[i].vlan_filter[port]);
 		}
 		kfree(priv->mfunc.master.slave_state);
-		iounmap(priv->mfunc.comm);
-		dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
-						     priv->mfunc.vhcr,
-						     priv->mfunc.vhcr_dma);
-		priv->mfunc.vhcr = NULL;
 	}
+
+	iounmap(priv->mfunc.comm);
+	dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
+		     priv->mfunc.vhcr, priv->mfunc.vhcr_dma);
+	priv->mfunc.vhcr = NULL;
 }
 
 void mlx4_cmd_cleanup(struct mlx4_dev *dev)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 467ae58..149e60d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -892,7 +892,8 @@
 
 	for (i = 0; i < priv->rx_ring_num; i++) {
 		if (priv->rx_ring[i].rx_info)
-			mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i]);
+			mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i],
+				priv->prof->rx_ring_size, priv->stride);
 		if (priv->rx_cq[i].buf)
 			mlx4_en_destroy_cq(priv, &priv->rx_cq[i]);
 	}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 971d4b6..d4ad8c2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -168,8 +168,12 @@
 	return 0;
 
 err:
-	while (i--)
+	while (i--) {
+		dma_addr_t dma = be64_to_cpu(rx_desc->data[i].addr);
+		pci_unmap_single(priv->mdev->pdev, dma, skb_frags[i].size,
+				 PCI_DMA_FROMDEVICE);
 		put_page(skb_frags[i].page);
+	}
 	return -ENOMEM;
 }
 
@@ -380,12 +384,12 @@
 }
 
 void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
-			     struct mlx4_en_rx_ring *ring)
+			     struct mlx4_en_rx_ring *ring, u32 size, u16 stride)
 {
 	struct mlx4_en_dev *mdev = priv->mdev;
 
 	mlx4_en_unmap_buffer(&ring->wqres.buf);
-	mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE);
+	mlx4_free_hwq_res(mdev->dev, &ring->wqres, size * stride + TXBB_SIZE);
 	vfree(ring->rx_info);
 	ring->rx_info = NULL;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 55d7bd4..9129ace 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -815,8 +815,9 @@
 	int err;
 	int i;
 
-	priv->eq_table.uar_map = kcalloc(sizeof *priv->eq_table.uar_map,
-					 mlx4_num_eq_uar(dev), GFP_KERNEL);
+	priv->eq_table.uar_map = kcalloc(mlx4_num_eq_uar(dev),
+					 sizeof *priv->eq_table.uar_map,
+					 GFP_KERNEL);
 	if (!priv->eq_table.uar_map) {
 		err = -ENOMEM;
 		goto err_out_free;
@@ -1035,7 +1036,7 @@
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	int vec = 0, err = 0, i;
 
-	spin_lock(&priv->msix_ctl.pool_lock);
+	mutex_lock(&priv->msix_ctl.pool_lock);
 	for (i = 0; !vec && i < dev->caps.comp_pool; i++) {
 		if (~priv->msix_ctl.pool_bm & 1ULL << i) {
 			priv->msix_ctl.pool_bm |= 1ULL << i;
@@ -1057,7 +1058,7 @@
 			eq_set_ci(&priv->eq_table.eq[vec], 1);
 		}
 	}
-	spin_unlock(&priv->msix_ctl.pool_lock);
+	mutex_unlock(&priv->msix_ctl.pool_lock);
 
 	if (vec) {
 		*vector = vec;
@@ -1078,13 +1079,13 @@
 	if (likely(i >= 0)) {
 		/*sanity check , making sure were not trying to free irq's
 		  Belonging to a legacy EQ*/
-		spin_lock(&priv->msix_ctl.pool_lock);
+		mutex_lock(&priv->msix_ctl.pool_lock);
 		if (priv->msix_ctl.pool_bm & 1ULL << i) {
 			free_irq(priv->eq_table.eq[vec].irq,
 				 &priv->eq_table.eq[vec]);
 			priv->msix_ctl.pool_bm &= ~(1ULL << i);
 		}
-		spin_unlock(&priv->msix_ctl.pool_lock);
+		mutex_unlock(&priv->msix_ctl.pool_lock);
 	}
 
 }
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 8a21e10..9ea7cab 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -685,7 +685,7 @@
 	return err;
 }
 
-static int mlx4_QUERY_PORT(struct mlx4_dev *dev, void *ptr, u8 port)
+int mlx4_QUERY_PORT(struct mlx4_dev *dev, void *ptr, u8 port)
 {
 	struct mlx4_cmd_mailbox *outbox = ptr;
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 678558b..d498f04 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -531,15 +531,14 @@
 	for (port = 0; port <  dev->caps.num_ports; port++) {
 		/* Change the port type only if the new type is different
 		 * from the current, and not set to Auto */
-		if (port_types[port] != dev->caps.port_type[port + 1]) {
+		if (port_types[port] != dev->caps.port_type[port + 1])
 			change = 1;
-			dev->caps.port_type[port + 1] = port_types[port];
-		}
 	}
 	if (change) {
 		mlx4_unregister_device(dev);
 		for (port = 1; port <= dev->caps.num_ports; port++) {
 			mlx4_CLOSE_PORT(dev, port);
+			dev->caps.port_type[port] = port_types[port - 1];
 			err = mlx4_SET_PORT(dev, port);
 			if (err) {
 				mlx4_err(dev, "Failed to set port %d, "
@@ -986,6 +985,9 @@
 	resource_size_t bf_len;
 	int err = 0;
 
+	if (!dev->caps.bf_reg_size)
+		return -ENXIO;
+
 	bf_start = pci_resource_start(dev->pdev, 2) +
 			(dev->caps.num_uars << PAGE_SHIFT);
 	bf_len = pci_resource_len(dev->pdev, 2) -
@@ -1825,7 +1827,7 @@
 		goto err_master_mfunc;
 
 	priv->msix_ctl.pool_bm = 0;
-	spin_lock_init(&priv->msix_ctl.pool_lock);
+	mutex_init(&priv->msix_ctl.pool_lock);
 
 	mlx4_enable_msi_x(dev);
 	if ((mlx4_is_mfunc(dev)) &&
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 0785d9b..ca574d8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -136,7 +136,7 @@
 	u32 prot;
 	int err;
 
-	s_steer = &mlx4_priv(dev)->steer[0];
+	s_steer = &mlx4_priv(dev)->steer[port - 1];
 	new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL);
 	if (!new_entry)
 		return -ENOMEM;
@@ -220,7 +220,7 @@
 	struct mlx4_promisc_qp *pqp;
 	struct mlx4_promisc_qp *dqp;
 
-	s_steer = &mlx4_priv(dev)->steer[0];
+	s_steer = &mlx4_priv(dev)->steer[port - 1];
 
 	pqp = get_promisc_qp(dev, 0, steer, qpn);
 	if (!pqp)
@@ -265,7 +265,7 @@
 	struct mlx4_steer_index *tmp_entry, *entry = NULL;
 	struct mlx4_promisc_qp *dqp, *tmp_dqp;
 
-	s_steer = &mlx4_priv(dev)->steer[0];
+	s_steer = &mlx4_priv(dev)->steer[port - 1];
 
 	/* if qp is not promisc, it cannot be duplicated */
 	if (!get_promisc_qp(dev, 0, steer, qpn))
@@ -306,7 +306,7 @@
 	bool ret = false;
 	int i;
 
-	s_steer = &mlx4_priv(dev)->steer[0];
+	s_steer = &mlx4_priv(dev)->steer[port - 1];
 
 	mailbox = mlx4_alloc_cmd_mailbox(dev);
 	if (IS_ERR(mailbox))
@@ -361,7 +361,7 @@
 	int err;
 	struct mlx4_priv *priv = mlx4_priv(dev);
 
-	s_steer = &mlx4_priv(dev)->steer[0];
+	s_steer = &mlx4_priv(dev)->steer[port - 1];
 
 	mutex_lock(&priv->mcg_table.mutex);
 
@@ -466,7 +466,7 @@
 	int loc, i;
 	int err;
 
-	s_steer = &mlx4_priv(dev)->steer[0];
+	s_steer = &mlx4_priv(dev)->steer[port - 1];
 	mutex_lock(&priv->mcg_table.mutex);
 
 	pqp = get_promisc_qp(dev, 0, steer, qpn);
@@ -1004,7 +1004,7 @@
 
 int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port)
 {
-	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
+	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER))
 		return 0;
 
 	if (mlx4_is_mfunc(dev))
@@ -1016,7 +1016,7 @@
 
 int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port)
 {
-	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
+	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER))
 		return 0;
 
 	if (mlx4_is_mfunc(dev))
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index c92269f..28f8251 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -697,7 +697,7 @@
 
 struct mlx4_msix_ctl {
 	u64		pool_bm;
-	spinlock_t	pool_lock;
+	struct mutex	pool_lock;
 };
 
 struct mlx4_steer {
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 35f0884..d60335f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -528,7 +528,8 @@
 			   struct mlx4_en_rx_ring *ring,
 			   u32 size, u16 stride);
 void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
-			     struct mlx4_en_rx_ring *ring);
+			     struct mlx4_en_rx_ring *ring,
+			     u32 size, u16 stride);
 int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv);
 void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
 				struct mlx4_en_rx_ring *ring);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index 8deeef9..25a80d7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -304,7 +304,7 @@
 			    MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
 }
 
-static int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align,
+int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align,
 			  u32 *base_mridx)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
@@ -320,14 +320,14 @@
 }
 EXPORT_SYMBOL_GPL(mlx4_mr_reserve_range);
 
-static void mlx4_mr_release_range(struct mlx4_dev *dev, u32 base_mridx, int cnt)
+void mlx4_mr_release_range(struct mlx4_dev *dev, u32 base_mridx, int cnt)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	mlx4_bitmap_free_range(&priv->mr_table.mpt_bitmap, base_mridx, cnt);
 }
 EXPORT_SYMBOL_GPL(mlx4_mr_release_range);
 
-static int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd,
+int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd,
 			   u64 iova, u64 size, u32 access, int npages,
 			   int page_shift, struct mlx4_mr *mr)
 {
@@ -457,7 +457,7 @@
 }
 EXPORT_SYMBOL_GPL(mlx4_mr_alloc);
 
-static void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr)
+void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr)
 {
 	int err;
 
@@ -852,7 +852,7 @@
 }
 EXPORT_SYMBOL_GPL(mlx4_fmr_alloc);
 
-static int mlx4_fmr_alloc_reserved(struct mlx4_dev *dev, u32 mridx,
+int mlx4_fmr_alloc_reserved(struct mlx4_dev *dev, u32 mridx,
 			    u32 pd, u32 access, int max_pages,
 			    int max_maps, u8 page_shift, struct mlx4_fmr *fmr)
 {
@@ -954,7 +954,7 @@
 }
 EXPORT_SYMBOL_GPL(mlx4_fmr_free);
 
-static int mlx4_fmr_free_reserved(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
+int mlx4_fmr_free_reserved(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
 {
 	if (fmr->maps)
 		return -EBUSY;
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index dcd819b..bfdb7af 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -73,6 +73,7 @@
 	struct list_head	list;
 	u8			gid[16];
 	enum mlx4_protocol	prot;
+	enum mlx4_steer_type	steer;
 };
 
 enum res_qp_states {
@@ -374,6 +375,7 @@
 
 	ret->com.res_id = id;
 	ret->com.state = RES_QP_RESERVED;
+	ret->local_qpn = id;
 	INIT_LIST_HEAD(&ret->mcg_list);
 	spin_lock_init(&ret->mcg_spl);
 
@@ -2479,7 +2481,8 @@
 }
 
 static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
-		       u8 *gid, enum mlx4_protocol prot)
+		       u8 *gid, enum mlx4_protocol prot,
+		       enum mlx4_steer_type steer)
 {
 	struct res_gid *res;
 	int err;
@@ -2495,6 +2498,7 @@
 	} else {
 		memcpy(res->gid, gid, 16);
 		res->prot = prot;
+		res->steer = steer;
 		list_add_tail(&res->list, &rqp->mcg_list);
 		err = 0;
 	}
@@ -2504,14 +2508,15 @@
 }
 
 static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
-		       u8 *gid, enum mlx4_protocol prot)
+		       u8 *gid, enum mlx4_protocol prot,
+		       enum mlx4_steer_type steer)
 {
 	struct res_gid *res;
 	int err;
 
 	spin_lock_irq(&rqp->mcg_spl);
 	res = find_gid(dev, slave, rqp, gid);
-	if (!res || res->prot != prot)
+	if (!res || res->prot != prot || res->steer != steer)
 		err = -EINVAL;
 	else {
 		list_del(&res->list);
@@ -2538,7 +2543,7 @@
 	int attach = vhcr->op_modifier;
 	int block_loopback = vhcr->in_modifier >> 31;
 	u8 steer_type_mask = 2;
-	enum mlx4_steer_type type = gid[7] & steer_type_mask;
+	enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
 
 	qpn = vhcr->in_modifier & 0xffffff;
 	err = get_res(dev, slave, qpn, RES_QP, &rqp);
@@ -2547,7 +2552,7 @@
 
 	qp.qpn = qpn;
 	if (attach) {
-		err = add_mcg_res(dev, slave, rqp, gid, prot);
+		err = add_mcg_res(dev, slave, rqp, gid, prot, type);
 		if (err)
 			goto ex_put;
 
@@ -2556,7 +2561,7 @@
 		if (err)
 			goto ex_rem;
 	} else {
-		err = rem_mcg_res(dev, slave, rqp, gid, prot);
+		err = rem_mcg_res(dev, slave, rqp, gid, prot, type);
 		if (err)
 			goto ex_put;
 		err = mlx4_qp_detach_common(dev, &qp, gid, prot, type);
@@ -2567,7 +2572,7 @@
 
 ex_rem:
 	/* ignore error return below, already in error */
-	err1 = rem_mcg_res(dev, slave, rqp, gid, prot);
+	err1 = rem_mcg_res(dev, slave, rqp, gid, prot, type);
 ex_put:
 	put_res(dev, slave, qpn, RES_QP);
 
@@ -2606,7 +2611,7 @@
 	list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) {
 		qp.qpn = rqp->local_qpn;
 		err = mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot,
-					    MLX4_MC_STEER);
+					    rgid->steer);
 		list_del(&rgid->list);
 		kfree(rgid);
 	}
diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig
index 1ea811c..fe42fc0 100644
--- a/drivers/net/ethernet/micrel/Kconfig
+++ b/drivers/net/ethernet/micrel/Kconfig
@@ -42,7 +42,6 @@
 	select NET_CORE
 	select MII
 	select CRC32
-	select MISC_DEVICES
 	select EEPROM_93CX6
 	---help---
 	  SPI driver for Micrel KS8851 SPI attached network chip.
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index 6b35e7d..0c3e400 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -583,7 +583,7 @@
 					ks8851_dbg_dumpkkt(ks, rxpkt);
 
 				skb->protocol = eth_type_trans(skb, ks->netdev);
-				netif_rx(skb);
+				netif_rx_ni(skb);
 
 				ks->netdev->stats.rx_packets++;
 				ks->netdev->stats.rx_bytes += rxlen;
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index e58e78e..2784bc7 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -394,7 +394,6 @@
  * @msg_enable	: The message flags controlling driver output (see ethtool).
  * @frame_cnt  	: number of frames received.
  * @bus_width  	: i/o bus width.
- * @irq    	: irq number assigned to this device.
  * @rc_rxqcr	: Cached copy of KS_RXQCR.
  * @rc_txcr	: Cached copy of KS_TXCR.
  * @rc_ier	: Cached copy of KS_IER.
@@ -441,7 +440,6 @@
 	u32			msg_enable;
 	u32			frame_cnt;
 	int			bus_width;
-	int             	irq;
 
 	u16			rc_rxqcr;
 	u16			rc_txcr;
@@ -907,10 +905,10 @@
 	netif_dbg(ks, ifup, ks->netdev, "%s - entry\n", __func__);
 
 	/* reset the HW */
-	err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev);
+	err = request_irq(netdev->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev);
 
 	if (err) {
-		pr_err("Failed to request IRQ: %d: %d\n", ks->irq, err);
+		pr_err("Failed to request IRQ: %d: %d\n", netdev->irq, err);
 		return err;
 	}
 
@@ -955,7 +953,7 @@
 
 	/* set powermode to soft power down to save power */
 	ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
-	free_irq(ks->irq, netdev);
+	free_irq(netdev->irq, netdev);
 	mutex_unlock(&ks->lock);
 	return 0;
 }
@@ -1545,10 +1543,10 @@
 	if (!ks->hw_addr_cmd)
 		goto err_ioremap1;
 
-	ks->irq = platform_get_irq(pdev, 0);
+	netdev->irq = platform_get_irq(pdev, 0);
 
-	if (ks->irq < 0) {
-		err = ks->irq;
+	if ((int)netdev->irq < 0) {
+		err = netdev->irq;
 		goto err_get_irq;
 	}
 
diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c
index 212f43b..cd827ff 100644
--- a/drivers/net/ethernet/octeon/octeon_mgmt.c
+++ b/drivers/net/ethernet/octeon/octeon_mgmt.c
@@ -670,7 +670,7 @@
 static int octeon_mgmt_init_phy(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	char phy_id[20];
+	char phy_id[MII_BUS_ID_SIZE + 3];
 
 	if (octeon_is_simulation()) {
 		/* No PHYs in the simulator. */
@@ -678,7 +678,7 @@
 		return 0;
 	}
 
-	snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", p->port);
+	snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "mdio-octeon-0", p->port);
 
 	p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0,
 				PHY_INTERFACE_MODE_MII);
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 813d41c..87b6501 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -38,6 +38,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/ethtool.h>
+#include <linux/if_vlan.h>
 #include <linux/sh_eth.h>
 
 #include "sh_eth.h"
@@ -817,7 +818,8 @@
 		sh_eth_write(ndev, 0, TRIMD);
 
 	/* Recv frame limit set register */
-	sh_eth_write(ndev, RFLR_VALUE, RFLR);
+	sh_eth_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN,
+		     RFLR);
 
 	sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
 	sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 47877b1..cdbd844 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -575,9 +575,6 @@
 	RPADIR_PADR = 0x0003f,
 };
 
-/* RFLR */
-#define RFLR_VALUE 0x1000
-
 /* FDR */
 #define DEFAULT_FDR_INIT	0x00000707
 
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index aca3498..fc52fca 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -156,11 +156,10 @@
 		if (unlikely(!skb))
 			return -ENOMEM;
 
-		/* Adjust the SKB for padding and checksum */
+		/* Adjust the SKB for padding */
 		skb_reserve(skb, NET_IP_ALIGN);
 		rx_buf->len = skb_len - NET_IP_ALIGN;
 		rx_buf->is_page = false;
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 		rx_buf->dma_addr = pci_map_single(efx->pci_dev,
 						  skb->data, rx_buf->len,
@@ -496,6 +495,7 @@
 
 		EFX_BUG_ON_PARANOID(!checksummed);
 		rx_buf->u.skb = NULL;
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 		gro_result = napi_gro_receive(napi, skb);
 	}
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index d0b814e..0319d64 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -67,6 +67,7 @@
 	unsigned long ipc_csum_error;
 	unsigned long rx_collision;
 	unsigned long rx_crc;
+	unsigned long dribbling_bit;
 	unsigned long rx_length;
 	unsigned long rx_mii;
 	unsigned long rx_multicast;
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index d879763..ad1b627 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -201,7 +201,7 @@
 
 	if (unlikely(p->des01.erx.dribbling)) {
 		CHIP_DBG(KERN_ERR "GMAC RX: dribbling error\n");
-		ret = discard_frame;
+		x->dribbling_bit++;
 	}
 	if (unlikely(p->des01.erx.sa_filter_fail)) {
 		CHIP_DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index fda5d2b..25953bb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -104,7 +104,7 @@
 		ret = discard_frame;
 	}
 	if (unlikely(p->des01.rx.dribbling))
-		ret = discard_frame;
+		x->dribbling_bit++;
 
 	if (unlikely(p->des01.rx.length_error)) {
 		x->rx_length++;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 1207400..b4b095f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -21,7 +21,7 @@
 *******************************************************************************/
 
 #define STMMAC_RESOURCE_NAME   "stmmaceth"
-#define DRV_MODULE_VERSION	"Dec_2011"
+#define DRV_MODULE_VERSION	"Feb_2012"
 #include <linux/stmmac.h>
 #include <linux/phy.h>
 #include "common.h"
@@ -97,4 +97,5 @@
 int stmmac_suspend(struct net_device *ndev);
 int stmmac_dvr_remove(struct net_device *ndev);
 struct stmmac_priv *stmmac_dvr_probe(struct device *device,
-				struct plat_stmmacenet_data *plat_dat);
+				     struct plat_stmmacenet_data *plat_dat,
+				     void __iomem *addr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 9573303..f98e151 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -47,23 +47,25 @@
 	offsetof(struct stmmac_priv, xstats.m)}
 
 static const struct stmmac_stats stmmac_gstrings_stats[] = {
+	/* Transmit errors */
 	STMMAC_STAT(tx_underflow),
 	STMMAC_STAT(tx_carrier),
 	STMMAC_STAT(tx_losscarrier),
 	STMMAC_STAT(vlan_tag),
 	STMMAC_STAT(tx_deferred),
 	STMMAC_STAT(tx_vlan),
-	STMMAC_STAT(rx_vlan),
 	STMMAC_STAT(tx_jabber),
 	STMMAC_STAT(tx_frame_flushed),
 	STMMAC_STAT(tx_payload_error),
 	STMMAC_STAT(tx_ip_header_error),
+	/* Receive errors */
 	STMMAC_STAT(rx_desc),
 	STMMAC_STAT(sa_filter_fail),
 	STMMAC_STAT(overflow_error),
 	STMMAC_STAT(ipc_csum_error),
 	STMMAC_STAT(rx_collision),
 	STMMAC_STAT(rx_crc),
+	STMMAC_STAT(dribbling_bit),
 	STMMAC_STAT(rx_length),
 	STMMAC_STAT(rx_mii),
 	STMMAC_STAT(rx_multicast),
@@ -73,6 +75,8 @@
 	STMMAC_STAT(sa_rx_filter_fail),
 	STMMAC_STAT(rx_missed_cntr),
 	STMMAC_STAT(rx_overflow_cntr),
+	STMMAC_STAT(rx_vlan),
+	/* Tx/Rx IRQ errors */
 	STMMAC_STAT(tx_undeflow_irq),
 	STMMAC_STAT(tx_process_stopped_irq),
 	STMMAC_STAT(tx_jabber_irq),
@@ -82,6 +86,7 @@
 	STMMAC_STAT(rx_watchdog_irq),
 	STMMAC_STAT(tx_early_irq),
 	STMMAC_STAT(fatal_bus_error_irq),
+	/* Extra info */
 	STMMAC_STAT(threshold),
 	STMMAC_STAT(tx_pkt_n),
 	STMMAC_STAT(rx_pkt_n),
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 96fa2da..6ee593a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -241,7 +241,7 @@
 			case 1000:
 				if (likely(priv->plat->has_gmac))
 					ctrl &= ~priv->hw->link.port;
-				stmmac_hw_fix_mac_speed(priv);
+					stmmac_hw_fix_mac_speed(priv);
 				break;
 			case 100:
 			case 10:
@@ -785,7 +785,7 @@
 		u32 uid = ((hwid & 0x0000ff00) >> 8);
 		u32 synid = (hwid & 0x000000ff);
 
-		pr_info("STMMAC - user ID: 0x%x, Synopsys ID: 0x%x\n",
+		pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n",
 			uid, synid);
 
 		return synid;
@@ -869,38 +869,6 @@
 	return hw_cap;
 }
 
-/**
- * stmmac_mac_device_setup
- * @dev : device pointer
- * Description: this is to attach the GMAC or MAC 10/100
- * main core structures that will be completed during the
- * open step.
- */
-static int stmmac_mac_device_setup(struct net_device *dev)
-{
-	struct stmmac_priv *priv = netdev_priv(dev);
-
-	struct mac_device_info *device;
-
-	if (priv->plat->has_gmac)
-		device = dwmac1000_setup(priv->ioaddr);
-	else
-		device = dwmac100_setup(priv->ioaddr);
-
-	if (!device)
-		return -ENOMEM;
-
-	priv->hw = device;
-	priv->hw->ring = &ring_mode_ops;
-
-	if (device_can_wakeup(priv->device)) {
-		priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
-		enable_irq_wake(priv->wol_irq);
-	}
-
-	return 0;
-}
-
 static void stmmac_check_ether_addr(struct stmmac_priv *priv)
 {
 	/* verify if the MAC address is valid, in case of failures it
@@ -930,20 +898,8 @@
 	struct stmmac_priv *priv = netdev_priv(dev);
 	int ret;
 
-	/* MAC HW device setup */
-	ret = stmmac_mac_device_setup(dev);
-	if (ret < 0)
-		return ret;
-
 	stmmac_check_ether_addr(priv);
 
-	stmmac_verify_args();
-
-	/* Override with kernel parameters if supplied XXX CRS XXX
-	 * this needs to have multiple instances */
-	if ((phyaddr >= 0) && (phyaddr <= 31))
-		priv->plat->phy_addr = phyaddr;
-
 	/* MDIO bus Registration */
 	ret = stmmac_mdio_register(dev);
 	if (ret < 0) {
@@ -976,44 +932,6 @@
 		goto open_error;
 	}
 
-	stmmac_get_synopsys_id(priv);
-
-	priv->hw_cap_support = stmmac_get_hw_features(priv);
-
-	if (priv->hw_cap_support) {
-		pr_info(" Support DMA HW capability register");
-
-		/* We can override some gmac/dma configuration fields: e.g.
-		 * enh_desc, tx_coe (e.g. that are passed through the
-		 * platform) with the values from the HW capability
-		 * register (if supported).
-		 */
-		priv->plat->enh_desc = priv->dma_cap.enh_desc;
-		priv->plat->tx_coe = priv->dma_cap.tx_coe;
-		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
-
-		/* By default disable wol on magic frame if not supported */
-		if (!priv->dma_cap.pmt_magic_frame)
-			priv->wolopts &= ~WAKE_MAGIC;
-
-	} else
-		pr_info(" No HW DMA feature register supported");
-
-	/* Select the enhnaced/normal descriptor structures */
-	stmmac_selec_desc_mode(priv);
-
-	/* PMT module is not integrated in all the MAC devices. */
-	if (priv->plat->pmt) {
-		pr_info(" Remote wake-up capable\n");
-		device_set_wakeup_capable(priv->device, 1);
-	}
-
-	priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
-	if (priv->rx_coe)
-		pr_info(" Checksum Offload Engine supported\n");
-	if (priv->plat->tx_coe)
-		pr_info(" Checksum insertion supported\n");
-
 	/* Create and initialize the TX/RX descriptors chains. */
 	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
@@ -1030,14 +948,14 @@
 
 	/* Copy the MAC addr into the HW  */
 	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
+
 	/* If required, perform hw setup of the bus. */
 	if (priv->plat->bus_setup)
 		priv->plat->bus_setup(priv->ioaddr);
+
 	/* Initialize the MAC Core */
 	priv->hw->mac->core_init(priv->ioaddr);
 
-	netdev_update_features(dev);
-
 	/* Request the IRQ lines */
 	ret = request_irq(dev->irq, stmmac_interrupt,
 			 IRQF_SHARED, dev->name, dev);
@@ -1047,6 +965,17 @@
 		goto open_error;
 	}
 
+	/* Request the Wake IRQ in case of another line is used for WoL */
+	if (priv->wol_irq != dev->irq) {
+		ret = request_irq(priv->wol_irq, stmmac_interrupt,
+				  IRQF_SHARED, dev->name, dev);
+		if (unlikely(ret < 0)) {
+			pr_err("%s: ERROR: allocating the ext WoL IRQ %d "
+			       "(error: %d)\n",	__func__, priv->wol_irq, ret);
+			goto open_error_wolirq;
+		}
+	}
+
 	/* Enable the MAC Rx/Tx */
 	stmmac_set_mac(priv->ioaddr, true);
 
@@ -1062,7 +991,7 @@
 #ifdef CONFIG_STMMAC_DEBUG_FS
 	ret = stmmac_init_fs(dev);
 	if (ret < 0)
-		pr_warning("\tFailed debugFS registration");
+		pr_warning("%s: failed debugFS registration\n", __func__);
 #endif
 	/* Start the ball rolling... */
 	DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
@@ -1072,6 +1001,7 @@
 #ifdef CONFIG_STMMAC_TIMER
 	priv->tm->timer_start(tmrate);
 #endif
+
 	/* Dump DMA/MAC registers */
 	if (netif_msg_hw(priv)) {
 		priv->hw->mac->dump_regs(priv->ioaddr);
@@ -1087,6 +1017,9 @@
 
 	return 0;
 
+open_error_wolirq:
+	free_irq(dev->irq, dev);
+
 open_error:
 #ifdef CONFIG_STMMAC_TIMER
 	kfree(priv->tm);
@@ -1127,6 +1060,8 @@
 
 	/* Free the IRQ lines */
 	free_irq(dev->irq, dev);
+	if (priv->wol_irq != dev->irq)
+		free_irq(priv->wol_irq, dev);
 
 	/* Stop TX/RX DMA and clear the descriptors */
 	priv->hw->dma->stop_tx(priv->ioaddr);
@@ -1789,13 +1724,77 @@
 };
 
 /**
+ *  stmmac_hw_init - Init the MAC device
+ *  @priv : pointer to the private device structure.
+ *  Description: this function detects which MAC device
+ *  (GMAC/MAC10-100) has to attached, checks the HW capability
+ *  (if supported) and sets the driver's features (for example
+ *  to use the ring or chaine mode or support the normal/enh
+ *  descriptor structure).
+ */
+static int stmmac_hw_init(struct stmmac_priv *priv)
+{
+	int ret = 0;
+	struct mac_device_info *mac;
+
+	/* Identify the MAC HW device */
+	if (priv->plat->has_gmac)
+		mac = dwmac1000_setup(priv->ioaddr);
+	else
+		mac = dwmac100_setup(priv->ioaddr);
+	if (!mac)
+		return -ENOMEM;
+
+	priv->hw = mac;
+
+	/* To use the chained or ring mode */
+	priv->hw->ring = &ring_mode_ops;
+
+	/* Get and dump the chip ID */
+	stmmac_get_synopsys_id(priv);
+
+	/* Get the HW capability (new GMAC newer than 3.50a) */
+	priv->hw_cap_support = stmmac_get_hw_features(priv);
+	if (priv->hw_cap_support) {
+		pr_info(" DMA HW capability register supported");
+
+		/* We can override some gmac/dma configuration fields: e.g.
+		 * enh_desc, tx_coe (e.g. that are passed through the
+		 * platform) with the values from the HW capability
+		 * register (if supported).
+		 */
+		priv->plat->enh_desc = priv->dma_cap.enh_desc;
+		priv->plat->tx_coe = priv->dma_cap.tx_coe;
+		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
+	} else
+		pr_info(" No HW DMA feature register supported");
+
+	/* Select the enhnaced/normal descriptor structures */
+	stmmac_selec_desc_mode(priv);
+
+	priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
+	if (priv->rx_coe)
+		pr_info(" RX Checksum Offload Engine supported\n");
+	if (priv->plat->tx_coe)
+		pr_info(" TX Checksum insertion supported\n");
+
+	if (priv->plat->pmt) {
+		pr_info(" Wake-Up On Lan supported\n");
+		device_set_wakeup_capable(priv->device, 1);
+	}
+
+	return ret;
+}
+
+/**
  * stmmac_dvr_probe
  * @device: device pointer
  * Description: this is the main probe function used to
  * call the alloc_etherdev, allocate the priv structure.
  */
 struct stmmac_priv *stmmac_dvr_probe(struct device *device,
-					struct plat_stmmacenet_data *plat_dat)
+				     struct plat_stmmacenet_data *plat_dat,
+				     void __iomem *addr)
 {
 	int ret = 0;
 	struct net_device *ndev = NULL;
@@ -1815,10 +1814,27 @@
 
 	ether_setup(ndev);
 
-	ndev->netdev_ops = &stmmac_netdev_ops;
 	stmmac_set_ethtool_ops(ndev);
+	priv->pause = pause;
+	priv->plat = plat_dat;
+	priv->ioaddr = addr;
+	priv->dev->base_addr = (unsigned long)addr;
 
-	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	/* Verify driver arguments */
+	stmmac_verify_args();
+
+	/* Override with kernel parameters if supplied XXX CRS XXX
+	 * this needs to have multiple instances */
+	if ((phyaddr >= 0) && (phyaddr <= 31))
+		priv->plat->phy_addr = phyaddr;
+
+	/* Init MAC and get the capabilities */
+	stmmac_hw_init(priv);
+
+	ndev->netdev_ops = &stmmac_netdev_ops;
+
+	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			    NETIF_F_RXCSUM;
 	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
 	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
 #ifdef STMMAC_VLAN_TAG_USED
@@ -1830,8 +1846,6 @@
 	if (flow_ctrl)
 		priv->flow_ctrl = FLOW_AUTO;	/* RX/TX pause on */
 
-	priv->pause = pause;
-	priv->plat = plat_dat;
 	netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
 
 	spin_lock_init(&priv->lock);
@@ -1839,15 +1853,10 @@
 
 	ret = register_netdev(ndev);
 	if (ret) {
-		pr_err("%s: ERROR %i registering the device\n",
-		       __func__, ret);
+		pr_err("%s: ERROR %i registering the device\n", __func__, ret);
 		goto error;
 	}
 
-	DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
-	    ndev->name, (ndev->features & NETIF_F_SG) ? "on" : "off",
-	    (ndev->features & NETIF_F_IP_CSUM) ? "on" : "off");
-
 	return priv;
 
 error:
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index c796de9..50ad5b8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -96,13 +96,11 @@
 
 	stmmac_default_data();
 
-	priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat);
+	priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat, addr);
 	if (!priv) {
-		pr_err("%s: main drivr probe failed", __func__);
+		pr_err("%s: main driver probe failed", __func__);
 		goto err_out;
 	}
-	priv->ioaddr = addr;
-	priv->dev->base_addr = (unsigned long)addr;
 	priv->dev->irq = pdev->irq;
 	priv->wol_irq = pdev->irq;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 1ac8324..3aad981 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -59,15 +59,19 @@
 		goto out_release_region;
 	}
 	plat_dat = pdev->dev.platform_data;
-	priv = stmmac_dvr_probe(&(pdev->dev), plat_dat);
-	if (!priv) {
-		pr_err("%s: main drivr probe failed", __func__);
-		goto out_unmap;
+
+	/* Custom initialisation (if needed)*/
+	if (plat_dat->init) {
+		ret = plat_dat->init(pdev);
+		if (unlikely(ret))
+			goto out_unmap;
 	}
 
-	priv->ioaddr = addr;
-	/* Set the I/O base addr */
-	priv->dev->base_addr = (unsigned long)addr;
+	priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr);
+	if (!priv) {
+		pr_err("%s: main driver probe failed", __func__);
+		goto out_unmap;
+	}
 
 	/* Get the MAC information */
 	priv->dev->irq = platform_get_irq_byname(pdev, "macirq");
@@ -92,13 +96,6 @@
 
 	platform_set_drvdata(pdev, priv->dev);
 
-	/* Custom initialisation */
-	if (priv->plat->init) {
-		ret = priv->plat->init(pdev);
-		if (unlikely(ret))
-			goto out_unmap;
-	}
-
 	pr_debug("STMMAC platform driver registration completed");
 
 	return 0;
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index 4d9a28f..cbc8df7 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -1122,7 +1122,7 @@
 	pdata = pdev->dev.platform_data;
 
 	if (external_switch || dumb_switch) {
-		strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
+		strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */
 		phy_id = pdev->id;
 	} else {
 		for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
@@ -1138,7 +1138,7 @@
 	if (phy_id == PHY_MAX_ADDR) {
 		dev_err(&pdev->dev, "no PHY present, falling back "
 					"to switch on MDIO bus 0\n");
-		strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
+		strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */
 		phy_id = pdev->id;
 	}
 
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 794ac30..4b2f545 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1009,7 +1009,7 @@
 	int			ret;
 
 	/* free and bail if we are shutting down */
-	if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) {
+	if (unlikely(!netif_running(ndev))) {
 		dev_kfree_skb_any(skb);
 		return;
 	}
@@ -1038,7 +1038,9 @@
 recycle:
 	ret = cpdma_chan_submit(priv->rxchan, skb, skb->data,
 			skb_tailroom(skb), GFP_KERNEL);
-	if (WARN_ON(ret < 0))
+
+	WARN_ON(ret == -ENOMEM);
+	if (unlikely(ret < 0))
 		dev_kfree_skb_any(skb);
 }
 
@@ -1600,8 +1602,9 @@
 		if (IS_ERR(priv->phydev)) {
 			dev_err(emac_dev, "could not connect to phy %s\n",
 				priv->phy_id);
+			ret = PTR_ERR(priv->phydev);
 			priv->phydev = NULL;
-			return PTR_ERR(priv->phydev);
+			return ret;
 		}
 
 		priv->link = 0;
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index ef7c9c1..af8b8fc 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -318,9 +318,9 @@
 
 	data->clk = clk_get(dev, NULL);
 	if (IS_ERR(data->clk)) {
-		data->clk = NULL;
 		dev_err(dev, "failed to get device clock\n");
 		ret = PTR_ERR(data->clk);
+		data->clk = NULL;
 		goto bail_out;
 	}
 
diff --git a/drivers/net/ethernet/toshiba/Kconfig b/drivers/net/ethernet/toshiba/Kconfig
index 0517647..74acb5c 100644
--- a/drivers/net/ethernet/toshiba/Kconfig
+++ b/drivers/net/ethernet/toshiba/Kconfig
@@ -5,7 +5,7 @@
 config NET_VENDOR_TOSHIBA
 	bool "Toshiba devices"
 	default y
-	depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB) || PPC_PS3
+	depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB || MIPS) || PPC_PS3
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y
 	  and read the Ethernet-HOWTO, available from
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index 4128d6b..cb35b14 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -2491,9 +2491,6 @@
 	if (dev->irq != 0)
 		free_irq(dev->irq, dev);
 
-	/* Power down the chip */
-	pci_set_power_state(vptr->pdev, PCI_D3hot);
-
 	velocity_free_rings(vptr);
 
 	vptr->flags &= (~VELOCITY_FLAGS_OPENED);
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 72a854f..41a8b5a 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -1416,7 +1416,8 @@
 	__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
 	udelay(50);
 
-	snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy);
+	snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT,
+		mdio_bus->id, plat->phy);
 	port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
 				   PHY_INTERFACE_MODE_MII);
 	if (IS_ERR(port->phydev)) {
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 1a1ca6c..466c58a 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -123,7 +123,7 @@
 	struct hv_device *device_obj = net_device_ctx->device_ctx;
 	int ret;
 
-	netif_stop_queue(net);
+	netif_tx_disable(net);
 
 	ret = rndis_filter_close(device_obj);
 	if (ret != 0)
@@ -151,10 +151,10 @@
 	int ret;
 	unsigned int i, num_pages, npg_data;
 
-	/* Add multipage for skb->data and additional one for RNDIS */
+	/* Add multipages for skb->data and additional 2 for RNDIS */
 	npg_data = (((unsigned long)skb->data + skb_headlen(skb) - 1)
 		>> PAGE_SHIFT) - ((unsigned long)skb->data >> PAGE_SHIFT) + 1;
-	num_pages = skb_shinfo(skb)->nr_frags + npg_data + 1;
+	num_pages = skb_shinfo(skb)->nr_frags + npg_data + 2;
 
 	/* Allocate a netvsc packet based on # of frags. */
 	packet = kzalloc(sizeof(struct hv_netvsc_packet) +
@@ -173,8 +173,8 @@
 				sizeof(struct hv_netvsc_packet) +
 				    (num_pages * sizeof(struct hv_page_buffer));
 
-	/* Setup the rndis header */
-	packet->page_buf_cnt = num_pages;
+	/* If the rndis msg goes beyond 1 page, we will add 1 later */
+	packet->page_buf_cnt = num_pages - 1;
 
 	/* Initialize it from the skb */
 	packet->total_data_buflen = skb->len;
@@ -256,7 +256,7 @@
 		schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
 	} else {
 		netif_carrier_off(net);
-		netif_stop_queue(net);
+		netif_tx_disable(net);
 	}
 }
 
@@ -298,7 +298,7 @@
 	skb->ip_summed = CHECKSUM_NONE;
 
 	net->stats.rx_packets++;
-	net->stats.rx_bytes += skb->len;
+	net->stats.rx_bytes += packet->total_data_buflen;
 
 	/*
 	 * Pass the skb back up. Network stack will deallocate the skb when it
@@ -337,7 +337,7 @@
 
 	nvdev->start_remove = true;
 	cancel_delayed_work_sync(&ndevctx->dwork);
-	netif_stop_queue(ndev);
+	netif_tx_disable(ndev);
 	rndis_filter_device_remove(hdev);
 
 	ndev->mtu = mtu;
@@ -460,7 +460,7 @@
 	cancel_delayed_work_sync(&ndev_ctx->dwork);
 
 	/* Stop outbound asap */
-	netif_stop_queue(net);
+	netif_tx_disable(net);
 
 	unregister_netdev(net);
 
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index da181f9..133b7fb 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -321,6 +321,25 @@
 	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
 
 	pkt->total_data_buflen -= data_offset;
+
+	/*
+	 * Make sure we got a valid RNDIS message, now total_data_buflen
+	 * should be the data packet size plus the trailer padding size
+	 */
+	if (pkt->total_data_buflen < rndis_pkt->data_len) {
+		netdev_err(dev->net_dev->ndev, "rndis message buffer "
+			   "overflow detected (got %u, min %u)"
+			   "...dropping this message!\n",
+			   pkt->total_data_buflen, rndis_pkt->data_len);
+		return;
+	}
+
+	/*
+	 * Remove the rndis trailer padding from rndis packet message
+	 * rndis_pkt->data_len tell us the real data length, we only copy
+	 * the data packet to the stack, without the rndis trailer padding
+	 */
+	pkt->total_data_buflen = rndis_pkt->data_len;
 	pkt->data = (void *)((unsigned long)pkt->data + data_offset);
 
 	pkt->is_data_pkt = true;
@@ -778,6 +797,19 @@
 			(unsigned long)rndisMessage & (PAGE_SIZE-1);
 	pkt->page_buf[0].len = rndisMessageSize;
 
+	/* Add one page_buf if the rndis msg goes beyond page boundary */
+	if (pkt->page_buf[0].offset + rndisMessageSize > PAGE_SIZE) {
+		int i;
+		for (i = pkt->page_buf_cnt; i > 1; i--)
+			pkt->page_buf[i] = pkt->page_buf[i-1];
+		pkt->page_buf_cnt++;
+		pkt->page_buf[0].len = PAGE_SIZE - pkt->page_buf[0].offset;
+		pkt->page_buf[1].pfn = virt_to_phys((void *)((ulong)
+			rndisMessage + pkt->page_buf[0].len)) >> PAGE_SHIFT;
+		pkt->page_buf[1].offset = 0;
+		pkt->page_buf[1].len = rndisMessageSize - pkt->page_buf[0].len;
+	}
+
 	/* Save the packet send completion and context */
 	filterPacket->completion = pkt->completion.send.send_completion;
 	filterPacket->completion_ctx =
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index c81f136..0856e1b 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -30,16 +30,16 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IC1001 PHY drivers");
+MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers");
 MODULE_AUTHOR("Michael Barkowski");
 MODULE_LICENSE("GPL");
 
-/* IP101A/IP1001 */
-#define IP10XX_SPEC_CTRL_STATUS		16  /* Spec. Control Register */
-#define IP1001_SPEC_CTRL_STATUS_2	20  /* IP1001 Spec. Control Reg 2 */
-#define IP1001_PHASE_SEL_MASK		3 /* IP1001 RX/TXPHASE_SEL */
-#define IP1001_APS_ON			11  /* IP1001 APS Mode  bit */
-#define IP101A_APS_ON			2   /* IP101A APS Mode bit */
+/* IP101A/G - IP1001 */
+#define IP10XX_SPEC_CTRL_STATUS		16	/* Spec. Control Register */
+#define IP1001_SPEC_CTRL_STATUS_2	20	/* IP1001 Spec. Control Reg 2 */
+#define IP1001_PHASE_SEL_MASK		3	/* IP1001 RX/TXPHASE_SEL */
+#define IP1001_APS_ON			11	/* IP1001 APS Mode  bit */
+#define IP101A_G_APS_ON			2	/* IP101A/G APS Mode bit */
 
 static int ip175c_config_init(struct phy_device *phydev)
 {
@@ -98,20 +98,24 @@
 
 static int ip1xx_reset(struct phy_device *phydev)
 {
-	int err, bmcr;
+	int bmcr;
 
 	/* Software Reset PHY */
 	bmcr = phy_read(phydev, MII_BMCR);
+	if (bmcr < 0)
+		return bmcr;
 	bmcr |= BMCR_RESET;
-	err = phy_write(phydev, MII_BMCR, bmcr);
-	if (err < 0)
-		return err;
+	bmcr = phy_write(phydev, MII_BMCR, bmcr);
+	if (bmcr < 0)
+		return bmcr;
 
 	do {
 		bmcr = phy_read(phydev, MII_BMCR);
+		if (bmcr < 0)
+			return bmcr;
 	} while (bmcr & BMCR_RESET);
 
-	return err;
+	return 0;
 }
 
 static int ip1001_config_init(struct phy_device *phydev)
@@ -124,7 +128,10 @@
 
 	/* Enable Auto Power Saving mode */
 	c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2);
+	if (c < 0)
+		return c;
 	c |= IP1001_APS_ON;
+	c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c);
 	if (c < 0)
 		return c;
 
@@ -132,14 +139,19 @@
 		/* Additional delay (2ns) used to adjust RX clock phase
 		 * at RGMII interface */
 		c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
+		if (c < 0)
+			return c;
+
 		c |= IP1001_PHASE_SEL_MASK;
 		c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
+		if (c < 0)
+			return c;
 	}
 
-	return c;
+	return 0;
 }
 
-static int ip101a_config_init(struct phy_device *phydev)
+static int ip101a_g_config_init(struct phy_device *phydev)
 {
 	int c;
 
@@ -149,7 +161,7 @@
 
 	/* Enable Auto Power Saving mode */
 	c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
-	c |= IP101A_APS_ON;
+	c |= IP101A_G_APS_ON;
 	return c;
 }
 
@@ -191,6 +203,7 @@
 	.phy_id_mask	= 0x0ffffff0,
 	.features	= PHY_GBIT_FEATURES | SUPPORTED_Pause |
 			  SUPPORTED_Asym_Pause,
+	.flags		= PHY_HAS_INTERRUPT,
 	.config_init	= &ip1001_config_init,
 	.config_aneg	= &genphy_config_aneg,
 	.read_status	= &genphy_read_status,
@@ -199,13 +212,14 @@
 	.driver		= { .owner = THIS_MODULE,},
 };
 
-static struct phy_driver ip101a_driver = {
+static struct phy_driver ip101a_g_driver = {
 	.phy_id		= 0x02430c54,
-	.name		= "ICPlus IP101A",
+	.name		= "ICPlus IP101A/G",
 	.phy_id_mask	= 0x0ffffff0,
 	.features	= PHY_BASIC_FEATURES | SUPPORTED_Pause |
 			  SUPPORTED_Asym_Pause,
-	.config_init	= &ip101a_config_init,
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_init	= &ip101a_g_config_init,
 	.config_aneg	= &genphy_config_aneg,
 	.read_status	= &genphy_read_status,
 	.suspend	= genphy_suspend,
@@ -221,7 +235,7 @@
 	if (ret < 0)
 		return -ENODEV;
 
-	ret = phy_driver_register(&ip101a_driver);
+	ret = phy_driver_register(&ip101a_g_driver);
 	if (ret < 0)
 		return -ENODEV;
 
@@ -231,7 +245,7 @@
 static void __exit icplus_exit(void)
 {
 	phy_driver_unregister(&ip1001_driver);
-	phy_driver_unregister(&ip101a_driver);
+	phy_driver_unregister(&ip101a_g_driver);
 	phy_driver_unregister(&ip175c_driver);
 }
 
@@ -241,6 +255,7 @@
 static struct mdio_device_id __maybe_unused icplus_tbl[] = {
 	{ 0x02430d80, 0x0ffffff0 },
 	{ 0x02430d90, 0x0ffffff0 },
+	{ 0x02430c54, 0x0ffffff0 },
 	{ }
 };
 
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index edfa15d..486b404 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2024,14 +2024,22 @@
 			continue;
 		}
 		if (PPP_MP_CB(p)->sequence != seq) {
+			u32 oldseq;
 			/* Fragment `seq' is missing.  If it is after
 			   minseq, it might arrive later, so stop here. */
 			if (seq_after(seq, minseq))
 				break;
 			/* Fragment `seq' is lost, keep going. */
 			lost = 1;
+			oldseq = seq;
 			seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
 				minseq + 1: PPP_MP_CB(p)->sequence;
+
+			if (ppp->debug & 1)
+				netdev_printk(KERN_DEBUG, ppp->dev,
+					      "lost frag %u..%u\n",
+					      oldseq, seq-1);
+
 			goto again;
 		}
 
@@ -2076,6 +2084,10 @@
 			struct sk_buff *tmp2;
 
 			skb_queue_reverse_walk_from_safe(list, p, tmp2) {
+				if (ppp->debug & 1)
+					netdev_printk(KERN_DEBUG, ppp->dev,
+						      "discarding frag %u\n",
+						      PPP_MP_CB(p)->sequence);
 				__skb_unlink(p, list);
 				kfree_skb(p);
 			}
@@ -2091,6 +2103,17 @@
 		/* If we have discarded any fragments,
 		   signal a receive error. */
 		if (PPP_MP_CB(head)->sequence != ppp->nextseq) {
+			skb_queue_walk_safe(list, p, tmp) {
+				if (p == head)
+					break;
+				if (ppp->debug & 1)
+					netdev_printk(KERN_DEBUG, ppp->dev,
+						      "discarding frag %u\n",
+						      PPP_MP_CB(p)->sequence);
+				__skb_unlink(p, list);
+				kfree_skb(p);
+			}
+
 			if (ppp->debug & 1)
 				netdev_printk(KERN_DEBUG, ppp->dev,
 					      "  missed pkts %u..%u\n",
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
index c7e0149..45550d4 100644
--- a/drivers/net/tokenring/Kconfig
+++ b/drivers/net/tokenring/Kconfig
@@ -7,7 +7,6 @@
 	bool "Token Ring driver support"
 	depends on NETDEVICES && !UML
 	depends on (PCI || ISA || MCA || CCW || PCMCIA)
-	select LLC
 	help
 	  Token Ring is IBM's way of communication on a local network; the
 	  rest of the world uses Ethernet. To participate on a Token Ring
@@ -20,6 +19,10 @@
 
 if TR
 
+config WANT_LLC
+	def_bool y
+	select LLC
+
 config PCMCIA_IBMTR
 	tristate "IBM PCMCIA tokenring adapter support"
 	depends on IBMTR!=y && PCMCIA
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 41a61ef..90a3002 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -573,6 +573,13 @@
 	.driver_info = 0,
 },
 
+/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
+{
+	USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+	.driver_info		= 0,
+},
+
 /*
  * WHITELIST!!!
  *
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 304fe78..e1324b4 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1632,7 +1632,7 @@
 	struct hso_serial *serial = get_serial_by_tty(tty);
 	struct hso_tiocmget  *tiocmget = serial->tiocmget;
 
-	memset(&icount, 0, sizeof(struct serial_icounter_struct));
+	memset(icount, 0, sizeof(struct serial_icounter_struct));
 
 	if (!tiocmget)
 		 return -ENOENT;
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index e84662d..dd78c4c 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -60,6 +60,7 @@
 #define USB_PRODUCT_IPHONE_3GS  0x1294
 #define USB_PRODUCT_IPHONE_4	0x1297
 #define USB_PRODUCT_IPHONE_4_VZW 0x129c
+#define USB_PRODUCT_IPHONE_4S	0x12a0
 
 #define IPHETH_USBINTF_CLASS    255
 #define IPHETH_USBINTF_SUBCLASS 253
@@ -103,6 +104,10 @@
 		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW,
 		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
 		IPHETH_USBINTF_PROTO) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(
+		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S,
+		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+		IPHETH_USBINTF_PROTO) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, ipheth_table);
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c
index f701d41..c3197ce 100644
--- a/drivers/net/usb/zaurus.c
+++ b/drivers/net/usb/zaurus.c
@@ -316,6 +316,11 @@
 	ZAURUS_MASTER_INTERFACE,
 	.driver_info = ZAURUS_PXA_INFO,
 }, {
+	/* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */
+	USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+	.driver_info = (unsigned long) &bogus_mdlm_info,
+}, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
@@ -349,6 +354,13 @@
 	ZAURUS_MASTER_INTERFACE,
 	.driver_info = OLYMPUS_MXL_INFO,
 },
+
+/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
+{
+	USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+	.driver_info = (unsigned long) &bogus_mdlm_info,
+},
 	{ },		// END
 };
 MODULE_DEVICE_TABLE(usb, products);
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 49f4667..4a34028 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -422,7 +422,9 @@
 	unregister_netdevice_queue(peer, head);
 }
 
-static const struct nla_policy veth_policy[VETH_INFO_MAX + 1];
+static const struct nla_policy veth_policy[VETH_INFO_MAX + 1] = {
+	[VETH_INFO_PEER]	= { .len = sizeof(struct ifinfomsg) },
+};
 
 static struct rtnl_link_ops veth_link_ops = {
 	.kind		= DRV_NAME,
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index de7fc34..3dcd385 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -843,8 +843,8 @@
 				/* for simplicity, don't copy L4 headers */
 				ctx->l4_hdr_size = 0;
 			}
-			ctx->copy_size = ctx->eth_ip_hdr_size +
-					 ctx->l4_hdr_size;
+			ctx->copy_size = min(ctx->eth_ip_hdr_size +
+					 ctx->l4_hdr_size, skb->len);
 		} else {
 			ctx->eth_ip_hdr_size = 0;
 			ctx->l4_hdr_size = 0;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index ee77595..87db1ee 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1037,13 +1037,16 @@
 
 	/*
 	 * Workaround for early ACK timeouts, add an offset to match the
-	 * initval's 64us ack timeout value.
+	 * initval's 64us ack timeout value. Use 48us for the CTS timeout.
 	 * This was initially only meant to work around an issue with delayed
 	 * BA frames in some implementations, but it has been found to fix ACK
 	 * timeout issues in other cases as well.
 	 */
-	if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
+	if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) {
 		acktimeout += 64 - sifstime - ah->slottime;
+		ctstimeout += 48 - sifstime - ah->slottime;
+	}
+
 
 	ath9k_hw_set_sifs_time(ah, sifstime);
 	ath9k_hw_setslottime(ah, slottime);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index abf9435..53a005d 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -822,6 +822,11 @@
 		ARRAY_SIZE(ath9k_tpt_blink));
 #endif
 
+	INIT_WORK(&sc->hw_reset_work, ath_reset_work);
+	INIT_WORK(&sc->hw_check_work, ath_hw_check);
+	INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+	INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
+
 	/* Register with mac80211 */
 	error = ieee80211_register_hw(hw);
 	if (error)
@@ -840,10 +845,6 @@
 			goto error_world;
 	}
 
-	INIT_WORK(&sc->hw_reset_work, ath_reset_work);
-	INIT_WORK(&sc->hw_check_work, ath_hw_check);
-	INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
-	INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
 	sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 
 	ath_init_leds(sc);
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index b3c3798..a427a16 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -694,7 +694,7 @@
 		return rate;
 
 	/* This should not happen */
-	WARN_ON(1);
+	WARN_ON_ONCE(1);
 
 	rate = ath_rc_priv->valid_rate_index[0];
 
@@ -1346,7 +1346,7 @@
 	fc = hdr->frame_control;
 	for (i = 0; i < sc->hw->max_rates; i++) {
 		struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
-		if (!rate->count)
+		if (rate->idx < 0 || !rate->count)
 			break;
 
 		final_ts_idx = i;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 0e666fb..7e1a91a 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -822,6 +822,14 @@
 		(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
 		 ATH9K_RXERR_KEYMISS));
 
+	/*
+	 * Key miss events are only relevant for pairwise keys where the
+	 * descriptor does contain a valid key index. This has been observed
+	 * mostly with CCMP encryption.
+	 */
+	if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
+		rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
+
 	if (!rx_stats->rs_datalen)
 		return false;
         /*
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index c664c27..63bbc60 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -91,6 +91,7 @@
 		tx_cmd->tid_tspec = qc[0] & 0xf;
 		tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
 	} else {
+		tx_cmd->tid_tspec = IWL_TID_NON_QOS;
 		if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
 			tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
 		else
@@ -620,7 +621,7 @@
 	sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit =
 		sta_priv->max_agg_bufsize;
 
-	IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
+	IWL_DEBUG_HT(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
 		 sta->addr, tid);
 
 	return iwl_send_lq_cmd(priv, ctx,
@@ -808,6 +809,8 @@
 	u32 status = le16_to_cpu(tx_resp->status.status);
 	int i;
 
+	WARN_ON(tid == IWL_TID_NON_QOS);
+
 	if (agg->wait_for_ba)
 		IWL_DEBUG_TX_REPLY(priv,
 			"got tx response w/o block-ack\n");
@@ -1035,10 +1038,13 @@
 		}
 
 		__skb_queue_head_init(&skbs);
-		priv->tid_data[sta_id][tid].next_reclaimed = next_reclaimed;
 
-		IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
-					  next_reclaimed);
+		if (tid != IWL_TID_NON_QOS) {
+			priv->tid_data[sta_id][tid].next_reclaimed =
+				next_reclaimed;
+			IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
+						  next_reclaimed);
+		}
 
 		/*we can free until ssn % q.n_bd not inclusive */
 		WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 265de39..f822ac4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -815,6 +815,7 @@
 
 #define	IWL_INVALID_STATION 	255
 #define IWL_MAX_TID_COUNT	8
+#define IWL_TID_NON_QOS IWL_MAX_TID_COUNT
 
 #define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2)
 #define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8)
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 67d6e32..324d06d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -1262,6 +1262,7 @@
 	txq->time_stamp = jiffies;
 
 	if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
+		     tid != IWL_TID_NON_QOS &&
 		     txq_id != trans_pcie->agg_txq[sta_id][tid])) {
 		/*
 		 * FIXME: this is a uCode bug which need to be addressed,
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c3b6c46..5b2972b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -841,7 +841,12 @@
 		ret = mwifiex_set_rf_channel(priv, channel,
 						priv->adapter->channel_type);
 
-	ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);	/* Disable keys */
+	/* As this is new association, clear locally stored
+	 * keys and security related flags */
+	priv->sec_info.wpa_enabled = false;
+	priv->sec_info.wpa2_enabled = false;
+	priv->wep_key_curr_index = 0;
+	ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
 
 	if (mode == NL80211_IFTYPE_ADHOC) {
 		/* "privacy" is set only for ad-hoc mode */
@@ -886,6 +891,7 @@
 			dev_dbg(priv->adapter->dev,
 				"info: setting wep encryption"
 				" with key len %d\n", sme->key_len);
+			priv->wep_key_curr_index = sme->key_idx;
 			ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
 							sme->key_idx, 0);
 		}
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index e05b417..1d0ec57 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -382,7 +382,8 @@
 
 	adapter->if_ops.cleanup_if(adapter);
 
-	dev_kfree_skb_any(adapter->sleep_cfm);
+	if (adapter->sleep_cfm)
+		dev_kfree_skb_any(adapter->sleep_cfm);
 }
 
 /*
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 84be196..b728f54 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -822,7 +822,9 @@
 			continue;
 
 		rtnl_lock();
-		mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
+		if (priv->wdev && priv->netdev)
+			mwifiex_del_virtual_intf(priv->wdev->wiphy,
+						 priv->netdev);
 		rtnl_unlock();
 	}
 
@@ -830,9 +832,11 @@
 	if (!priv)
 		goto exit_remove;
 
-	wiphy_unregister(priv->wdev->wiphy);
-	wiphy_free(priv->wdev->wiphy);
-	kfree(priv->wdev);
+	if (priv->wdev) {
+		wiphy_unregister(priv->wdev->wiphy);
+		wiphy_free(priv->wdev->wiphy);
+		kfree(priv->wdev);
+	}
 
 	mwifiex_terminate_workqueue(adapter);
 
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 470ca75..b0fbf5d 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -54,7 +54,7 @@
 int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
 {
 	bool cancel_flag = false;
-	int status = adapter->cmd_wait_q.status;
+	int status;
 	struct cmd_ctrl_node *cmd_queued;
 
 	if (!adapter->cmd_queued)
@@ -79,6 +79,8 @@
 		mwifiex_cancel_pending_ioctl(adapter);
 		dev_dbg(adapter->dev, "cmd cancel\n");
 	}
+
+	status = adapter->cmd_wait_q.status;
 	adapter->cmd_wait_q.status = 0;
 
 	return status;
@@ -240,6 +242,8 @@
 
 		if (!netif_queue_stopped(priv->netdev))
 			mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+		if (netif_carrier_ok(priv->netdev))
+			netif_carrier_off(priv->netdev);
 
 		/* Clear any past association response stored for
 		 * application retrieval */
@@ -271,6 +275,8 @@
 
 		if (!netif_queue_stopped(priv->netdev))
 			mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+		if (netif_carrier_ok(priv->netdev))
+			netif_carrier_off(priv->netdev);
 
 		if (!ret) {
 			dev_dbg(adapter->dev, "info: network found in scan"
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 22a1a8f..7bef66d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -514,9 +514,9 @@
 
 static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
 {
-	int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
-	int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
-	int rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2);
+	s8 rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
+	s8 rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
+	s8 rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2);
 	u16 eeprom;
 	u8 offset0;
 	u8 offset1;
@@ -552,7 +552,7 @@
 	 * which gives less energy...
 	 */
 	rssi0 = max(rssi0, rssi1);
-	return max(rssi0, rssi2);
+	return (int)max(rssi0, rssi2);
 }
 
 void rt2800_process_rxwi(struct queue_entry *entry,
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 39e0907..9245d88 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1501,7 +1501,7 @@
 		return err;
 	}
 
-	return 1;
+	return 0;
 }
 
 static int rtl_pci_start(struct ieee80211_hw *hw)
@@ -1870,7 +1870,7 @@
 	}
 
 	/* Init PCI sw */
-	err = !rtl_pci_init(hw, pdev);
+	err = rtl_pci_init(hw, pdev);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("Failed to init PCI.\n"));
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 0a70149..98a574a 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -866,6 +866,14 @@
 
 	ZD_ASSERT(frag_len <= 0xffff);
 
+	/*
+	 * Firmware computes the duration itself (for all frames except PSPoll)
+	 * and needs the field set to 0 at input, otherwise firmware messes up
+	 * duration_id and sets bits 14 and 15 on.
+	 */
+	if (!ieee80211_is_pspoll(hdr->frame_control))
+		hdr->duration_id = 0;
+
 	txrate = ieee80211_get_tx_rate(mac->hw, info);
 
 	cs->modulation = txrate->hw_value;
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h
index a9c46cc..8c33491 100644
--- a/drivers/parisc/iommu-helpers.h
+++ b/drivers/parisc/iommu-helpers.h
@@ -1,3 +1,5 @@
+#include <linux/prefetch.h>
+
 /**
  * iommu_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir.
  * @ioc: The I/O Controller.
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 0321fa3..0dab5ec 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -347,8 +347,6 @@
 			return rc;
 	}
 
-	pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
-
 	iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
 	pci_cfg_access_lock(dev);
 	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
@@ -466,6 +464,7 @@
 		return -EIO;
 
 	pgsz &= ~(pgsz - 1);
+	pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
 
 	nres = 0;
 	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 7cc9e2f..71eac9c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -651,6 +651,11 @@
 	dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
 		secondary, subordinate, pass);
 
+	if (!primary && (primary != bus->number) && secondary && subordinate) {
+		dev_warn(&dev->dev, "Primary bus is hard wired to 0\n");
+		primary = bus->number;
+	}
+
 	/* Check if setup is sensible at all */
 	if (!pass &&
 	    (primary != bus->number || secondary <= bus->number)) {
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 6def362..ef8b18c 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -77,6 +77,7 @@
 }
 EXPORT_SYMBOL(pci_remove_bus);
 
+static void __pci_remove_behind_bridge(struct pci_dev *dev);
 /**
  * pci_remove_bus_device - remove a PCI device and any children
  * @dev: the device to remove
@@ -94,7 +95,7 @@
 	if (dev->subordinate) {
 		struct pci_bus *b = dev->subordinate;
 
-		pci_remove_behind_bridge(dev);
+		__pci_remove_behind_bridge(dev);
 		pci_remove_bus(b);
 		dev->subordinate = NULL;
 	}
@@ -107,6 +108,24 @@
 	__pci_remove_bus_device(dev);
 }
 
+static void __pci_remove_behind_bridge(struct pci_dev *dev)
+{
+	struct list_head *l, *n;
+
+	if (dev->subordinate)
+		list_for_each_safe(l, n, &dev->subordinate->devices)
+			__pci_remove_bus_device(pci_dev_b(l));
+}
+
+static void pci_stop_behind_bridge(struct pci_dev *dev)
+{
+	struct list_head *l, *n;
+
+	if (dev->subordinate)
+		list_for_each_safe(l, n, &dev->subordinate->devices)
+			pci_stop_bus_device(pci_dev_b(l));
+}
+
 /**
  * pci_remove_behind_bridge - remove all devices behind a PCI bridge
  * @dev: PCI bridge device
@@ -117,11 +136,8 @@
  */
 void pci_remove_behind_bridge(struct pci_dev *dev)
 {
-	struct list_head *l, *n;
-
-	if (dev->subordinate)
-		list_for_each_safe(l, n, &dev->subordinate->devices)
-			__pci_remove_bus_device(pci_dev_b(l));
+	pci_stop_behind_bridge(dev);
+	__pci_remove_behind_bridge(dev);
 }
 
 static void pci_stop_bus_devices(struct pci_bus *bus)
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 7cf3d2f..1620088 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -189,7 +189,7 @@
 
 	if (verbose_request)
 		dev_info(&pdev->xdev->dev,
-			 "read dev=%04x:%02x:%02x.%01x - offset %x size %d\n",
+			 "read dev=%04x:%02x:%02x.%d - offset %x size %d\n",
 			 pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
 			 PCI_FUNC(devfn), where, size);
 
@@ -228,7 +228,7 @@
 
 	if (verbose_request)
 		dev_info(&pdev->xdev->dev,
-			 "write dev=%04x:%02x:%02x.%01x - "
+			 "write dev=%04x:%02x:%02x.%d - "
 			 "offset %x size %d val %x\n",
 			 pci_domain_nr(bus), bus->number,
 			 PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
@@ -432,7 +432,7 @@
 		d = pci_scan_single_device(b, devfn);
 		if (d)
 			dev_info(&pdev->xdev->dev, "New device on "
-				 "%04x:%02x:%02x.%02x found.\n", domain, bus,
+				 "%04x:%02x:%02x.%d found.\n", domain, bus,
 				 PCI_SLOT(devfn), PCI_FUNC(devfn));
 	}
 
@@ -1041,7 +1041,7 @@
 		pci_dev = pci_get_slot(pci_bus, PCI_DEVFN(slot, func));
 		if (!pci_dev) {
 			dev_dbg(&pdev->xdev->dev,
-				"Cannot get PCI device %04x:%02x:%02x.%02x\n",
+				"Cannot get PCI device %04x:%02x:%02x.%d\n",
 				domain, bus, slot, func);
 			continue;
 		}
@@ -1049,7 +1049,7 @@
 		pci_dev_put(pci_dev);
 
 		dev_dbg(&pdev->xdev->dev,
-			"PCI device %04x:%02x:%02x.%02x removed.\n",
+			"PCI device %04x:%02x:%02x.%d removed.\n",
 			domain, bus, slot, func);
 	}
 
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index a87e272..64d433e 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -328,21 +328,15 @@
 			goto err1;
 	}
 
-	if (ret) {
-		while (--i >= 0)
-			soc_pcmcia_remove_one(&sinfo->skt[i]);
-		kfree(sinfo);
-		clk_put(clk);
-	} else {
-		pxa2xx_configure_sockets(&dev->dev);
-		dev_set_drvdata(&dev->dev, sinfo);
-	}
+	pxa2xx_configure_sockets(&dev->dev);
+	dev_set_drvdata(&dev->dev, sinfo);
 
 	return 0;
 
 err1:
 	while (--i >= 0)
 		soc_pcmcia_remove_one(&sinfo->skt[i]);
+	clk_put(clk);
 	kfree(sinfo);
 err0:
 	return ret;
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 8fe15cf..894cd5e 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -189,7 +189,7 @@
 	pindesc->pctldev = pctldev;
 
 	/* Copy basic pin info */
-	if (pindesc->name) {
+	if (name) {
 		pindesc->name = name;
 	} else {
 		pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number);
diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c
index 42a7d60..7481146 100644
--- a/drivers/platform/x86/ibm_rtl.c
+++ b/drivers/platform/x86/ibm_rtl.c
@@ -33,6 +33,8 @@
 #include <linux/mutex.h>
 #include <asm/bios_ebda.h>
 
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
 static bool force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -83,19 +85,6 @@
 static u8 rtl_cmd_type;
 static u8 rtl_cmd_width;
 
-#ifndef readq
-static inline __u64 readq(const volatile void __iomem *addr)
-{
-	const volatile u32 __iomem *p = addr;
-	u32 low, high;
-
-	low = readl(p);
-	high = readl(p + 1);
-
-	return low + ((u64)high << 32);
-}
-#endif
-
 static void __iomem *rtl_port_map(phys_addr_t addr, unsigned long len)
 {
 	if (rtl_cmd_type == RTL_ADDR_TYPE_MMIO)
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 809a3ae..88a98cf 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -77,6 +77,8 @@
 #include <asm/processor.h>
 #include "intel_ips.h"
 
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
 #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32
 
 /*
@@ -344,19 +346,6 @@
 static bool
 ips_gpu_turbo_enabled(struct ips_driver *ips);
 
-#ifndef readq
-static inline __u64 readq(const volatile void __iomem *addr)
-{
-	const volatile u32 __iomem *p = addr;
-	u32 low, high;
-
-	low = readl(p);
-	high = readl(p + 1);
-
-	return low + ((u64)high << 32);
-}
-#endif
-
 /**
  * ips_cpu_busy - is CPU busy?
  * @ips: IPS driver struct
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 98bf567..1ed6ea0 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -62,11 +62,10 @@
 
 #define BQ27500_REG_SOC			0x2C
 #define BQ27500_REG_DCAP		0x3C /* Design capacity */
-#define BQ27500_FLAG_DSG		BIT(0) /* Discharging */
+#define BQ27500_FLAG_DSC		BIT(0)
 #define BQ27500_FLAG_SOCF		BIT(1) /* State-of-Charge threshold final */
 #define BQ27500_FLAG_SOC1		BIT(2) /* State-of-Charge threshold 1 */
-#define BQ27500_FLAG_CHG		BIT(8) /* Charging */
-#define BQ27500_FLAG_FC			BIT(9) /* Fully charged */
+#define BQ27500_FLAG_FC			BIT(9)
 
 #define BQ27000_RS			20 /* Resistor sense */
 
@@ -312,7 +311,7 @@
 	struct bq27x00_reg_cache cache = {0, };
 	bool is_bq27500 = di->chip == BQ27500;
 
-	cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500);
+	cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
 	if (cache.flags >= 0) {
 		if (!is_bq27500 && (cache.flags & BQ27000_FLAG_CI)) {
 			dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
@@ -401,14 +400,10 @@
 	if (di->chip == BQ27500) {
 		if (di->cache.flags & BQ27500_FLAG_FC)
 			status = POWER_SUPPLY_STATUS_FULL;
-		else if (di->cache.flags & BQ27500_FLAG_DSG)
+		else if (di->cache.flags & BQ27500_FLAG_DSC)
 			status = POWER_SUPPLY_STATUS_DISCHARGING;
-		else if (di->cache.flags & BQ27500_FLAG_CHG)
-			status = POWER_SUPPLY_STATUS_CHARGING;
-		else if (power_supply_am_i_supplied(&di->bat))
-			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 		else
-			status = POWER_SUPPLY_STATUS_UNKNOWN;
+			status = POWER_SUPPLY_STATUS_CHARGING;
 	} else {
 		if (di->cache.flags & BQ27000_FLAG_FC)
 			status = POWER_SUPPLY_STATUS_FULL;
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
index 0378d01..88fd971 100644
--- a/drivers/power/charger-manager.c
+++ b/drivers/power/charger-manager.c
@@ -974,10 +974,11 @@
 	return 0;
 }
 
-const struct platform_device_id charger_manager_id[] = {
+static const struct platform_device_id charger_manager_id[] = {
 	{ "charger-manager", 0 },
 	{ },
 };
+MODULE_DEVICE_TABLE(platform, charger_manager_id);
 
 static int cm_suspend_prepare(struct device *dev)
 {
@@ -1069,4 +1070,3 @@
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
 MODULE_DESCRIPTION("Charger Manager");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("charger-manager");
diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c
index b15b575..c53dd12 100644
--- a/drivers/power/lp8727_charger.c
+++ b/drivers/power/lp8727_charger.c
@@ -464,6 +464,7 @@
 
 static const struct i2c_device_id lp8727_ids[] = {
 	{"lp8727", 0},
+	{ }
 };
 
 static struct i2c_driver lp8727_driver = {
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index df33530..28b81ae 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -196,7 +196,7 @@
 };
 
 static const unsigned int LDO13_table[] = {
-	1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0, 0,
+	1200000, 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0,
 };
 
 static const unsigned int LDO13_suspend_table[] = {
@@ -389,10 +389,10 @@
 	PM8607_LDO( 7,         LDO7, 0, 3, SUPPLIES_EN12, 1),
 	PM8607_LDO( 8,         LDO8, 0, 3, SUPPLIES_EN12, 2),
 	PM8607_LDO( 9,         LDO9, 0, 3, SUPPLIES_EN12, 3),
-	PM8607_LDO(10,        LDO10, 0, 3, SUPPLIES_EN12, 4),
+	PM8607_LDO(10,        LDO10, 0, 4, SUPPLIES_EN12, 4),
 	PM8607_LDO(12,        LDO12, 0, 4, SUPPLIES_EN12, 5),
 	PM8607_LDO(13, VIBRATOR_SET, 1, 3,  VIBRATOR_SET, 0),
-	PM8607_LDO(14,        LDO14, 0, 4, SUPPLIES_EN12, 6),
+	PM8607_LDO(14,        LDO14, 0, 3, SUPPLIES_EN12, 6),
 };
 
 static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index b06a239..d0e1180 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -150,7 +150,7 @@
 	if (ret != 0)
 		return ret;
 	val &= MAX8649_VOL_MASK;
-	voltage = max8649_list_voltage(rdev, (unsigned char)ret); /* uV */
+	voltage = max8649_list_voltage(rdev, (unsigned char)val); /* uV */
 
 	/* get rate */
 	ret = regmap_read(info->regmap, MAX8649_RAMP, &val);
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c
index 80ecafe..62dcd0a 100644
--- a/drivers/regulator/mc13xxx-regulator-core.c
+++ b/drivers/regulator/mc13xxx-regulator-core.c
@@ -254,6 +254,7 @@
 
 	return num;
 }
+EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt);
 
 struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
 	struct platform_device *pdev, struct mc13xxx_regulator *regulators,
@@ -291,6 +292,7 @@
 
 	return data;
 }
+EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt);
 #endif
 
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index a3ad957..ee3c122 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -307,8 +307,12 @@
 		device_init_wakeup(&pdev->dev, 1);
 
 	platform_set_drvdata(pdev, rtc);
-	rtc->rtt = (void __force __iomem *) (AT91_VA_BASE_SYS - AT91_BASE_SYS);
-	rtc->rtt += r->start;
+	rtc->rtt = ioremap(r->start, resource_size(r));
+	if (!rtc->rtt) {
+		dev_err(&pdev->dev, "failed to map registers, aborting.\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
 
 	mr = rtt_readl(rtc, MR);
 
@@ -326,7 +330,7 @@
 				&at91_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtcdev)) {
 		ret = PTR_ERR(rtc->rtcdev);
-		goto fail;
+		goto fail_register;
 	}
 
 	/* register irq handler after we know what name we'll use */
@@ -351,6 +355,8 @@
 
 	return 0;
 
+fail_register:
+	iounmap(rtc->rtt);
 fail:
 	platform_set_drvdata(pdev, NULL);
 	kfree(rtc);
@@ -371,6 +377,7 @@
 
 	rtc_device_unregister(rtc->rtcdev);
 
+	iounmap(rtc->rtt);
 	platform_set_drvdata(pdev, NULL);
 	kfree(rtc);
 	return 0;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 70880be..2617b1e 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -18,12 +18,12 @@
 #include <linux/hdreg.h>	/* HDIO_GETGEO			    */
 #include <linux/bio.h>
 #include <linux/module.h>
+#include <linux/compat.h>
 #include <linux/init.h>
 
 #include <asm/debug.h>
 #include <asm/idals.h>
 #include <asm/ebcdic.h>
-#include <asm/compat.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/cio.h>
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index f1a2016..792c69e 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -13,6 +13,7 @@
 #define KMSG_COMPONENT "dasd"
 
 #include <linux/interrupt.h>
+#include <linux/compat.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/blkpg.h>
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 934458a..e71a50d 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -87,6 +87,7 @@
 	struct tty_struct *tty;	      /* pointer to tty structure if present */
 	struct raw3215_req *queued_read; /* pointer to queued read requests */
 	struct raw3215_req *queued_write;/* pointer to queued write requests */
+	struct tasklet_struct tlet;   /* tasklet to invoke tty_wakeup */
 	wait_queue_head_t empty_wait; /* wait queue for flushing */
 	struct timer_list timer;      /* timer for delayed output */
 	int line_pos;		      /* position on the line (for tabs) */
@@ -334,19 +335,23 @@
 }
 
 /*
+ * Call tty_wakeup from tasklet context
+ */
+static void raw3215_wakeup(unsigned long data)
+{
+	struct raw3215_info *raw = (struct raw3215_info *) data;
+	tty_wakeup(raw->tty);
+}
+
+/*
  * Try to start the next IO and wake up processes waiting on the tty.
  */
 static void raw3215_next_io(struct raw3215_info *raw)
 {
-	struct tty_struct *tty;
-
 	raw3215_mk_write_req(raw);
 	raw3215_try_io(raw);
-	tty = raw->tty;
-	if (tty != NULL &&
-	    RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) {
-	    	tty_wakeup(tty);
-	}
+	if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
+		tasklet_schedule(&raw->tlet);
 }
 
 /*
@@ -682,6 +687,7 @@
 		return -ENOMEM;
 	}
 	init_waitqueue_head(&raw->empty_wait);
+	tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
 
 	dev_set_drvdata(&cdev->dev, raw);
 	cdev->handler = raw3215_irq;
@@ -901,6 +907,7 @@
 
 	raw->flags |= RAW3215_FIXED;
 	init_waitqueue_head(&raw->empty_wait);
+	tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
 
 	/* Request the console irq */
 	if (raw3215_startup(raw) != 0) {
@@ -966,6 +973,7 @@
 	tty->closing = 1;
 	/* Shutdown the terminal */
 	raw3215_shutdown(raw);
+	tasklet_kill(&raw->tlet);
 	tty->closing = 0;
 	raw->tty = NULL;
 }
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index e712981..9117045 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -11,6 +11,7 @@
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/compat.h>
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/slab.h>
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 75bde6a..89c03e6 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -13,6 +13,7 @@
 
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/compat.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 0c87b0f..8f9a1a3 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -8,6 +8,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/compat.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index 303dde0..fab2c25 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -11,6 +11,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/compat.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/miscdevice.h>
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 53a31c7..20c4557 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -364,10 +364,7 @@
 	struct rdac_controller *ctlr;
 	ctlr = container_of(kref, struct rdac_controller, kref);
 
-	flush_workqueue(kmpath_rdacd);
-	spin_lock(&list_lock);
 	list_del(&ctlr->node);
-	spin_unlock(&list_lock);
 	kfree(ctlr);
 }
 
@@ -376,20 +373,17 @@
 {
 	struct rdac_controller *ctlr, *tmp;
 
-	spin_lock(&list_lock);
-
 	list_for_each_entry(tmp, &ctlr_list, node) {
 		if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) &&
 			  (tmp->index == index) &&
 			  (tmp->host == sdev->host)) {
 			kref_get(&tmp->kref);
-			spin_unlock(&list_lock);
 			return tmp;
 		}
 	}
 	ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC);
 	if (!ctlr)
-		goto done;
+		return NULL;
 
 	/* initialize fields of controller */
 	memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN);
@@ -405,8 +399,7 @@
 	INIT_WORK(&ctlr->ms_work, send_mode_select);
 	INIT_LIST_HEAD(&ctlr->ms_head);
 	list_add(&ctlr->node, &ctlr_list);
-done:
-	spin_unlock(&list_lock);
+
 	return ctlr;
 }
 
@@ -517,9 +510,12 @@
 			index = 0;
 		else
 			index = 1;
+
+		spin_lock(&list_lock);
 		h->ctlr = get_controller(index, array_name, array_id, sdev);
 		if (!h->ctlr)
 			err = SCSI_DH_RES_TEMP_UNAVAIL;
+		spin_unlock(&list_lock);
 	}
 	return err;
 }
@@ -906,7 +902,9 @@
 	return 0;
 
 clean_ctlr:
+	spin_lock(&list_lock);
 	kref_put(&h->ctlr->kref, release_controller);
+	spin_unlock(&list_lock);
 
 failed:
 	kfree(scsi_dh_data);
@@ -921,14 +919,19 @@
 	struct rdac_dh_data *h;
 	unsigned long flags;
 
-	spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
 	scsi_dh_data = sdev->scsi_dh_data;
+	h = (struct rdac_dh_data *) scsi_dh_data->buf;
+	if (h->ctlr && h->ctlr->ms_queued)
+		flush_workqueue(kmpath_rdacd);
+
+	spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
 	sdev->scsi_dh_data = NULL;
 	spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
 
-	h = (struct rdac_dh_data *) scsi_dh_data->buf;
+	spin_lock(&list_lock);
 	if (h->ctlr)
 		kref_put(&h->ctlr->kref, release_controller);
+	spin_unlock(&list_lock);
 	kfree(scsi_dh_data);
 	module_put(THIS_MODULE);
 	sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", RDAC_NAME);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 67b169b..b538f08 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4613,11 +4613,13 @@
 	ENTER;
 	ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
 
-	dev_err(&ioa_cfg->pdev->dev,
-		"Adapter being reset as a result of error recovery.\n");
+	if (!ioa_cfg->in_reset_reload) {
+		dev_err(&ioa_cfg->pdev->dev,
+			"Adapter being reset as a result of error recovery.\n");
 
-	if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
-		ioa_cfg->sdt_state = GET_DUMP;
+		if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
+			ioa_cfg->sdt_state = GET_DUMP;
+	}
 
 	rc = ipr_reset_reload(ioa_cfg, IPR_SHUTDOWN_ABBREV);
 
@@ -4907,7 +4909,7 @@
 	struct ipr_ioa_cfg *ioa_cfg;
 	struct ipr_resource_entry *res;
 	struct ipr_cmd_pkt *cmd_pkt;
-	u32 ioasc;
+	u32 ioasc, int_reg;
 	int op_found = 0;
 
 	ENTER;
@@ -4920,7 +4922,17 @@
 	 */
 	if (ioa_cfg->in_reset_reload || ioa_cfg->ioa_is_dead)
 		return FAILED;
-	if (!res || !ipr_is_gscsi(res))
+	if (!res)
+		return FAILED;
+
+	/*
+	 * If we are aborting a timed out op, chances are that the timeout was caused
+	 * by a still not detected EEH error. In such cases, reading a register will
+	 * trigger the EEH recovery infrastructure.
+	 */
+	int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
+
+	if (!ipr_is_gscsi(res))
 		return FAILED;
 
 	list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 1a65d65..418391b 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1848,9 +1848,11 @@
 	if (state == SCIC_RESET ||
 	    state == SCIC_INITIALIZING ||
 	    state == SCIC_INITIALIZED) {
+		u8 oem_version = pci_info->orom ? pci_info->orom->hdr.version :
+			ISCI_ROM_VER_1_0;
 
 		if (sci_oem_parameters_validate(&ihost->oem_parameters,
-						pci_info->orom->hdr.version))
+						oem_version))
 			return SCI_FAILURE_INVALID_PARAMETER_VALUE;
 
 		return SCI_SUCCESS;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 0b2c955..a78036f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -4548,7 +4548,7 @@
 		printk(MPT2SAS_ERR_FMT "%s: pci error recovery reset\n",
 		    ioc->name, __func__);
 		r = 0;
-		goto out;
+		goto out_unlocked;
 	}
 
 	if (mpt2sas_fwfault_debug)
@@ -4604,6 +4604,7 @@
 	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 	mutex_unlock(&ioc->reset_in_progress_mutex);
 
+ out_unlocked:
 	dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
 	    __func__));
 	return r;
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index b31a8e3..d4ed9eb 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -69,10 +69,10 @@
 #ifndef SCSI_OSD_MAJOR
 #  define SCSI_OSD_MAJOR 260
 #endif
-#define SCSI_OSD_MAX_MINOR 64
+#define SCSI_OSD_MAX_MINOR MINORMASK
 
 static const char osd_name[] = "osd";
-static const char *osd_version_string = "open-osd 0.2.0";
+static const char *osd_version_string = "open-osd 0.2.1";
 
 MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
 MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko");
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index a2f1b30..9f41b3b 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1036,8 +1036,7 @@
 	    vha->device_flags & DFLG_NO_CABLE)
 		len = snprintf(buf, PAGE_SIZE, "Link Down\n");
 	else if (atomic_read(&vha->loop_state) != LOOP_READY ||
-	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+	    qla2x00_reset_active(vha))
 		len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
 	else {
 		len = snprintf(buf, PAGE_SIZE, "Link Up - ");
@@ -1359,8 +1358,7 @@
 		return snprintf(buf, PAGE_SIZE, "\n");
 
 	temp = frac = 0;
-	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+	if (qla2x00_reset_active(vha))
 		ql_log(ql_log_warn, vha, 0x707b,
 		    "ISP reset active.\n");
 	else if (!vha->hw->flags.eeh_busy)
@@ -1379,8 +1377,7 @@
 	int rval = QLA_FUNCTION_FAILED;
 	uint16_t state[5];
 
-	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+	if (qla2x00_reset_active(vha))
 		ql_log(ql_log_warn, vha, 0x707c,
 		    "ISP reset active.\n");
 	else if (!vha->hw->flags.eeh_busy)
@@ -1693,9 +1690,7 @@
 	if (IS_FWI2_CAPABLE(ha)) {
 		rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma);
 	} else if (atomic_read(&base_vha->loop_state) == LOOP_READY &&
-		    !test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) &&
-		    !test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
-		    !ha->dpc_active) {
+	    !qla2x00_reset_active(vha) && !ha->dpc_active) {
 		/* Must be in a 'READY' state for statistics retrieval. */
 		rval = qla2x00_get_link_status(base_vha, base_vha->loop_id,
 						stats, stats_dma);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index b1d0f93..1682e2e 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -108,13 +108,6 @@
 		goto exit_fcp_prio_cfg;
 	}
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ret = -EBUSY;
-		goto exit_fcp_prio_cfg;
-	}
-
 	/* Get the sub command */
 	oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
 
@@ -646,13 +639,6 @@
 	dma_addr_t rsp_data_dma;
 	uint32_t rsp_data_len;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ql_log(ql_log_warn, vha, 0x7018, "Abort active or needed.\n");
-		return -EBUSY;
-	}
-
 	if (!vha->flags.online) {
 		ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
 		return -EIO;
@@ -874,13 +860,6 @@
 	int rval = 0;
 	uint32_t flag;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-	    test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ql_log(ql_log_warn, vha, 0x702e, "Abort active or needed.\n");
-		return -EBUSY;
-	}
-
 	if (!IS_QLA84XX(ha)) {
 		ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
 		return -EINVAL;
@@ -922,11 +901,6 @@
 	uint32_t flag;
 	uint32_t fw_ver;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags))
-		return -EBUSY;
-
 	if (!IS_QLA84XX(ha)) {
 		ql_dbg(ql_dbg_user, vha, 0x7032,
 		    "Not 84xx, exiting.\n");
@@ -1036,14 +1010,6 @@
 	uint32_t data_len = 0;
 	uint32_t dma_direction = DMA_NONE;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ql_log(ql_log_warn, vha, 0x7039,
-		    "Abort active or needed.\n");
-		return -EBUSY;
-	}
-
 	if (!IS_QLA84XX(ha)) {
 		ql_log(ql_log_warn, vha, 0x703a,
 		    "Not 84xx, exiting.\n");
@@ -1246,13 +1212,6 @@
 
 	bsg_job->reply->reply_payload_rcv_len = 0;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ql_log(ql_log_warn, vha, 0x7045, "abort active or needed.\n");
-		return -EBUSY;
-	}
-
 	if (!IS_IIDMA_CAPABLE(vha->hw)) {
 		ql_log(ql_log_info, vha, 0x7046, "iiDMA not supported.\n");
 		return -EINVAL;
@@ -1668,6 +1627,15 @@
 		vha = shost_priv(host);
 	}
 
+	if (qla2x00_reset_active(vha)) {
+		ql_dbg(ql_dbg_user, vha, 0x709f,
+		    "BSG: ISP abort active/needed -- cmd=%d.\n",
+		    bsg_job->request->msgcode);
+		bsg_job->reply->result = (DID_ERROR << 16);
+		bsg_job->job_done(bsg_job);
+		return -EBUSY;
+	}
+
 	ql_dbg(ql_dbg_user, vha, 0x7000,
 	    "Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode);
 
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 7c54624..45cbf0b 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -19,7 +19,8 @@
  * | DPC Thread                   |       0x401c       |		|
  * | Async Events                 |       0x5057       | 0x5052		|
  * | Timer Routines               |       0x6011       | 0x600e,0x600f  |
- * | User Space Interactions      |       0x709e       |		|
+ * | User Space Interactions      |       0x709e       | 0x7018,0x702e  |
+ * |                              |                    | 0x7039,0x7045  |
  * | Task Management              |       0x803c       | 0x8025-0x8026  |
  * |                              |                    | 0x800b,0x8039  |
  * | AER/EEH                      |       0x900f       |		|
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index a6a4eeb..af1003f 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -44,6 +44,7 @@
  * ISP2100 HBAs.
  */
 #define MAILBOX_REGISTER_COUNT_2100	8
+#define MAILBOX_REGISTER_COUNT_2200	24
 #define MAILBOX_REGISTER_COUNT		32
 
 #define QLA2200A_RISC_ROM_VER	4
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 9902834..7cc4f36 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -131,3 +131,16 @@
 	}
 	return 0;
 }
+
+static inline int
+qla2x00_reset_active(scsi_qla_host_t *vha)
+{
+	scsi_qla_host_t *base_vha = pci_get_drvdata(vha->hw->pdev);
+
+	/* Test appropriate base-vha and vha flags. */
+	return test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) ||
+	    test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
+	    test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
+	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
+	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
+}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index e804585..349843e 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2090,7 +2090,6 @@
 			break;
                 case CT_IOCB_TYPE:
 			qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
-			clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags);
 			break;
                 case ELS_IOCB_TYPE:
 			qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 34344d3..08f1d01 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -342,6 +342,8 @@
 
 				set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
 				clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+				/* Allow next mbx cmd to come in. */
+				complete(&ha->mbx_cmd_comp);
 				if (ha->isp_ops->abort_isp(vha)) {
 					/* Failed. retry later. */
 					set_bit(ISP_ABORT_NEEDED,
@@ -350,6 +352,7 @@
 				clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
 				ql_dbg(ql_dbg_mbx, base_vha, 0x101f,
 				    "Finished abort_isp.\n");
+				goto mbx_done;
 			}
 		}
 	}
@@ -358,6 +361,7 @@
 	/* Allow next mbx cmd to come in. */
 	complete(&ha->mbx_cmd_comp);
 
+mbx_done:
 	if (rval) {
 		ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
 		    "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, cmd=%x ****.\n",
@@ -2581,7 +2585,8 @@
 	ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
 
 	mcp->mb[0] = MBC_STOP_FIRMWARE;
-	mcp->out_mb = MBX_0;
+	mcp->mb[1] = 0;
+	mcp->out_mb = MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->tov = 5;
 	mcp->flags = 0;
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 1cd46cd..270ba31 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1165,19 +1165,6 @@
 		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
 	else
 		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
-
-	/* reset ms */
-	val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
-	val |= (1 << 1);
-	qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
-	msleep(20);
-
-	/* unreset ms */
-	val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
-	val &= ~(1 << 1);
-	qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
-	msleep(20);
-
 	qla82xx_rom_unlock(ha);
 
 	/* Read the signature value from the flash.
@@ -3392,7 +3379,7 @@
 					    QLA82XX_CRB_PEG_NET_3 + 0x3c),
 				    qla82xx_rd_32(ha,
 					    QLA82XX_CRB_PEG_NET_4 + 0x3c));
-				if (LSW(MSB(halt_status)) == 0x67)
+				if (((halt_status & 0x1fffff00) >> 8) == 0x67)
 					ql_log(ql_log_warn, vha, 0xb052,
 					    "Firmware aborted with "
 					    "error code 0x00006700. Device is "
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4ed1e4a..036030c 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -625,6 +625,12 @@
 			cmd->result = DID_NO_CONNECT << 16;
 			goto qc24_fail_command;
 	}
+
+	if (!fcport) {
+		cmd->result = DID_NO_CONNECT << 16;
+		goto qc24_fail_command;
+	}
+
 	if (atomic_read(&fcport->state) != FCS_ONLINE) {
 		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
 			atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
@@ -877,6 +883,7 @@
 
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	if (ha->isp_ops->abort_command(sp)) {
+		ret = FAILED;
 		ql_dbg(ql_dbg_taskm, vha, 0x8003,
 		    "Abort command mbx failed cmd=%p.\n", cmd);
 	} else {
@@ -1124,7 +1131,6 @@
 qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
 {
 	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
-	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
 	struct qla_hw_data *ha = vha->hw;
 	int ret = FAILED;
 	unsigned int id, lun;
@@ -1133,15 +1139,6 @@
 	id = cmd->device->id;
 	lun = cmd->device->lun;
 
-	if (!fcport) {
-		return ret;
-	}
-
-	ret = fc_block_scsi_eh(cmd);
-	if (ret != 0)
-		return ret;
-	ret = FAILED;
-
 	ql_log(ql_log_info, vha, 0x8018,
 	    "ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
 
@@ -2047,7 +2044,7 @@
 		ha->nvram_data_off = ~0;
 		ha->isp_ops = &qla2100_isp_ops;
 	} else if (IS_QLA2200(ha)) {
-		ha->mbx_count = MAILBOX_REGISTER_COUNT;
+		ha->mbx_count = MAILBOX_REGISTER_COUNT_2200;
 		req_length = REQUEST_ENTRY_CNT_2200;
 		rsp_length = RESPONSE_ENTRY_CNT_2100;
 		ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 23f33a6..29d780c 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.07.12-k"
+#define QLA2XXX_VERSION      "8.03.07.13-k"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	3
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 78f1111..65253df 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -10,6 +10,8 @@
 #include "ql4_def.h"
 #include "ql4_glbl.h"
 
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
 #define MASK(n)		DMA_BIT_MASK(n)
 #define MN_WIN(addr)	(((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
 #define OCM_WIN(addr)	(((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
@@ -655,27 +657,6 @@
 	return 0;
 }
 
-#ifndef readq
-static inline __u64 readq(const volatile void __iomem *addr)
-{
-	const volatile u32 __iomem *p = addr;
-	u32 low, high;
-
-	low = readl(p);
-	high = readl(p + 1);
-
-	return low + ((u64)high << 32);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(__u64 val, volatile void __iomem *addr)
-{
-	writel(val, addr);
-	writel(val >> 32, addr+4);
-}
-#endif
-
 static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha,
 		u64 off, void *data, int size)
 {
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index bf8bf79..c467064 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -7,6 +7,7 @@
 
 #include <linux/pm_runtime.h>
 #include <linux/export.h>
+#include <linux/async.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -92,6 +93,19 @@
 	return err;
 }
 
+static int scsi_bus_prepare(struct device *dev)
+{
+	if (scsi_is_sdev_device(dev)) {
+		/* sd probing uses async_schedule.  Wait until it finishes. */
+		async_synchronize_full();
+
+	} else if (scsi_is_host_device(dev)) {
+		/* Wait until async scanning is finished */
+		scsi_complete_async_scans();
+	}
+	return 0;
+}
+
 static int scsi_bus_suspend(struct device *dev)
 {
 	return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
@@ -110,6 +124,7 @@
 #else /* CONFIG_PM_SLEEP */
 
 #define scsi_bus_resume_common		NULL
+#define scsi_bus_prepare		NULL
 #define scsi_bus_suspend		NULL
 #define scsi_bus_freeze			NULL
 #define scsi_bus_poweroff		NULL
@@ -218,6 +233,7 @@
 #endif /* CONFIG_PM_RUNTIME */
 
 const struct dev_pm_ops scsi_bus_pm_ops = {
+	.prepare =		scsi_bus_prepare,
 	.suspend =		scsi_bus_suspend,
 	.resume =		scsi_bus_resume_common,
 	.freeze =		scsi_bus_freeze,
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 68eadd1..be4fa6d 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -109,6 +109,7 @@
 #endif /* CONFIG_PROC_FS */
 
 /* scsi_scan.c */
+extern int scsi_complete_async_scans(void);
 extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
 				   unsigned int, unsigned int, int);
 extern void scsi_forget_host(struct Scsi_Host *);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 89da43f..29c4c04 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1815,6 +1815,7 @@
 	}
 	spin_unlock(&async_scan_lock);
 
+	scsi_autopm_put_host(shost);
 	scsi_host_put(shost);
 	kfree(data);
 }
@@ -1841,7 +1842,6 @@
 
 	do_scsi_scan_host(shost);
 	scsi_finish_async_scan(data);
-	scsi_autopm_put_host(shost);
 	return 0;
 }
 
@@ -1869,7 +1869,7 @@
 	p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
 	if (IS_ERR(p))
 		do_scan_async(data);
-	/* scsi_autopm_put_host(shost) is called in do_scan_async() */
+	/* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */
 }
 EXPORT_SYMBOL(scsi_scan_host);
 
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 45fee36..92d314a 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -190,7 +190,7 @@
 		return -EINVAL;
 	}
 
-	clk->parent = clk->parent_table[val];
+	clk_reparent(clk, clk->parent_table[val]);
 	if (!clk->parent) {
 		pr_err("sh_clk_init_parent: unable to set parent");
 		return -EINVAL;
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 520e828..49d2091 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -75,7 +75,7 @@
 	u32 tmp;
 
 	/* We do only have one cardbus device behind the bridge. */
-	if (pc->cardbusmode && (dev >= 1))
+	if (pc->cardbusmode && (dev > 1))
 		goto out;
 
 	if (bus == 0) {
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 21e2f4b..9e63472 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -60,8 +60,6 @@
 
 source "drivers/staging/frontier/Kconfig"
 
-source "drivers/staging/pohmelfs/Kconfig"
-
 source "drivers/staging/phison/Kconfig"
 
 source "drivers/staging/line6/Kconfig"
@@ -120,8 +118,6 @@
 
 source "drivers/staging/ste_rmi4/Kconfig"
 
-source "drivers/staging/gma500/Kconfig"
-
 source "drivers/staging/mei/Kconfig"
 
 source "drivers/staging/nvec/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 7c5808d..943e148 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -22,7 +22,6 @@
 obj-$(CONFIG_RTS_PSTOR)		+= rts_pstor/
 obj-$(CONFIG_RTS5139)		+= rts5139/
 obj-$(CONFIG_TRANZPORT)		+= frontier/
-obj-$(CONFIG_POHMELFS)		+= pohmelfs/
 obj-$(CONFIG_IDE_PHISON)	+= phison/
 obj-$(CONFIG_LINE6_USB)		+= line6/
 obj-$(CONFIG_USB_SERIAL_QUATECH2)	+= serqt_usb2/
@@ -52,7 +51,6 @@
 obj-$(CONFIG_SPEAKUP)		+= speakup/
 obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217)	+= cptm1217/
 obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)	+= ste_rmi4/
-obj-$(CONFIG_DRM_PSB)		+= gma500/
 obj-$(CONFIG_INTEL_MEI)		+= mei/
 obj-$(CONFIG_MFD_NVEC)		+= nvec/
 obj-$(CONFIG_DRM_OMAP)		+= omapdrm/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index becf711..fef3580 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -27,6 +27,7 @@
 
 config ANDROID_RAM_CONSOLE
 	bool "Android RAM buffer console"
+	depends on !S390 && !UML
 	default n
 
 config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
@@ -99,10 +100,6 @@
 	---help---
 	  Register processes to be killed when memory is low
 
-config ANDROID_PMEM
-	bool "Android pmem allocator"
-	depends on ARM
-
 source "drivers/staging/android/switch/Kconfig"
 
 endif # if ANDROID
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index eaed1ff..5fcc24f 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -5,5 +5,4 @@
 obj-$(CONFIG_ANDROID_TIMED_OUTPUT)	+= timed_output.o
 obj-$(CONFIG_ANDROID_TIMED_GPIO)	+= timed_gpio.o
 obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
-obj-$(CONFIG_ANDROID_PMEM)		+= pmem.o
 obj-$(CONFIG_ANDROID_SWITCH)		+= switch/
diff --git a/drivers/staging/android/android_pmem.h b/drivers/staging/android/android_pmem.h
deleted file mode 100644
index f633621..0000000
--- a/drivers/staging/android/android_pmem.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* include/linux/android_pmem.h
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _ANDROID_PMEM_H_
-#define _ANDROID_PMEM_H_
-
-#define PMEM_IOCTL_MAGIC 'p'
-#define PMEM_GET_PHYS		_IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
-#define PMEM_MAP		_IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
-#define PMEM_GET_SIZE		_IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
-#define PMEM_UNMAP		_IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
-/* This ioctl will allocate pmem space, backing the file, it will fail
- * if the file already has an allocation, pass it the len as the argument
- * to the ioctl */
-#define PMEM_ALLOCATE		_IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
-/* This will connect a one pmem file to another, pass the file that is already
- * backed in memory as the argument to the ioctl
- */
-#define PMEM_CONNECT		_IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
-/* Returns the total size of the pmem region it is sent to as a pmem_region
- * struct (with offset set to 0). 
- */
-#define PMEM_GET_TOTAL_SIZE	_IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
-#define PMEM_CACHE_FLUSH	_IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
-
-struct android_pmem_platform_data
-{
-	const char* name;
-	/* starting physical address of memory region */
-	unsigned long start;
-	/* size of memory region */
-	unsigned long size;
-	/* set to indicate the region should not be managed with an allocator */
-	unsigned no_allocator;
-	/* set to indicate maps of this region should be cached, if a mix of
-	 * cached and uncached is desired, set this and open the device with
-	 * O_SYNC to get an uncached region */
-	unsigned cached;
-	/* The MSM7k has bits to enable a write buffer in the bus controller*/
-	unsigned buffered;
-};
-
-struct pmem_region {
-	unsigned long offset;
-	unsigned long len;
-};
-
-#ifdef CONFIG_ANDROID_PMEM
-int is_pmem_file(struct file *file);
-int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
-		  unsigned long *end, struct file **filp);
-int get_pmem_user_addr(struct file *file, unsigned long *start,
-		       unsigned long *end);
-void put_pmem_file(struct file* file);
-void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
-int pmem_setup(struct android_pmem_platform_data *pdata,
-	       long (*ioctl)(struct file *, unsigned int, unsigned long),
-	       int (*release)(struct inode *, struct file *));
-int pmem_remap(struct pmem_region *region, struct file *file,
-	       unsigned operation);
-
-#else
-static inline int is_pmem_file(struct file *file) { return 0; }
-static inline int get_pmem_file(int fd, unsigned long *start,
-				unsigned long *vstart, unsigned long *end,
-				struct file **filp) { return -ENOSYS; }
-static inline int get_pmem_user_addr(struct file *file, unsigned long *start,
-				     unsigned long *end) { return -ENOSYS; }
-static inline void put_pmem_file(struct file* file) { return; }
-static inline void flush_pmem_file(struct file *file, unsigned long start,
-				   unsigned long len) { return; }
-static inline int pmem_setup(struct android_pmem_platform_data *pdata,
-	      long (*ioctl)(struct file *, unsigned int, unsigned long),
-	      int (*release)(struct inode *, struct file *)) { return -ENOSYS; }
-
-static inline int pmem_remap(struct pmem_region *region, struct file *file,
-			     unsigned operation) { return -ENOSYS; }
-#endif
-
-#endif //_ANDROID_PPP_H_
-
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 7491801..f0b7e66 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -38,6 +38,7 @@
 
 static DEFINE_MUTEX(binder_lock);
 static DEFINE_MUTEX(binder_deferred_lock);
+static DEFINE_MUTEX(binder_mmap_lock);
 
 static HLIST_HEAD(binder_procs);
 static HLIST_HEAD(binder_deferred_list);
@@ -632,6 +633,11 @@
 	if (mm) {
 		down_write(&mm->mmap_sem);
 		vma = proc->vma;
+		if (vma && mm != vma->vm_mm) {
+			pr_err("binder: %d: vma mm and task mm mismatch\n",
+				proc->pid);
+			vma = NULL;
+		}
 	}
 
 	if (allocate == 0)
@@ -2759,7 +2765,6 @@
 		     proc->pid, vma->vm_start, vma->vm_end,
 		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
 		     (unsigned long)pgprot_val(vma->vm_page_prot));
-	dump_stack();
 }
 
 static void binder_vma_close(struct vm_area_struct *vma)
@@ -2803,6 +2808,7 @@
 	}
 	vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
 
+	mutex_lock(&binder_mmap_lock);
 	if (proc->buffer) {
 		ret = -EBUSY;
 		failure_string = "already mapped";
@@ -2817,6 +2823,7 @@
 	}
 	proc->buffer = area->addr;
 	proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
+	mutex_unlock(&binder_mmap_lock);
 
 #ifdef CONFIG_CPU_CACHE_VIPT
 	if (cache_is_vipt_aliasing()) {
@@ -2849,7 +2856,7 @@
 	binder_insert_free_buffer(proc, buffer);
 	proc->free_async_space = proc->buffer_size / 2;
 	barrier();
-	proc->files = get_files_struct(current);
+	proc->files = get_files_struct(proc->tsk);
 	proc->vma = vma;
 
 	/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
@@ -2860,10 +2867,12 @@
 	kfree(proc->pages);
 	proc->pages = NULL;
 err_alloc_pages_failed:
+	mutex_lock(&binder_mmap_lock);
 	vfree(proc->buffer);
 	proc->buffer = NULL;
 err_get_vm_area_failed:
 err_already_mapped:
+	mutex_unlock(&binder_mmap_lock);
 err_bad_arg:
 	printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
 	       proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 2d8d2b7..efc7dc1 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -54,6 +54,7 @@
 static int lowmem_minfree_size = 4;
 
 static struct task_struct *lowmem_deathpending;
+static unsigned long lowmem_deathpending_timeout;
 
 #define lowmem_print(level, x...)			\
 	do {						\
@@ -103,7 +104,8 @@
 	 * Note: Currently you need CONFIG_PROFILING
 	 * for this to work correctly.
 	 */
-	if (lowmem_deathpending)
+	if (lowmem_deathpending &&
+	    time_before_eq(jiffies, lowmem_deathpending_timeout))
 		return 0;
 
 	if (lowmem_adj_size < array_size)
@@ -178,6 +180,7 @@
 		 */
 #ifdef CONFIG_PROFILING
 		lowmem_deathpending = selected;
+		lowmem_deathpending_timeout = jiffies + HZ;
 		task_handoff_register(&task_nb);
 #endif
 		force_sig(SIGKILL, selected);
diff --git a/drivers/staging/android/pmem.c b/drivers/staging/android/pmem.c
deleted file mode 100644
index 7d97032..0000000
--- a/drivers/staging/android/pmem.c
+++ /dev/null
@@ -1,1345 +0,0 @@
-/* pmem.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/miscdevice.h>
-#include <linux/platform_device.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/mm.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/debugfs.h>
-#include <linux/mempolicy.h>
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/cacheflush.h>
-#include "android_pmem.h"
-
-#define PMEM_MAX_DEVICES 10
-#define PMEM_MAX_ORDER 128
-#define PMEM_MIN_ALLOC PAGE_SIZE
-
-#define PMEM_DEBUG 1
-
-/* indicates that a refernce to this file has been taken via get_pmem_file,
- * the file should not be released until put_pmem_file is called */
-#define PMEM_FLAGS_BUSY 0x1
-/* indicates that this is a suballocation of a larger master range */
-#define PMEM_FLAGS_CONNECTED 0x1 << 1
-/* indicates this is a master and not a sub allocation and that it is mmaped */
-#define PMEM_FLAGS_MASTERMAP 0x1 << 2
-/* submap and unsubmap flags indicate:
- * 00: subregion has never been mmaped
- * 10: subregion has been mmaped, reference to the mm was taken
- * 11: subretion has ben released, refernece to the mm still held
- * 01: subretion has been released, reference to the mm has been released
- */
-#define PMEM_FLAGS_SUBMAP 0x1 << 3
-#define PMEM_FLAGS_UNSUBMAP 0x1 << 4
-
-
-struct pmem_data {
-	/* in alloc mode: an index into the bitmap
-	 * in no_alloc mode: the size of the allocation */
-	int index;
-	/* see flags above for descriptions */
-	unsigned int flags;
-	/* protects this data field, if the mm_mmap sem will be held at the
-	 * same time as this sem, the mm sem must be taken first (as this is
-	 * the order for vma_open and vma_close ops */
-	struct rw_semaphore sem;
-	/* info about the mmaping process */
-	struct vm_area_struct *vma;
-	/* task struct of the mapping process */
-	struct task_struct *task;
-	/* process id of teh mapping process */
-	pid_t pid;
-	/* file descriptor of the master */
-	int master_fd;
-	/* file struct of the master */
-	struct file *master_file;
-	/* a list of currently available regions if this is a suballocation */
-	struct list_head region_list;
-	/* a linked list of data so we can access them for debugging */
-	struct list_head list;
-#if PMEM_DEBUG
-	int ref;
-#endif
-};
-
-struct pmem_bits {
-	unsigned allocated:1;		/* 1 if allocated, 0 if free */
-	unsigned order:7;		/* size of the region in pmem space */
-};
-
-struct pmem_region_node {
-	struct pmem_region region;
-	struct list_head list;
-};
-
-#define PMEM_DEBUG_MSGS 0
-#if PMEM_DEBUG_MSGS
-#define DLOG(fmt,args...) \
-	do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
-		    ##args); } \
-	while (0)
-#else
-#define DLOG(x...) do {} while (0)
-#endif
-
-struct pmem_info {
-	struct miscdevice dev;
-	/* physical start address of the remaped pmem space */
-	unsigned long base;
-	/* vitual start address of the remaped pmem space */
-	unsigned char __iomem *vbase;
-	/* total size of the pmem space */
-	unsigned long size;
-	/* number of entries in the pmem space */
-	unsigned long num_entries;
-	/* pfn of the garbage page in memory */
-	unsigned long garbage_pfn;
-	/* index of the garbage page in the pmem space */
-	int garbage_index;
-	/* the bitmap for the region indicating which entries are allocated
-	 * and which are free */
-	struct pmem_bits *bitmap;
-	/* indicates the region should not be managed with an allocator */
-	unsigned no_allocator;
-	/* indicates maps of this region should be cached, if a mix of
-	 * cached and uncached is desired, set this and open the device with
-	 * O_SYNC to get an uncached region */
-	unsigned cached;
-	unsigned buffered;
-	/* in no_allocator mode the first mapper gets the whole space and sets
-	 * this flag */
-	unsigned allocated;
-	/* for debugging, creates a list of pmem file structs, the
-	 * data_list_lock should be taken before pmem_data->sem if both are
-	 * needed */
-	struct mutex data_list_lock;
-	struct list_head data_list;
-	/* pmem_sem protects the bitmap array
-	 * a write lock should be held when modifying entries in bitmap
-	 * a read lock should be held when reading data from bits or
-	 * dereferencing a pointer into bitmap
-	 *
-	 * pmem_data->sem protects the pmem data of a particular file
-	 * Many of the function that require the pmem_data->sem have a non-
-	 * locking version for when the caller is already holding that sem.
-	 *
-	 * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER:
-	 * down(pmem_data->sem) => down(bitmap_sem)
-	 */
-	struct rw_semaphore bitmap_sem;
-
-	long (*ioctl)(struct file *, unsigned int, unsigned long);
-	int (*release)(struct inode *, struct file *);
-};
-
-static struct pmem_info pmem[PMEM_MAX_DEVICES];
-static int id_count;
-
-#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated)
-#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
-#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
-#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
-#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC)
-#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base)
-#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC)
-#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \
-	PMEM_LEN(id, index))
-#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase)
-#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \
-	PMEM_LEN(id, index))
-#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED)
-#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
-#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \
-	(!(data->flags & PMEM_FLAGS_UNSUBMAP)))
-
-static int pmem_release(struct inode *, struct file *);
-static int pmem_mmap(struct file *, struct vm_area_struct *);
-static int pmem_open(struct inode *, struct file *);
-static long pmem_ioctl(struct file *, unsigned int, unsigned long);
-
-struct file_operations pmem_fops = {
-	.release = pmem_release,
-	.mmap = pmem_mmap,
-	.open = pmem_open,
-	.unlocked_ioctl = pmem_ioctl,
-};
-
-static int get_id(struct file *file)
-{
-	return MINOR(file->f_dentry->d_inode->i_rdev);
-}
-
-int is_pmem_file(struct file *file)
-{
-	int id;
-
-	if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))
-		return 0;
-	id = get_id(file);
-	if (unlikely(id >= PMEM_MAX_DEVICES))
-		return 0;
-	if (unlikely(file->f_dentry->d_inode->i_rdev !=
-	     MKDEV(MISC_MAJOR, pmem[id].dev.minor)))
-		return 0;
-	return 1;
-}
-
-static int has_allocation(struct file *file)
-{
-	struct pmem_data *data;
-	/* check is_pmem_file first if not accessed via pmem_file_ops */
-
-	if (unlikely(!file->private_data))
-		return 0;
-	data = (struct pmem_data *)file->private_data;
-	if (unlikely(data->index < 0))
-		return 0;
-	return 1;
-}
-
-static int is_master_owner(struct file *file)
-{
-	struct file *master_file;
-	struct pmem_data *data;
-	int put_needed, ret = 0;
-
-	if (!is_pmem_file(file) || !has_allocation(file))
-		return 0;
-	data = (struct pmem_data *)file->private_data;
-	if (PMEM_FLAGS_MASTERMAP & data->flags)
-		return 1;
-	master_file = fget_light(data->master_fd, &put_needed);
-	if (master_file && data->master_file == master_file)
-		ret = 1;
-	fput_light(master_file, put_needed);
-	return ret;
-}
-
-static int pmem_free(int id, int index)
-{
-	/* caller should hold the write lock on pmem_sem! */
-	int buddy, curr = index;
-	DLOG("index %d\n", index);
-
-	if (pmem[id].no_allocator) {
-		pmem[id].allocated = 0;
-		return 0;
-	}
-	/* clean up the bitmap, merging any buddies */
-	pmem[id].bitmap[curr].allocated = 0;
-	/* find a slots buddy Buddy# = Slot# ^ (1 << order)
-	 * if the buddy is also free merge them
-	 * repeat until the buddy is not free or end of the bitmap is reached
-	 */
-	do {
-		buddy = PMEM_BUDDY_INDEX(id, curr);
-		if (PMEM_IS_FREE(id, buddy) &&
-				PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
-			PMEM_ORDER(id, buddy)++;
-			PMEM_ORDER(id, curr)++;
-			curr = min(buddy, curr);
-		} else {
-			break;
-		}
-	} while (curr < pmem[id].num_entries);
-
-	return 0;
-}
-
-static void pmem_revoke(struct file *file, struct pmem_data *data);
-
-static int pmem_release(struct inode *inode, struct file *file)
-{
-	struct pmem_data *data = (struct pmem_data *)file->private_data;
-	struct pmem_region_node *region_node;
-	struct list_head *elt, *elt2;
-	int id = get_id(file), ret = 0;
-
-
-	mutex_lock(&pmem[id].data_list_lock);
-	/* if this file is a master, revoke all the memory in the connected
-	 *  files */
-	if (PMEM_FLAGS_MASTERMAP & data->flags) {
-		struct pmem_data *sub_data;
-		list_for_each(elt, &pmem[id].data_list) {
-			sub_data = list_entry(elt, struct pmem_data, list);
-			down_read(&sub_data->sem);
-			if (PMEM_IS_SUBMAP(sub_data) &&
-			    file == sub_data->master_file) {
-				up_read(&sub_data->sem);
-				pmem_revoke(file, sub_data);
-			}  else
-				up_read(&sub_data->sem);
-		}
-	}
-	list_del(&data->list);
-	mutex_unlock(&pmem[id].data_list_lock);
-
-
-	down_write(&data->sem);
-
-	/* if its not a conencted file and it has an allocation, free it */
-	if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) {
-		down_write(&pmem[id].bitmap_sem);
-		ret = pmem_free(id, data->index);
-		up_write(&pmem[id].bitmap_sem);
-	}
-
-	/* if this file is a submap (mapped, connected file), downref the
-	 * task struct */
-	if (PMEM_FLAGS_SUBMAP & data->flags)
-		if (data->task) {
-			put_task_struct(data->task);
-			data->task = NULL;
-		}
-
-	file->private_data = NULL;
-
-	list_for_each_safe(elt, elt2, &data->region_list) {
-		region_node = list_entry(elt, struct pmem_region_node, list);
-		list_del(elt);
-		kfree(region_node);
-	}
-	BUG_ON(!list_empty(&data->region_list));
-
-	up_write(&data->sem);
-	kfree(data);
-	if (pmem[id].release)
-		ret = pmem[id].release(inode, file);
-
-	return ret;
-}
-
-static int pmem_open(struct inode *inode, struct file *file)
-{
-	struct pmem_data *data;
-	int id = get_id(file);
-	int ret = 0;
-
-	DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file));
-	/* setup file->private_data to indicate its unmapped */
-	/*  you can only open a pmem device one time */
-	if (file->private_data != NULL)
-		return -1;
-	data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL);
-	if (!data) {
-		printk("pmem: unable to allocate memory for pmem metadata.");
-		return -1;
-	}
-	data->flags = 0;
-	data->index = -1;
-	data->task = NULL;
-	data->vma = NULL;
-	data->pid = 0;
-	data->master_file = NULL;
-#if PMEM_DEBUG
-	data->ref = 0;
-#endif
-	INIT_LIST_HEAD(&data->region_list);
-	init_rwsem(&data->sem);
-
-	file->private_data = data;
-	INIT_LIST_HEAD(&data->list);
-
-	mutex_lock(&pmem[id].data_list_lock);
-	list_add(&data->list, &pmem[id].data_list);
-	mutex_unlock(&pmem[id].data_list_lock);
-	return ret;
-}
-
-static unsigned long pmem_order(unsigned long len)
-{
-	int i;
-
-	len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC;
-	len--;
-	for (i = 0; i < sizeof(len)*8; i++)
-		if (len >> i == 0)
-			break;
-	return i;
-}
-
-static int pmem_allocate(int id, unsigned long len)
-{
-	/* caller should hold the write lock on pmem_sem! */
-	/* return the corresponding pdata[] entry */
-	int curr = 0;
-	int end = pmem[id].num_entries;
-	int best_fit = -1;
-	unsigned long order = pmem_order(len);
-
-	if (pmem[id].no_allocator) {
-		DLOG("no allocator");
-		if ((len > pmem[id].size) || pmem[id].allocated)
-			return -1;
-		pmem[id].allocated = 1;
-		return len;
-	}
-
-	if (order > PMEM_MAX_ORDER)
-		return -1;
-	DLOG("order %lx\n", order);
-
-	/* look through the bitmap:
-	 * 	if you find a free slot of the correct order use it
-	 * 	otherwise, use the best fit (smallest with size > order) slot
-	 */
-	while (curr < end) {
-		if (PMEM_IS_FREE(id, curr)) {
-			if (PMEM_ORDER(id, curr) == (unsigned char)order) {
-				/* set the not free bit and clear others */
-				best_fit = curr;
-				break;
-			}
-			if (PMEM_ORDER(id, curr) > (unsigned char)order &&
-			    (best_fit < 0 ||
-			     PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit)))
-				best_fit = curr;
-		}
-		curr = PMEM_NEXT_INDEX(id, curr);
-	}
-
-	/* if best_fit < 0, there are no suitable slots,
-	 * return an error
-	 */
-	if (best_fit < 0) {
-		printk("pmem: no space left to allocate!\n");
-		return -1;
-	}
-
-	/* now partition the best fit:
-	 * 	split the slot into 2 buddies of order - 1
-	 * 	repeat until the slot is of the correct order
-	 */
-	while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
-		int buddy;
-		PMEM_ORDER(id, best_fit) -= 1;
-		buddy = PMEM_BUDDY_INDEX(id, best_fit);
-		PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit);
-	}
-	pmem[id].bitmap[best_fit].allocated = 1;
-	return best_fit;
-}
-
-static pgprot_t pmem_access_prot(struct file *file, pgprot_t vma_prot)
-{
-	int id = get_id(file);
-#ifdef pgprot_noncached
-	if (pmem[id].cached == 0 || file->f_flags & O_SYNC)
-		return pgprot_noncached(vma_prot);
-#endif
-#ifdef pgprot_ext_buffered
-	else if (pmem[id].buffered)
-		return pgprot_ext_buffered(vma_prot);
-#endif
-	return vma_prot;
-}
-
-static unsigned long pmem_start_addr(int id, struct pmem_data *data)
-{
-	if (pmem[id].no_allocator)
-		return PMEM_START_ADDR(id, 0);
-	else
-		return PMEM_START_ADDR(id, data->index);
-
-}
-
-static void *pmem_start_vaddr(int id, struct pmem_data *data)
-{
-	return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase;
-}
-
-static unsigned long pmem_len(int id, struct pmem_data *data)
-{
-	if (pmem[id].no_allocator)
-		return data->index;
-	else
-		return PMEM_LEN(id, data->index);
-}
-
-static int pmem_map_garbage(int id, struct vm_area_struct *vma,
-			    struct pmem_data *data, unsigned long offset,
-			    unsigned long len)
-{
-	int i, garbage_pages = len >> PAGE_SHIFT;
-
-	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE;
-	for (i = 0; i < garbage_pages; i++) {
-		if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE),
-		    pmem[id].garbage_pfn))
-			return -EAGAIN;
-	}
-	return 0;
-}
-
-static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma,
-				struct pmem_data *data, unsigned long offset,
-				unsigned long len)
-{
-	int garbage_pages;
-	DLOG("unmap offset %lx len %lx\n", offset, len);
-
-	BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
-
-	garbage_pages = len >> PAGE_SHIFT;
-	zap_page_range(vma, vma->vm_start + offset, len, NULL);
-	pmem_map_garbage(id, vma, data, offset, len);
-	return 0;
-}
-
-static int pmem_map_pfn_range(int id, struct vm_area_struct *vma,
-			      struct pmem_data *data, unsigned long offset,
-			      unsigned long len)
-{
-	DLOG("map offset %lx len %lx\n", offset, len);
-	BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start));
-	BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end));
-	BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
-	BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset));
-
-	if (io_remap_pfn_range(vma, vma->vm_start + offset,
-		(pmem_start_addr(id, data) + offset) >> PAGE_SHIFT,
-		len, vma->vm_page_prot)) {
-		return -EAGAIN;
-	}
-	return 0;
-}
-
-static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma,
-			      struct pmem_data *data, unsigned long offset,
-			      unsigned long len)
-{
-	/* hold the mm semp for the vma you are modifying when you call this */
-	BUG_ON(!vma);
-	zap_page_range(vma, vma->vm_start + offset, len, NULL);
-	return pmem_map_pfn_range(id, vma, data, offset, len);
-}
-
-static void pmem_vma_open(struct vm_area_struct *vma)
-{
-	struct file *file = vma->vm_file;
-	struct pmem_data *data = file->private_data;
-	int id = get_id(file);
-	/* this should never be called as we don't support copying pmem
-	 * ranges via fork */
-	BUG_ON(!has_allocation(file));
-	down_write(&data->sem);
-	/* remap the garbage pages, forkers don't get access to the data */
-	pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end);
-	up_write(&data->sem);
-}
-
-static void pmem_vma_close(struct vm_area_struct *vma)
-{
-	struct file *file = vma->vm_file;
-	struct pmem_data *data = file->private_data;
-
-	DLOG("current %u ppid %u file %p count %d\n", current->pid,
-	     current->parent->pid, file, file_count(file));
-	if (unlikely(!is_pmem_file(file) || !has_allocation(file))) {
-		printk(KERN_WARNING "pmem: something is very wrong, you are "
-		       "closing a vm backing an allocation that doesn't "
-		       "exist!\n");
-		return;
-	}
-	down_write(&data->sem);
-	if (data->vma == vma) {
-		data->vma = NULL;
-		if ((data->flags & PMEM_FLAGS_CONNECTED) &&
-		    (data->flags & PMEM_FLAGS_SUBMAP))
-			data->flags |= PMEM_FLAGS_UNSUBMAP;
-	}
-	/* the kernel is going to free this vma now anyway */
-	up_write(&data->sem);
-}
-
-static struct vm_operations_struct vm_ops = {
-	.open = pmem_vma_open,
-	.close = pmem_vma_close,
-};
-
-static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct pmem_data *data;
-	int index;
-	unsigned long vma_size =  vma->vm_end - vma->vm_start;
-	int ret = 0, id = get_id(file);
-
-	if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) {
-#if PMEM_DEBUG
-		printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned"
-				" and a multiple of pages_size.\n");
-#endif
-		return -EINVAL;
-	}
-
-	data = (struct pmem_data *)file->private_data;
-	down_write(&data->sem);
-	/* check this file isn't already mmaped, for submaps check this file
-	 * has never been mmaped */
-	if ((data->flags & PMEM_FLAGS_SUBMAP) ||
-	    (data->flags & PMEM_FLAGS_UNSUBMAP)) {
-#if PMEM_DEBUG
-		printk(KERN_ERR "pmem: you can only mmap a pmem file once, "
-		       "this file is already mmaped. %x\n", data->flags);
-#endif
-		ret = -EINVAL;
-		goto error;
-	}
-	/* if file->private_data == unalloced, alloc*/
-	if (data && data->index == -1) {
-		down_write(&pmem[id].bitmap_sem);
-		index = pmem_allocate(id, vma->vm_end - vma->vm_start);
-		up_write(&pmem[id].bitmap_sem);
-		data->index = index;
-	}
-	/* either no space was available or an error occured */
-	if (!has_allocation(file)) {
-		ret = -EINVAL;
-		printk("pmem: could not find allocation for map.\n");
-		goto error;
-	}
-
-	if (pmem_len(id, data) < vma_size) {
-#if PMEM_DEBUG
-		printk(KERN_WARNING "pmem: mmap size [%lu] does not match"
-		       "size of backing region [%lu].\n", vma_size,
-		       pmem_len(id, data));
-#endif
-		ret = -EINVAL;
-		goto error;
-	}
-
-	vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT;
-	vma->vm_page_prot = pmem_access_prot(file, vma->vm_page_prot);
-
-	if (data->flags & PMEM_FLAGS_CONNECTED) {
-		struct pmem_region_node *region_node;
-		struct list_head *elt;
-		if (pmem_map_garbage(id, vma, data, 0, vma_size)) {
-			printk("pmem: mmap failed in kernel!\n");
-			ret = -EAGAIN;
-			goto error;
-		}
-		list_for_each(elt, &data->region_list) {
-			region_node = list_entry(elt, struct pmem_region_node,
-						 list);
-			DLOG("remapping file: %p %lx %lx\n", file,
-				region_node->region.offset,
-				region_node->region.len);
-			if (pmem_remap_pfn_range(id, vma, data,
-						 region_node->region.offset,
-						 region_node->region.len)) {
-				ret = -EAGAIN;
-				goto error;
-			}
-		}
-		data->flags |= PMEM_FLAGS_SUBMAP;
-		get_task_struct(current->group_leader);
-		data->task = current->group_leader;
-		data->vma = vma;
-#if PMEM_DEBUG
-		data->pid = current->pid;
-#endif
-		DLOG("submmapped file %p vma %p pid %u\n", file, vma,
-		     current->pid);
-	} else {
-		if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) {
-			printk(KERN_INFO "pmem: mmap failed in kernel!\n");
-			ret = -EAGAIN;
-			goto error;
-		}
-		data->flags |= PMEM_FLAGS_MASTERMAP;
-		data->pid = current->pid;
-	}
-	vma->vm_ops = &vm_ops;
-error:
-	up_write(&data->sem);
-	return ret;
-}
-
-/* the following are the api for accessing pmem regions by other drivers
- * from inside the kernel */
-int get_pmem_user_addr(struct file *file, unsigned long *start,
-		   unsigned long *len)
-{
-	struct pmem_data *data;
-	if (!is_pmem_file(file) || !has_allocation(file)) {
-#if PMEM_DEBUG
-		printk(KERN_INFO "pmem: requested pmem data from invalid"
-				  "file.\n");
-#endif
-		return -1;
-	}
-	data = (struct pmem_data *)file->private_data;
-	down_read(&data->sem);
-	if (data->vma) {
-		*start = data->vma->vm_start;
-		*len = data->vma->vm_end - data->vma->vm_start;
-	} else {
-		*start = 0;
-		*len = 0;
-	}
-	up_read(&data->sem);
-	return 0;
-}
-
-int get_pmem_addr(struct file *file, unsigned long *start,
-		  unsigned long *vstart, unsigned long *len)
-{
-	struct pmem_data *data;
-	int id;
-
-	if (!is_pmem_file(file) || !has_allocation(file)) {
-		return -1;
-	}
-
-	data = (struct pmem_data *)file->private_data;
-	if (data->index == -1) {
-#if PMEM_DEBUG
-		printk(KERN_INFO "pmem: requested pmem data from file with no "
-		       "allocation.\n");
-		return -1;
-#endif
-	}
-	id = get_id(file);
-
-	down_read(&data->sem);
-	*start = pmem_start_addr(id, data);
-	*len = pmem_len(id, data);
-	*vstart = (unsigned long)pmem_start_vaddr(id, data);
-	up_read(&data->sem);
-#if PMEM_DEBUG
-	down_write(&data->sem);
-	data->ref++;
-	up_write(&data->sem);
-#endif
-	return 0;
-}
-
-int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
-		  unsigned long *len, struct file **filp)
-{
-	struct file *file;
-
-	file = fget(fd);
-	if (unlikely(file == NULL)) {
-		printk(KERN_INFO "pmem: requested data from file descriptor "
-		       "that doesn't exist.");
-		return -1;
-	}
-
-	if (get_pmem_addr(file, start, vstart, len))
-		goto end;
-
-	if (filp)
-		*filp = file;
-	return 0;
-end:
-	fput(file);
-	return -1;
-}
-
-void put_pmem_file(struct file *file)
-{
-	struct pmem_data *data;
-	int id;
-
-	if (!is_pmem_file(file))
-		return;
-	id = get_id(file);
-	data = (struct pmem_data *)file->private_data;
-#if PMEM_DEBUG
-	down_write(&data->sem);
-	if (data->ref == 0) {
-		printk("pmem: pmem_put > pmem_get %s (pid %d)\n",
-		       pmem[id].dev.name, data->pid);
-		BUG();
-	}
-	data->ref--;
-	up_write(&data->sem);
-#endif
-	fput(file);
-}
-
-void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
-{
-	struct pmem_data *data;
-	int id;
-	void *vaddr;
-	struct pmem_region_node *region_node;
-	struct list_head *elt;
-	void *flush_start, *flush_end;
-
-	if (!is_pmem_file(file) || !has_allocation(file)) {
-		return;
-	}
-
-	id = get_id(file);
-	data = (struct pmem_data *)file->private_data;
-	if (!pmem[id].cached || file->f_flags & O_SYNC)
-		return;
-
-	down_read(&data->sem);
-	vaddr = pmem_start_vaddr(id, data);
-	/* if this isn't a submmapped file, flush the whole thing */
-	if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) {
-		dmac_flush_range(vaddr, vaddr + pmem_len(id, data));
-		goto end;
-	}
-	/* otherwise, flush the region of the file we are drawing */
-	list_for_each(elt, &data->region_list) {
-		region_node = list_entry(elt, struct pmem_region_node, list);
-		if ((offset >= region_node->region.offset) &&
-		    ((offset + len) <= (region_node->region.offset +
-			region_node->region.len))) {
-			flush_start = vaddr + region_node->region.offset;
-			flush_end = flush_start + region_node->region.len;
-			dmac_flush_range(flush_start, flush_end);
-			break;
-		}
-	}
-end:
-	up_read(&data->sem);
-}
-
-static int pmem_connect(unsigned long connect, struct file *file)
-{
-	struct pmem_data *data = (struct pmem_data *)file->private_data;
-	struct pmem_data *src_data;
-	struct file *src_file;
-	int ret = 0, put_needed;
-
-	down_write(&data->sem);
-	/* retrieve the src file and check it is a pmem file with an alloc */
-	src_file = fget_light(connect, &put_needed);
-	DLOG("connect %p to %p\n", file, src_file);
-	if (!src_file) {
-		printk("pmem: src file not found!\n");
-		ret = -EINVAL;
-		goto err_no_file;
-	}
-	if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) {
-		printk(KERN_INFO "pmem: src file is not a pmem file or has no "
-		       "alloc!\n");
-		ret = -EINVAL;
-		goto err_bad_file;
-	}
-	src_data = (struct pmem_data *)src_file->private_data;
-
-	if (has_allocation(file) && (data->index != src_data->index)) {
-		printk("pmem: file is already mapped but doesn't match this"
-		       " src_file!\n");
-		ret = -EINVAL;
-		goto err_bad_file;
-	}
-	data->index = src_data->index;
-	data->flags |= PMEM_FLAGS_CONNECTED;
-	data->master_fd = connect;
-	data->master_file = src_file;
-
-err_bad_file:
-	fput_light(src_file, put_needed);
-err_no_file:
-	up_write(&data->sem);
-	return ret;
-}
-
-static void pmem_unlock_data_and_mm(struct pmem_data *data,
-				    struct mm_struct *mm)
-{
-	up_write(&data->sem);
-	if (mm != NULL) {
-		up_write(&mm->mmap_sem);
-		mmput(mm);
-	}
-}
-
-static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data,
-				 struct mm_struct **locked_mm)
-{
-	int ret = 0;
-	struct mm_struct *mm = NULL;
-	*locked_mm = NULL;
-lock_mm:
-	down_read(&data->sem);
-	if (PMEM_IS_SUBMAP(data)) {
-		mm = get_task_mm(data->task);
-		if (!mm) {
-#if PMEM_DEBUG
-			printk("pmem: can't remap task is gone!\n");
-#endif
-			up_read(&data->sem);
-			return -1;
-		}
-	}
-	up_read(&data->sem);
-
-	if (mm)
-		down_write(&mm->mmap_sem);
-
-	down_write(&data->sem);
-	/* check that the file didn't get mmaped before we could take the
-	 * data sem, this should be safe b/c you can only submap each file
-	 * once */
-	if (PMEM_IS_SUBMAP(data) && !mm) {
-		pmem_unlock_data_and_mm(data, mm);
-		up_write(&data->sem);
-		goto lock_mm;
-	}
-	/* now check that vma.mm is still there, it could have been
-	 * deleted by vma_close before we could get the data->sem */
-	if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) {
-		/* might as well release this */
-		if (data->flags & PMEM_FLAGS_SUBMAP) {
-			put_task_struct(data->task);
-			data->task = NULL;
-			/* lower the submap flag to show the mm is gone */
-			data->flags &= ~(PMEM_FLAGS_SUBMAP);
-		}
-		pmem_unlock_data_and_mm(data, mm);
-		return -1;
-	}
-	*locked_mm = mm;
-	return ret;
-}
-
-int pmem_remap(struct pmem_region *region, struct file *file,
-		      unsigned operation)
-{
-	int ret;
-	struct pmem_region_node *region_node;
-	struct mm_struct *mm = NULL;
-	struct list_head *elt, *elt2;
-	int id = get_id(file);
-	struct pmem_data *data = (struct pmem_data *)file->private_data;
-
-	/* pmem region must be aligned on a page boundry */
-	if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
-		 !PMEM_IS_PAGE_ALIGNED(region->len))) {
-#if PMEM_DEBUG
-		printk("pmem: request for unaligned pmem suballocation "
-		       "%lx %lx\n", region->offset, region->len);
-#endif
-		return -EINVAL;
-	}
-
-	/* if userspace requests a region of len 0, there's nothing to do */
-	if (region->len == 0)
-		return 0;
-
-	/* lock the mm and data */
-	ret = pmem_lock_data_and_mm(file, data, &mm);
-	if (ret)
-		return 0;
-
-	/* only the owner of the master file can remap the client fds
-	 * that back in it */
-	if (!is_master_owner(file)) {
-#if PMEM_DEBUG
-		printk("pmem: remap requested from non-master process\n");
-#endif
-		ret = -EINVAL;
-		goto err;
-	}
-
-	/* check that the requested range is within the src allocation */
-	if (unlikely((region->offset > pmem_len(id, data)) ||
-		     (region->len > pmem_len(id, data)) ||
-		     (region->offset + region->len > pmem_len(id, data)))) {
-#if PMEM_DEBUG
-		printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n");
-#endif
-		ret = -EINVAL;
-		goto err;
-	}
-
-	if (operation == PMEM_MAP) {
-		region_node = kmalloc(sizeof(struct pmem_region_node),
-			      GFP_KERNEL);
-		if (!region_node) {
-			ret = -ENOMEM;
-#if PMEM_DEBUG
-			printk(KERN_INFO "No space to allocate metadata!");
-#endif
-			goto err;
-		}
-		region_node->region = *region;
-		list_add(&region_node->list, &data->region_list);
-	} else if (operation == PMEM_UNMAP) {
-		int found = 0;
-		list_for_each_safe(elt, elt2, &data->region_list) {
-			region_node = list_entry(elt, struct pmem_region_node,
-				      list);
-			if (region->len == 0 ||
-			    (region_node->region.offset == region->offset &&
-			    region_node->region.len == region->len)) {
-				list_del(elt);
-				kfree(region_node);
-				found = 1;
-			}
-		}
-		if (!found) {
-#if PMEM_DEBUG
-			printk("pmem: Unmap region does not map any mapped "
-				"region!");
-#endif
-			ret = -EINVAL;
-			goto err;
-		}
-	}
-
-	if (data->vma && PMEM_IS_SUBMAP(data)) {
-		if (operation == PMEM_MAP)
-			ret = pmem_remap_pfn_range(id, data->vma, data,
-						   region->offset, region->len);
-		else if (operation == PMEM_UNMAP)
-			ret = pmem_unmap_pfn_range(id, data->vma, data,
-						   region->offset, region->len);
-	}
-
-err:
-	pmem_unlock_data_and_mm(data, mm);
-	return ret;
-}
-
-static void pmem_revoke(struct file *file, struct pmem_data *data)
-{
-	struct pmem_region_node *region_node;
-	struct list_head *elt, *elt2;
-	struct mm_struct *mm = NULL;
-	int id = get_id(file);
-	int ret = 0;
-
-	data->master_file = NULL;
-	ret = pmem_lock_data_and_mm(file, data, &mm);
-	/* if lock_data_and_mm fails either the task that mapped the fd, or
-	 * the vma that mapped it have already gone away, nothing more
-	 * needs to be done */
-	if (ret)
-		return;
-	/* unmap everything */
-	/* delete the regions and region list nothing is mapped any more */
-	if (data->vma)
-		list_for_each_safe(elt, elt2, &data->region_list) {
-			region_node = list_entry(elt, struct pmem_region_node,
-						 list);
-			pmem_unmap_pfn_range(id, data->vma, data,
-					     region_node->region.offset,
-					     region_node->region.len);
-			list_del(elt);
-			kfree(region_node);
-	}
-	/* delete the master file */
-	pmem_unlock_data_and_mm(data, mm);
-}
-
-static void pmem_get_size(struct pmem_region *region, struct file *file)
-{
-	struct pmem_data *data = (struct pmem_data *)file->private_data;
-	int id = get_id(file);
-
-	if (!has_allocation(file)) {
-		region->offset = 0;
-		region->len = 0;
-		return;
-	} else {
-		region->offset = pmem_start_addr(id, data);
-		region->len = pmem_len(id, data);
-	}
-	DLOG("offset %lx len %lx\n", region->offset, region->len);
-}
-
-
-static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct pmem_data *data;
-	int id = get_id(file);
-
-	switch (cmd) {
-	case PMEM_GET_PHYS:
-		{
-			struct pmem_region region;
-			DLOG("get_phys\n");
-			if (!has_allocation(file)) {
-				region.offset = 0;
-				region.len = 0;
-			} else {
-				data = (struct pmem_data *)file->private_data;
-				region.offset = pmem_start_addr(id, data);
-				region.len = pmem_len(id, data);
-			}
-			printk(KERN_INFO "pmem: request for physical address of pmem region "
-					"from process %d.\n", current->pid);
-			if (copy_to_user((void __user *)arg, &region,
-						sizeof(struct pmem_region)))
-				return -EFAULT;
-			break;
-		}
-	case PMEM_MAP:
-		{
-			struct pmem_region region;
-			if (copy_from_user(&region, (void __user *)arg,
-						sizeof(struct pmem_region)))
-				return -EFAULT;
-			data = (struct pmem_data *)file->private_data;
-			return pmem_remap(&region, file, PMEM_MAP);
-		}
-		break;
-	case PMEM_UNMAP:
-		{
-			struct pmem_region region;
-			if (copy_from_user(&region, (void __user *)arg,
-						sizeof(struct pmem_region)))
-				return -EFAULT;
-			data = (struct pmem_data *)file->private_data;
-			return pmem_remap(&region, file, PMEM_UNMAP);
-			break;
-		}
-	case PMEM_GET_SIZE:
-		{
-			struct pmem_region region;
-			DLOG("get_size\n");
-			pmem_get_size(&region, file);
-			if (copy_to_user((void __user *)arg, &region,
-						sizeof(struct pmem_region)))
-				return -EFAULT;
-			break;
-		}
-	case PMEM_GET_TOTAL_SIZE:
-		{
-			struct pmem_region region;
-			DLOG("get total size\n");
-			region.offset = 0;
-			get_id(file);
-			region.len = pmem[id].size;
-			if (copy_to_user((void __user *)arg, &region,
-						sizeof(struct pmem_region)))
-				return -EFAULT;
-			break;
-		}
-	case PMEM_ALLOCATE:
-		{
-			if (has_allocation(file))
-				return -EINVAL;
-			data = (struct pmem_data *)file->private_data;
-			data->index = pmem_allocate(id, arg);
-			break;
-		}
-	case PMEM_CONNECT:
-		DLOG("connect\n");
-		return pmem_connect(arg, file);
-		break;
-	case PMEM_CACHE_FLUSH:
-		{
-			struct pmem_region region;
-			DLOG("flush\n");
-			if (copy_from_user(&region, (void __user *)arg,
-					   sizeof(struct pmem_region)))
-				return -EFAULT;
-			flush_pmem_file(file, region.offset, region.len);
-			break;
-		}
-	default:
-		if (pmem[id].ioctl)
-			return pmem[id].ioctl(file, cmd, arg);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-#if PMEM_DEBUG
-static ssize_t debug_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
-			  loff_t *ppos)
-{
-	struct list_head *elt, *elt2;
-	struct pmem_data *data;
-	struct pmem_region_node *region_node;
-	int id = (int)file->private_data;
-	const int debug_bufmax = 4096;
-	static char buffer[4096];
-	int n = 0;
-
-	DLOG("debug open\n");
-	n = scnprintf(buffer, debug_bufmax,
-		      "pid #: mapped regions (offset, len) (offset,len)...\n");
-
-	mutex_lock(&pmem[id].data_list_lock);
-	list_for_each(elt, &pmem[id].data_list) {
-		data = list_entry(elt, struct pmem_data, list);
-		down_read(&data->sem);
-		n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:",
-				data->pid);
-		list_for_each(elt2, &data->region_list) {
-			region_node = list_entry(elt2, struct pmem_region_node,
-				      list);
-			n += scnprintf(buffer + n, debug_bufmax - n,
-					"(%lx,%lx) ",
-					region_node->region.offset,
-					region_node->region.len);
-		}
-		n += scnprintf(buffer + n, debug_bufmax - n, "\n");
-		up_read(&data->sem);
-	}
-	mutex_unlock(&pmem[id].data_list_lock);
-
-	n++;
-	buffer[n] = 0;
-	return simple_read_from_buffer(buf, count, ppos, buffer, n);
-}
-
-static struct file_operations debug_fops = {
-	.read = debug_read,
-	.open = debug_open,
-};
-#endif
-
-#if 0
-static struct miscdevice pmem_dev = {
-	.name = "pmem",
-	.fops = &pmem_fops,
-};
-#endif
-
-int pmem_setup(struct android_pmem_platform_data *pdata,
-	       long (*ioctl)(struct file *, unsigned int, unsigned long),
-	       int (*release)(struct inode *, struct file *))
-{
-	int err = 0;
-	int i, index = 0;
-	int id = id_count;
-	id_count++;
-
-	pmem[id].no_allocator = pdata->no_allocator;
-	pmem[id].cached = pdata->cached;
-	pmem[id].buffered = pdata->buffered;
-	pmem[id].base = pdata->start;
-	pmem[id].size = pdata->size;
-	pmem[id].ioctl = ioctl;
-	pmem[id].release = release;
-	init_rwsem(&pmem[id].bitmap_sem);
-	mutex_init(&pmem[id].data_list_lock);
-	INIT_LIST_HEAD(&pmem[id].data_list);
-	pmem[id].dev.name = pdata->name;
-	pmem[id].dev.minor = id;
-	pmem[id].dev.fops = &pmem_fops;
-	printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached);
-
-	err = misc_register(&pmem[id].dev);
-	if (err) {
-		printk(KERN_ALERT "Unable to register pmem driver!\n");
-		goto err_cant_register_device;
-	}
-	pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC;
-
-	pmem[id].bitmap = kmalloc(pmem[id].num_entries *
-				  sizeof(struct pmem_bits), GFP_KERNEL);
-	if (!pmem[id].bitmap)
-		goto err_no_mem_for_metadata;
-
-	memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) *
-					  pmem[id].num_entries);
-
-	for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) {
-		if ((pmem[id].num_entries) &  1<<i) {
-			PMEM_ORDER(id, index) = i;
-			index = PMEM_NEXT_INDEX(id, index);
-		}
-	}
-
-	if (pmem[id].cached)
-		pmem[id].vbase = ioremap_cached(pmem[id].base,
-						pmem[id].size);
-#ifdef ioremap_ext_buffered
-	else if (pmem[id].buffered)
-		pmem[id].vbase = ioremap_ext_buffered(pmem[id].base,
-						      pmem[id].size);
-#endif
-	else
-		pmem[id].vbase = ioremap(pmem[id].base, pmem[id].size);
-
-	if (pmem[id].vbase == 0)
-		goto error_cant_remap;
-
-	pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
-	if (pmem[id].no_allocator)
-		pmem[id].allocated = 0;
-
-#if PMEM_DEBUG
-	debugfs_create_file(pdata->name, S_IFREG | S_IRUGO, NULL, (void *)id,
-			    &debug_fops);
-#endif
-	return 0;
-error_cant_remap:
-	kfree(pmem[id].bitmap);
-err_no_mem_for_metadata:
-	misc_deregister(&pmem[id].dev);
-err_cant_register_device:
-	return -1;
-}
-
-static int pmem_probe(struct platform_device *pdev)
-{
-	struct android_pmem_platform_data *pdata;
-
-	if (!pdev || !pdev->dev.platform_data) {
-		printk(KERN_ALERT "Unable to probe pmem!\n");
-		return -1;
-	}
-	pdata = pdev->dev.platform_data;
-	return pmem_setup(pdata, NULL, NULL);
-}
-
-
-static int pmem_remove(struct platform_device *pdev)
-{
-	int id = pdev->id;
-	__free_page(pfn_to_page(pmem[id].garbage_pfn));
-	misc_deregister(&pmem[id].dev);
-	return 0;
-}
-
-static struct platform_driver pmem_driver = {
-	.probe = pmem_probe,
-	.remove = pmem_remove,
-	.driver = { .name = "android_pmem" }
-};
-
-
-static int __init pmem_init(void)
-{
-	return platform_driver_register(&pmem_driver);
-}
-
-static void __exit pmem_exit(void)
-{
-	platform_driver_unregister(&pmem_driver);
-}
-
-module_init(pmem_init);
-module_exit(pmem_exit);
-
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index e77e4e0..1df9586 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -355,7 +355,14 @@
 
 static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
 {
-	while (count-- > 0 && val) {
+	odev->last_val = val;
+
+	if (val == 0) {
+		odev->buf_offs += count;
+		return 0;
+	}
+
+	while (count-- > 0) {
 		size_t x = odev->buf_offs % odev->width;
 		size_t y = odev->buf_offs / odev->width;
 		size_t i;
@@ -406,7 +413,6 @@
 			;
 		}
 
-		odev->last_val = val;
 		odev->buf_offs++;
 	}
 
@@ -805,10 +811,9 @@
 
 static void __exit asus_oled_exit(void)
 {
+	usb_deregister(&oled_driver);
 	class_remove_file(oled_class, &class_attr_version.attr);
 	class_destroy(oled_class);
-
-	usb_deregister(&oled_driver);
 }
 
 module_init(asus_oled_init);
diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig
deleted file mode 100644
index c7a2b3b..0000000
--- a/drivers/staging/gma500/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-config DRM_PSB
-	tristate "Intel GMA5/600 KMS Framebuffer"
-	depends on DRM && PCI && X86 && BROKEN
-	select FB_CFB_COPYAREA
-        select FB_CFB_FILLRECT
-        select FB_CFB_IMAGEBLIT
-        select DRM_KMS_HELPER
-        select DRM_TTM
-	help
-	  Say yes for an experimental 2D KMS framebuffer driver for the
-	  Intel GMA500 ('Poulsbo') and other Intel IMG based graphics
-	  devices.
-
-config DRM_PSB_MRST
-	bool "Intel GMA600 support (Experimental)"
-	depends on DRM_PSB
-	help
-	  Say yes to include support for GMA600 (Intel Moorestown/Oaktrail)
-	  platforms with LVDS ports. HDMI and MIPI are not currently
-	  supported.
-
-config DRM_PSB_MFLD
-	bool "Intel Medfield support (Experimental)"
-	depends on DRM_PSB
-	help
-	  Say yes to include support for Intel Medfield platforms with MIPI
-	  interfaces.
-	
-config DRM_PSB_CDV
-	bool "Intel Cedarview support (Experimental)"
-	depends on DRM_PSB
-	help
-	  Say yes to include support for Intel Cedarview platforms
diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
deleted file mode 100644
index c729868..0000000
--- a/drivers/staging/gma500/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-#	KMS driver for the GMA500
-#
-ccflags-y += -Iinclude/drm
-
-psb_gfx-y += gem_glue.o \
-	  accel_2d.o \
-	  backlight.o \
-	  framebuffer.o \
-	  gem.o \
-	  gtt.o \
-	  intel_bios.o \
-	  intel_i2c.o \
-	  intel_opregion.o \
-	  mmu.o \
-	  power.o \
-	  psb_drv.o \
-	  psb_intel_display.o \
-	  psb_intel_lvds.o \
-	  psb_intel_modes.o \
-	  psb_intel_sdvo.o \
-	  psb_lid.o \
-	  psb_irq.o \
-	  psb_device.o \
-	  mid_bios.o
-
-psb_gfx-$(CONFIG_DRM_PSB_CDV) +=  cdv_device.o \
-	  cdv_intel_crt.o \
-	  cdv_intel_display.o \
-	  cdv_intel_hdmi.o \
-	  cdv_intel_lvds.o
-
-psb_gfx-$(CONFIG_DRM_PSB_MRST) += mrst_device.o \
-	  mrst_crtc.o \
-	  mrst_lvds.o \
-	  mrst_hdmi.o \
-	  mrst_hdmi_i2c.o
-
-psb_gfx-$(CONFIG_DRM_PSB_MFLD) += mdfld_device.o \
-	  mdfld_output.o \
-	  mdfld_pyr_cmd.o \
-	  mdfld_tmd_vid.o \
-	  mdfld_tpo_cmd.o \
-	  mdfld_tpo_vid.o \
-	  mdfld_dsi_pkg_sender.o \
-	  mdfld_dsi_dpi.o \
-	  mdfld_dsi_output.o \
-	  mdfld_dsi_dbi.o \
-	  mdfld_dsi_dbi_dpu.o \
-	  mdfld_intel_display.o
-
-obj-$(CONFIG_DRM_PSB) += psb_gfx.o
diff --git a/drivers/staging/gma500/TODO b/drivers/staging/gma500/TODO
deleted file mode 100644
index fc83615..0000000
--- a/drivers/staging/gma500/TODO
+++ /dev/null
@@ -1,15 +0,0 @@
--	Sort out the power management side. Not important for Poulsbo but
-	matters for Moorestown/Medfield
--	Debug Oaktrail/Moorestown support (single pipe, no BIOS on mrst,
-					some other differences)
--	Add 2D acceleration via console and DRM
--	Add scrolling acceleration using the GTT to do remapping on the main
-	framebuffer.
--	HDMI testing
--	Oaktrail HDMI and other features
--	Oaktrail MIPI
--	Medfield needs a lot of further love
-
-As per kernel policy and the in the interest of the safety of various
-kittens there is no support or plans to add hooks for the closed user space
-stuff.
diff --git a/drivers/staging/gma500/accel_2d.c b/drivers/staging/gma500/accel_2d.c
deleted file mode 100644
index b8f78eb..0000000
--- a/drivers/staging/gma500/accel_2d.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- * develop this driver.
- *
- **************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/console.h>
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "framebuffer.h"
-
-/**
- *	psb_spank		-	reset the 2D engine
- *	@dev_priv: our PSB DRM device
- *
- *	Soft reset the graphics engine and then reload the necessary registers.
- *	We use this at initialisation time but it will become relevant for
- *	accelerated X later
- */
-void psb_spank(struct drm_psb_private *dev_priv)
-{
-	PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET |
-		_PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET |
-		_PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET |
-		_PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET);
-	PSB_RSGX32(PSB_CR_SOFT_RESET);
-
-	msleep(1);
-
-	PSB_WSGX32(0, PSB_CR_SOFT_RESET);
-	wmb();
-	PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT,
-		   PSB_CR_BIF_CTRL);
-	wmb();
-	(void) PSB_RSGX32(PSB_CR_BIF_CTRL);
-
-	msleep(1);
-	PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT,
-		   PSB_CR_BIF_CTRL);
-	(void) PSB_RSGX32(PSB_CR_BIF_CTRL);
-	PSB_WSGX32(dev_priv->gtt.gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
-}
-
-/**
- *	psb2_2d_wait_available	-	wait for FIFO room
- *	@dev_priv: our DRM device
- *	@size: size (in dwords) of the command we want to issue
- *
- *	Wait until there is room to load the FIFO with our data. If the
- *	device is not responding then reset it
- */
-static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
-			  unsigned size)
-{
-	uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
-	unsigned long t = jiffies + HZ;
-
-	while (avail < size) {
-		avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
-		if (time_after(jiffies, t)) {
-			psb_spank(dev_priv);
-			return -EIO;
-		}
-	}
-	return 0;
-}
-
-/**
- *	psb_2d_submit		-	submit a 2D command
- *	@dev_priv: our DRM device
- *	@cmdbuf: command to issue
- *	@size: length (in dwords)
- *
- *	Issue one or more 2D commands to the accelerator. This needs to be
- *	serialized later when we add the GEM interfaces for acceleration
- */
-static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
-								unsigned size)
-{
-	int ret = 0;
-	int i;
-	unsigned submit_size;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev_priv->lock_2d, flags);
-	while (size > 0) {
-		submit_size = (size < 0x60) ? size : 0x60;
-		size -= submit_size;
-		ret = psb_2d_wait_available(dev_priv, submit_size);
-		if (ret)
-			break;
-
-		submit_size <<= 2;
-
-		for (i = 0; i < submit_size; i += 4)
-			PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i);
-
-		(void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
-	}
-	spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
-	return ret;
-}
-
-
-/**
- *	psb_accel_2d_copy_direction	-	compute blit order
- *	@xdir: X direction of move
- *	@ydir: Y direction of move
- *
- *	Compute the correct order setings to ensure that an overlapping blit
- *	correctly copies all the pixels.
- */
-static u32 psb_accel_2d_copy_direction(int xdir, int ydir)
-{
-	if (xdir < 0)
-		return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL :
-						PSB_2D_COPYORDER_TR2BL;
-	else
-		return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR :
-						PSB_2D_COPYORDER_TL2BR;
-}
-
-/**
- *	psb_accel_2d_copy		-	accelerated 2D copy
- *	@dev_priv: our DRM device
- *	@src_offset in bytes
- *	@src_stride in bytes
- *	@src_format psb 2D format defines
- *	@dst_offset in bytes
- *	@dst_stride in bytes
- *	@dst_format psb 2D format defines
- *	@src_x offset in pixels
- *	@src_y offset in pixels
- *	@dst_x offset in pixels
- *	@dst_y offset in pixels
- *	@size_x of the copied area
- *	@size_y of the copied area
- *
- *	Format and issue a 2D accelerated copy command.
- */
-static int psb_accel_2d_copy(struct drm_psb_private *dev_priv,
-			     uint32_t src_offset, uint32_t src_stride,
-			     uint32_t src_format, uint32_t dst_offset,
-			     uint32_t dst_stride, uint32_t dst_format,
-			     uint16_t src_x, uint16_t src_y,
-			     uint16_t dst_x, uint16_t dst_y,
-			     uint16_t size_x, uint16_t size_y)
-{
-	uint32_t blit_cmd;
-	uint32_t buffer[10];
-	uint32_t *buf;
-	uint32_t direction;
-
-	buf = buffer;
-
-	direction =
-	    psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y);
-
-	if (direction == PSB_2D_COPYORDER_BR2TL ||
-	    direction == PSB_2D_COPYORDER_TR2BL) {
-		src_x += size_x - 1;
-		dst_x += size_x - 1;
-	}
-	if (direction == PSB_2D_COPYORDER_BR2TL ||
-	    direction == PSB_2D_COPYORDER_BL2TR) {
-		src_y += size_y - 1;
-		dst_y += size_y - 1;
-	}
-
-	blit_cmd =
-	    PSB_2D_BLIT_BH |
-	    PSB_2D_ROT_NONE |
-	    PSB_2D_DSTCK_DISABLE |
-	    PSB_2D_SRCCK_DISABLE |
-	    PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction;
-
-	*buf++ = PSB_2D_FENCE_BH;
-	*buf++ =
-	    PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
-					       PSB_2D_DST_STRIDE_SHIFT);
-	*buf++ = dst_offset;
-	*buf++ =
-	    PSB_2D_SRC_SURF_BH | src_format | (src_stride <<
-					       PSB_2D_SRC_STRIDE_SHIFT);
-	*buf++ = src_offset;
-	*buf++ =
-	    PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) |
-	    (src_y << PSB_2D_SRCOFF_YSTART_SHIFT);
-	*buf++ = blit_cmd;
-	*buf++ =
-	    (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
-						  PSB_2D_DST_YSTART_SHIFT);
-	*buf++ =
-	    (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
-						  PSB_2D_DST_YSIZE_SHIFT);
-	*buf++ = PSB_2D_FLUSH_BH;
-
-	return psbfb_2d_submit(dev_priv, buffer, buf - buffer);
-}
-
-/**
- *	psbfb_copyarea_accel	-	copyarea acceleration for /dev/fb
- *	@info: our framebuffer
- *	@a: copyarea parameters from the framebuffer core
- *
- *	Perform a 2D copy via the accelerator
- */
-static void psbfb_copyarea_accel(struct fb_info *info,
-				 const struct fb_copyarea *a)
-{
-	struct psb_fbdev *fbdev = info->par;
-	struct psb_framebuffer *psbfb = &fbdev->pfb;
-	struct drm_device *dev = psbfb->base.dev;
-	struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	uint32_t offset;
-	uint32_t stride;
-	uint32_t src_format;
-	uint32_t dst_format;
-
-	if (!fb)
-		return;
-
-	offset = psbfb->gtt->offset;
-	stride = fb->pitches[0];
-
-	switch (fb->depth) {
-	case 8:
-		src_format = PSB_2D_SRC_332RGB;
-		dst_format = PSB_2D_DST_332RGB;
-		break;
-	case 15:
-		src_format = PSB_2D_SRC_555RGB;
-		dst_format = PSB_2D_DST_555RGB;
-		break;
-	case 16:
-		src_format = PSB_2D_SRC_565RGB;
-		dst_format = PSB_2D_DST_565RGB;
-		break;
-	case 24:
-	case 32:
-		/* this is wrong but since we don't do blending its okay */
-		src_format = PSB_2D_SRC_8888ARGB;
-		dst_format = PSB_2D_DST_8888ARGB;
-		break;
-	default:
-		/* software fallback */
-		cfb_copyarea(info, a);
-		return;
-	}
-
-	if (!gma_power_begin(dev, false)) {
-		cfb_copyarea(info, a);
-		return;
-	}
-	psb_accel_2d_copy(dev_priv,
-			  offset, stride, src_format,
-			  offset, stride, dst_format,
-			  a->sx, a->sy, a->dx, a->dy, a->width, a->height);
-	gma_power_end(dev);
-}
-
-/**
- *	psbfb_copyarea	-	2D copy interface
- *	@info: our framebuffer
- *	@region: region to copy
- *
- *	Copy an area of the framebuffer console either by the accelerator
- *	or directly using the cfb helpers according to the request
- */
-void psbfb_copyarea(struct fb_info *info,
-			   const struct fb_copyarea *region)
-{
-	if (unlikely(info->state != FBINFO_STATE_RUNNING))
-		return;
-
-	/* Avoid the 8 pixel erratum */
-	if (region->width == 8 || region->height == 8 ||
-		(info->flags & FBINFO_HWACCEL_DISABLED))
-		return cfb_copyarea(info, region);
-
-	psbfb_copyarea_accel(info, region);
-}
-
-/**
- *	psbfb_sync	-	synchronize 2D
- *	@info: our framebuffer
- *
- *	Wait for the 2D engine to quiesce so that we can do CPU
- *	access to the framebuffer again
- */
-int psbfb_sync(struct fb_info *info)
-{
-	struct psb_fbdev *fbdev = info->par;
-	struct psb_framebuffer *psbfb = &fbdev->pfb;
-	struct drm_device *dev = psbfb->base.dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long _end = jiffies + DRM_HZ;
-	int busy = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev_priv->lock_2d, flags);
-	/*
-	 * First idle the 2D engine.
-	 */
-
-	if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) &&
-	    ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0))
-		goto out;
-
-	do {
-		busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
-		cpu_relax();
-	} while (busy && !time_after_eq(jiffies, _end));
-
-	if (busy)
-		busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
-	if (busy)
-		goto out;
-
-	do {
-		busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
-						_PSB_C2B_STATUS_BUSY) != 0);
-		cpu_relax();
-	} while (busy && !time_after_eq(jiffies, _end));
-	if (busy)
-		busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
-					_PSB_C2B_STATUS_BUSY) != 0);
-
-out:
-	spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
-	return (busy) ? -EBUSY : 0;
-}
-
-int psb_accel_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_psb_2d_op *op = data;
-	u32 *op_ptr = &op->cmd[0];
-	int i;
-	struct drm_gem_object *obj;
-	struct gtt_range *gtt;
-	int err = -EINVAL;
-
-	if (!dev_priv->ops->accel_2d)
-		return -EOPNOTSUPP;
-	if (op->size > PSB_2D_OP_BUFLEN)
-		return -EINVAL;
-
-	/* The GEM object being used. We need to support separate src/dst/etc
-	   in the end but for now keep them all the same */
-	obj = drm_gem_object_lookup(dev, file, op->src);
-	if (obj == NULL)
-		return -ENOENT;
-	gtt = container_of(obj, struct gtt_range, gem);
-
-	if (psb_gtt_pin(gtt) < 0)
-		goto bad_2;
-	for (i = 0; i < op->size; i++, op_ptr++) {
-		u32 r = *op_ptr & 0xF0000000;
-		/* Fill in the GTT offsets for the command buffer */
-		if (r == PSB_2D_SRC_SURF_BH ||
-			r == PSB_2D_DST_SURF_BH ||
-			r == PSB_2D_MASK_SURF_BH ||
-			r == PSB_2D_PAT_SURF_BH) {
-			i++;
-			op_ptr++;
-			if (i == op->size)
-				goto bad;
-			if (*op_ptr)
-				goto bad;
-			*op_ptr = gtt->offset;
-			continue;
-		}
-	}
-	psbfb_2d_submit(dev_priv, op->cmd, op->size);
-	err = 0;
-bad:
-	psb_gtt_unpin(gtt);
-bad_2:
-	drm_gem_object_unreference(obj);
-	return err;
-}
diff --git a/drivers/staging/gma500/backlight.c b/drivers/staging/gma500/backlight.c
deleted file mode 100644
index 2079395..0000000
--- a/drivers/staging/gma500/backlight.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * GMA500 Backlight Interface
- *
- * Copyright (c) 2009-2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Eric Knopp
- *
- */
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_drv.h"
-#include "intel_bios.h"
-#include "power.h"
-
-int gma_backlight_init(struct drm_device *dev)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	return dev_priv->ops->backlight_init(dev);
-#else
-	return 0;
-#endif
-}
-
-void gma_backlight_exit(struct drm_device *dev)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	if (dev_priv->backlight_device) {
-		dev_priv->backlight_device->props.brightness = 0;
-		backlight_update_status(dev_priv->backlight_device);
-		backlight_device_unregister(dev_priv->backlight_device);
-	}
-#endif
-}
diff --git a/drivers/staging/gma500/cdv_device.c b/drivers/staging/gma500/cdv_device.c
deleted file mode 100644
index 8ec10ca..0000000
--- a/drivers/staging/gma500/cdv_device.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-#include "cdv_device.h"
-
-#define VGA_SR_INDEX		0x3c4
-#define VGA_SR_DATA		0x3c5
-
-static void cdv_disable_vga(struct drm_device *dev)
-{
-	u8 sr1;
-	u32 vga_reg;
-
-	vga_reg = VGACNTRL;
-
-	outb(1, VGA_SR_INDEX);
-	sr1 = inb(VGA_SR_DATA);
-	outb(sr1 | 1<<5, VGA_SR_DATA);
-	udelay(300);
-
-	REG_WRITE(vga_reg, VGA_DISP_DISABLE);
-	REG_READ(vga_reg);
-}
-
-static int cdv_output_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	cdv_disable_vga(dev);
-
-	cdv_intel_crt_init(dev, &dev_priv->mode_dev);
-	cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
-
-	/* These bits indicate HDMI not SDVO on CDV, but we don't yet support
-	   the HDMI interface */
-	if (REG_READ(SDVOB) & SDVO_DETECTED)
-		cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
-	if (REG_READ(SDVOC) & SDVO_DETECTED)
-		cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC);
-	return 0;
-}
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-/*
- *	Poulsbo Backlight Interfaces
- */
-
-#define BLC_PWM_PRECISION_FACTOR 100	/* 10000000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 1000000
-
-#define PSB_BLC_PWM_PRECISION_FACTOR    10
-#define PSB_BLC_MAX_PWM_REG_FREQ        0xFFFE
-#define PSB_BLC_MIN_PWM_REG_FREQ        0x2
-
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)
-
-static int cdv_brightness;
-static struct backlight_device *cdv_backlight_device;
-
-static int cdv_get_brightness(struct backlight_device *bd)
-{
-	/* return locally cached var instead of HW read (due to DPST etc.) */
-	/* FIXME: ideally return actual value in case firmware fiddled with
-	   it */
-	return cdv_brightness;
-}
-
-
-static int cdv_backlight_setup(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long core_clock;
-	/* u32 bl_max_freq; */
-	/* unsigned long value; */
-	u16 bl_max_freq;
-	uint32_t value;
-	uint32_t blc_pwm_precision_factor;
-
-	/* get bl_max_freq and pol from dev_priv*/
-	if (!dev_priv->lvds_bl) {
-		dev_err(dev->dev, "Has no valid LVDS backlight info\n");
-		return -ENOENT;
-	}
-	bl_max_freq = dev_priv->lvds_bl->freq;
-	blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
-
-	core_clock = dev_priv->core_freq;
-
-	value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
-	value *= blc_pwm_precision_factor;
-	value /= bl_max_freq;
-	value /= blc_pwm_precision_factor;
-
-	if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
-		 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
-				return -ERANGE;
-	else {
-		/* FIXME */
-	}
-	return 0;
-}
-
-static int cdv_set_brightness(struct backlight_device *bd)
-{
-	int level = bd->props.brightness;
-
-	/* Percentage 1-100% being valid */
-	if (level < 1)
-		level = 1;
-
-	/*cdv_intel_lvds_set_brightness(dev, level); FIXME */
-	cdv_brightness = level;
-	return 0;
-}
-
-static const struct backlight_ops cdv_ops = {
-	.get_brightness = cdv_get_brightness,
-	.update_status  = cdv_set_brightness,
-};
-
-static int cdv_backlight_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int ret;
-	struct backlight_properties props;
-
-	memset(&props, 0, sizeof(struct backlight_properties));
-	props.max_brightness = 100;
-	props.type = BACKLIGHT_PLATFORM;
-
-	cdv_backlight_device = backlight_device_register("psb-bl",
-					NULL, (void *)dev, &cdv_ops, &props);
-	if (IS_ERR(cdv_backlight_device))
-		return PTR_ERR(cdv_backlight_device);
-
-	ret = cdv_backlight_setup(dev);
-	if (ret < 0) {
-		backlight_device_unregister(cdv_backlight_device);
-		cdv_backlight_device = NULL;
-		return ret;
-	}
-	cdv_backlight_device->props.brightness = 100;
-	cdv_backlight_device->props.max_brightness = 100;
-	backlight_update_status(cdv_backlight_device);
-	dev_priv->backlight_device = cdv_backlight_device;
-	return 0;
-}
-
-#endif
-
-/*
- *	Provide the Cedarview specific chip logic and low level methods
- *	for power management
- *
- *	FIXME: we need to implement the apm/ospm base management bits
- *	for this and the MID devices.
- */
-
-static inline u32 CDV_MSG_READ32(uint port, uint offset)
-{
-	int mcr = (0x10<<24) | (port << 16) | (offset << 8);
-	uint32_t ret_val = 0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	pci_write_config_dword(pci_root, 0xD0, mcr);
-	pci_read_config_dword(pci_root, 0xD4, &ret_val);
-	pci_dev_put(pci_root);
-	return ret_val;
-}
-
-static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value)
-{
-	int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	pci_write_config_dword(pci_root, 0xD4, value);
-	pci_write_config_dword(pci_root, 0xD0, mcr);
-	pci_dev_put(pci_root);
-}
-
-#define PSB_APM_CMD			0x0
-#define PSB_APM_STS			0x04
-#define PSB_PM_SSC			0x20
-#define PSB_PM_SSS			0x30
-#define PSB_PWRGT_GFX_MASK		0x3
-#define CDV_PWRGT_DISPLAY_CNTR		0x000fc00c
-#define CDV_PWRGT_DISPLAY_STS		0x000fc00c
-
-static void cdv_init_pm(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 pwr_cnt;
-	int i;
-
-	dev_priv->apm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
-							PSB_APMBA) & 0xFFFF;
-	dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
-							PSB_OSPMBA) & 0xFFFF;
-
-	/* Force power on for now */
-	pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD);
-	pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
-
-	outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD);
-	for (i = 0; i < 5; i++) {
-		u32 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
-		if ((pwr_sts & PSB_PWRGT_GFX_MASK) == 0)
-			break;
-		udelay(10);
-	}
-	pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
-	pwr_cnt &= ~CDV_PWRGT_DISPLAY_CNTR;
-	outl(pwr_cnt, dev_priv->ospm_base + PSB_PM_SSC);
-	for (i = 0; i < 5; i++) {
-		u32 pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
-		if ((pwr_sts & CDV_PWRGT_DISPLAY_STS) == 0)
-			break;
-		udelay(10);
-	}
-}
-
-/**
- *	cdv_save_display_registers	-	save registers lost on suspend
- *	@dev: our DRM device
- *
- *	Save the state we need in order to be able to restore the interface
- *	upon resume from suspend
- *
- *	FIXME: review
- */
-static int cdv_save_display_registers(struct drm_device *dev)
-{
-	return 0;
-}
-
-/**
- *	cdv_restore_display_registers	-	restore lost register state
- *	@dev: our DRM device
- *
- *	Restore register state that was lost during suspend and resume.
- *
- *	FIXME: review
- */
-static int cdv_restore_display_registers(struct drm_device *dev)
-{
-	return 0;
-}
-
-static int cdv_power_down(struct drm_device *dev)
-{
-	return 0;
-}
-
-static int cdv_power_up(struct drm_device *dev)
-{
-	return 0;
-}
-
-/* FIXME ? - shared with Poulsbo */
-static void cdv_get_core_freq(struct drm_device *dev)
-{
-	uint32_t clock;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
-	pci_read_config_dword(pci_root, 0xD4, &clock);
-	pci_dev_put(pci_root);
-
-	switch (clock & 0x07) {
-	case 0:
-		dev_priv->core_freq = 100;
-		break;
-	case 1:
-		dev_priv->core_freq = 133;
-		break;
-	case 2:
-		dev_priv->core_freq = 150;
-		break;
-	case 3:
-		dev_priv->core_freq = 178;
-		break;
-	case 4:
-		dev_priv->core_freq = 200;
-		break;
-	case 5:
-	case 6:
-	case 7:
-		dev_priv->core_freq = 266;
-	default:
-		dev_priv->core_freq = 0;
-	}
-}
-
-static int cdv_chip_setup(struct drm_device *dev)
-{
-	cdv_get_core_freq(dev);
-	gma_intel_opregion_init(dev);
-	psb_intel_init_bios(dev);
-	return 0;
-}
-
-/* CDV is much like Poulsbo but has MID like SGX offsets and PM */
-
-const struct psb_ops cdv_chip_ops = {
-	.name = "Cedartrail",
-	.accel_2d = 0,
-	.pipes = 2,
-	.sgx_offset = MRST_SGX_OFFSET,
-	.chip_setup = cdv_chip_setup,
-
-	.crtc_helper = &cdv_intel_helper_funcs,
-	.crtc_funcs = &cdv_intel_crtc_funcs,
-
-	.output_init = cdv_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	.backlight_init = cdv_backlight_init,
-#endif
-
-	.init_pm = cdv_init_pm,
-	.save_regs = cdv_save_display_registers,
-	.restore_regs = cdv_restore_display_registers,
-	.power_down = cdv_power_down,
-	.power_up = cdv_power_up,
-};
diff --git a/drivers/staging/gma500/cdv_device.h b/drivers/staging/gma500/cdv_device.h
deleted file mode 100644
index 2a88b7b..0000000
--- a/drivers/staging/gma500/cdv_device.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright © 2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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., 
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-extern const struct drm_crtc_helper_funcs cdv_intel_helper_funcs;
-extern const struct drm_crtc_funcs cdv_intel_crtc_funcs;
-extern void cdv_intel_crt_init(struct drm_device *dev,
-			struct psb_intel_mode_device *mode_dev);
-extern void cdv_intel_lvds_init(struct drm_device *dev,
-			struct psb_intel_mode_device *mode_dev);
-extern void cdv_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev,
-			int reg);
-extern struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev,
-					     struct drm_crtc *crtc);
-
-extern inline void cdv_intel_wait_for_vblank(struct drm_device *dev)
-{
-	/* Wait for 20ms, i.e. one cycle at 50hz. */
-        /* FIXME: msleep ?? */
-	mdelay(20);
-}
-
-
diff --git a/drivers/staging/gma500/cdv_intel_crt.c b/drivers/staging/gma500/cdv_intel_crt.c
deleted file mode 100644
index efda63b..0000000
--- a/drivers/staging/gma500/cdv_intel_crt.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright © 2006-2007 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include <linux/pm_runtime.h>
-
-
-static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct drm_device *dev = encoder->dev;
-	u32 temp, reg;
-	reg = ADPA;
-
-	temp = REG_READ(reg);
-	temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
-	temp &= ~ADPA_DAC_ENABLE;
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		temp |= ADPA_DAC_ENABLE;
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-		temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
-		break;
-	case DRM_MODE_DPMS_SUSPEND:
-		temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
-		break;
-	case DRM_MODE_DPMS_OFF:
-		temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
-		break;
-	}
-
-	REG_WRITE(reg, temp);
-}
-
-static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
-				struct drm_display_mode *mode)
-{
-	int max_clock = 0;
-	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-		return MODE_NO_DBLESCAN;
-
-	/* The lowest clock for CDV is 20000KHz */
-	if (mode->clock < 20000)
-		return MODE_CLOCK_LOW;
-
-	/* The max clock for CDV is 355 instead of 400 */
-	max_clock = 355000;
-	if (mode->clock > max_clock)
-		return MODE_CLOCK_HIGH;
-
-	if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
-		return MODE_PANEL;
-
-	return MODE_OK;
-}
-
-static bool cdv_intel_crt_mode_fixup(struct drm_encoder *encoder,
-				 struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-static void cdv_intel_crt_mode_set(struct drm_encoder *encoder,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode)
-{
-
-	struct drm_device *dev = encoder->dev;
-	struct drm_crtc *crtc = encoder->crtc;
-	struct psb_intel_crtc *psb_intel_crtc =
-					to_psb_intel_crtc(crtc);
-	int dpll_md_reg;
-	u32 adpa, dpll_md;
-	u32 adpa_reg;
-
-	if (psb_intel_crtc->pipe == 0)
-		dpll_md_reg = DPLL_A_MD;
-	else
-		dpll_md_reg = DPLL_B_MD;
-
-	adpa_reg = ADPA;
-
-	/*
-	 * Disable separate mode multiplier used when cloning SDVO to CRT
-	 * XXX this needs to be adjusted when we really are cloning
-	 */
-	{
-		dpll_md = REG_READ(dpll_md_reg);
-		REG_WRITE(dpll_md_reg,
-			   dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
-	}
-
-	adpa = 0;
-	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
-		adpa |= ADPA_HSYNC_ACTIVE_HIGH;
-	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
-		adpa |= ADPA_VSYNC_ACTIVE_HIGH;
-
-	if (psb_intel_crtc->pipe == 0)
-		adpa |= ADPA_PIPE_A_SELECT;
-	else
-		adpa |= ADPA_PIPE_B_SELECT;
-
-	REG_WRITE(adpa_reg, adpa);
-}
-
-
-/**
- * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
- *
- * \return true if CRT is connected.
- * \return false if CRT is disconnected.
- */
-static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector,
-								bool force)
-{
-	struct drm_device *dev = connector->dev;
-	u32 hotplug_en;
-	int i, tries = 0, ret = false;
-	u32 adpa_orig;
-
-	/* disable the DAC when doing the hotplug detection */
-
-	adpa_orig = REG_READ(ADPA);
-
-	REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE));
-
-	/*
-	 * On a CDV thep, CRT detect sequence need to be done twice
-	 * to get a reliable result.
-	 */
-	tries = 2;
-
-	hotplug_en = REG_READ(PORT_HOTPLUG_EN);
-	hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK);
-	hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
-
-	hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
-	hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
-
-	for (i = 0; i < tries ; i++) {
-		unsigned long timeout;
-		/* turn on the FORCE_DETECT */
-		REG_WRITE(PORT_HOTPLUG_EN, hotplug_en);
-		timeout = jiffies + msecs_to_jiffies(1000);
-		/* wait for FORCE_DETECT to go off */
-		do {
-			if (!(REG_READ(PORT_HOTPLUG_EN) &
-					CRT_HOTPLUG_FORCE_DETECT))
-				break;
-			msleep(1);
-		} while (time_after(timeout, jiffies));
-	}
-
-	if ((REG_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
-	    CRT_HOTPLUG_MONITOR_NONE)
-		ret = true;
-
-	/* Restore the saved ADPA */
-	REG_WRITE(ADPA, adpa_orig);
-	return ret;
-}
-
-static enum drm_connector_status cdv_intel_crt_detect(
-				struct drm_connector *connector, bool force)
-{
-	if (cdv_intel_crt_detect_hotplug(connector, force))
-		return connector_status_connected;
-	else
-		return connector_status_disconnected;
-}
-
-static void cdv_intel_crt_destroy(struct drm_connector *connector)
-{
-	struct psb_intel_output *intel_output = to_psb_intel_output(connector);
-
-	psb_intel_i2c_destroy(intel_output->ddc_bus);
-	drm_sysfs_connector_remove(connector);
-	drm_connector_cleanup(connector);
-	kfree(connector);
-}
-
-static int cdv_intel_crt_get_modes(struct drm_connector *connector)
-{
-	struct psb_intel_output *intel_output =
-				to_psb_intel_output(connector);
-	return psb_intel_ddc_get_modes(intel_output);
-}
-
-static int cdv_intel_crt_set_property(struct drm_connector *connector,
-				  struct drm_property *property,
-				  uint64_t value)
-{
-	return 0;
-}
-
-/*
- * Routines for controlling stuff on the analog port
- */
-
-static const struct drm_encoder_helper_funcs cdv_intel_crt_helper_funcs = {
-	.dpms = cdv_intel_crt_dpms,
-	.mode_fixup = cdv_intel_crt_mode_fixup,
-	.prepare = psb_intel_encoder_prepare,
-	.commit = psb_intel_encoder_commit,
-	.mode_set = cdv_intel_crt_mode_set,
-};
-
-static const struct drm_connector_funcs cdv_intel_crt_connector_funcs = {
-	.dpms = drm_helper_connector_dpms,
-	.detect = cdv_intel_crt_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = cdv_intel_crt_destroy,
-	.set_property = cdv_intel_crt_set_property,
-};
-
-static const struct drm_connector_helper_funcs
-				cdv_intel_crt_connector_helper_funcs = {
-	.mode_valid = cdv_intel_crt_mode_valid,
-	.get_modes = cdv_intel_crt_get_modes,
-	.best_encoder = psb_intel_best_encoder,
-};
-
-static void cdv_intel_crt_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs cdv_intel_crt_enc_funcs = {
-	.destroy = cdv_intel_crt_enc_destroy,
-};
-
-void cdv_intel_crt_init(struct drm_device *dev,
-			struct psb_intel_mode_device *mode_dev)
-{
-
-	struct psb_intel_output *psb_intel_output;
-	struct drm_connector *connector;
-	struct drm_encoder *encoder;
-
-	u32 i2c_reg;
-
-	psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
-	if (!psb_intel_output)
-		return;
-
-	psb_intel_output->mode_dev = mode_dev;
-	connector = &psb_intel_output->base;
-	drm_connector_init(dev, connector,
-		&cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
-
-	encoder = &psb_intel_output->enc;
-	drm_encoder_init(dev, encoder,
-		&cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC);
-
-	drm_mode_connector_attach_encoder(&psb_intel_output->base,
-					  &psb_intel_output->enc);
-
-	/* Set up the DDC bus. */
-	i2c_reg = GPIOA;
-	/* Remove the following code for CDV */
-	/*
-	if (dev_priv->crt_ddc_bus != 0)
-		i2c_reg = dev_priv->crt_ddc_bus;
-	}*/
-	psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
-						i2c_reg, "CRTDDC_A");
-	if (!psb_intel_output->ddc_bus) {
-		dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
-			   "failed.\n");
-		goto failed_ddc;
-	}
-
-	psb_intel_output->type = INTEL_OUTPUT_ANALOG;
-	/*
-	psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT);
-	psb_intel_output->crtc_mask = (1 << 0) | (1 << 1);
-	*/
-	connector->interlace_allowed = 0;
-	connector->doublescan_allowed = 0;
-
-	drm_encoder_helper_add(encoder, &cdv_intel_crt_helper_funcs);
-	drm_connector_helper_add(connector,
-					&cdv_intel_crt_connector_helper_funcs);
-
-	drm_sysfs_connector_add(connector);
-
-	return;
-failed_ddc:
-	drm_encoder_cleanup(&psb_intel_output->enc);
-	drm_connector_cleanup(&psb_intel_output->base);
-	kfree(psb_intel_output);
-	return;
-}
diff --git a/drivers/staging/gma500/cdv_intel_display.c b/drivers/staging/gma500/cdv_intel_display.c
deleted file mode 100644
index c63a327..0000000
--- a/drivers/staging/gma500/cdv_intel_display.c
+++ /dev/null
@@ -1,1508 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-
-#include <drm/drmP.h>
-#include "framebuffer.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_display.h"
-#include "power.h"
-#include "cdv_device.h"
-
-
-struct cdv_intel_range_t {
-	int min, max;
-};
-
-struct cdv_intel_p2_t {
-	int dot_limit;
-	int p2_slow, p2_fast;
-};
-
-struct cdv_intel_clock_t {
-	/* given values */
-	int n;
-	int m1, m2;
-	int p1, p2;
-	/* derived values */
-	int dot;
-	int vco;
-	int m;
-	int p;
-};
-
-#define INTEL_P2_NUM		      2
-
-struct cdv_intel_limit_t {
-	struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1;
-	struct cdv_intel_p2_t p2;
-};
-
-#define CDV_LIMIT_SINGLE_LVDS_96	0
-#define CDV_LIMIT_SINGLE_LVDS_100	1
-#define CDV_LIMIT_DAC_HDMI_27		2
-#define CDV_LIMIT_DAC_HDMI_96		3
-
-static const struct cdv_intel_limit_t cdv_intel_limits[] = {
-	{			/* CDV_SIGNLE_LVDS_96MHz */
-	 .dot = {.min = 20000, .max = 115500},
-	 .vco = {.min = 1800000, .max = 3600000},
-	 .n = {.min = 2, .max = 6},
-	 .m = {.min = 60, .max = 160},
-	 .m1 = {.min = 0, .max = 0},
-	 .m2 = {.min = 58, .max = 158},
-	 .p = {.min = 28, .max = 140},
-	 .p1 = {.min = 2, .max = 10},
-	 .p2 = {.dot_limit = 200000,
-		.p2_slow = 14, .p2_fast = 14},
-	 },
-	{			/* CDV_SINGLE_LVDS_100MHz */
-	 .dot = {.min = 20000, .max = 115500},
-	 .vco = {.min = 1800000, .max = 3600000},
-	 .n = {.min = 2, .max = 6},
-	 .m = {.min = 60, .max = 160},
-	 .m1 = {.min = 0, .max = 0},
-	 .m2 = {.min = 58, .max = 158},
-	 .p = {.min = 28, .max = 140},
-	 .p1 = {.min = 2, .max = 10},
-	 /* The single-channel range is 25-112Mhz, and dual-channel
-	  * is 80-224Mhz.  Prefer single channel as much as possible.
-	  */
-	 .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14},
-	 },
-	{			/* CDV_DAC_HDMI_27MHz */
-	 .dot = {.min = 20000, .max = 400000},
-	 .vco = {.min = 1809000, .max = 3564000},
-	 .n = {.min = 1, .max = 1},
-	 .m = {.min = 67, .max = 132},
-	 .m1 = {.min = 0, .max = 0},
-	 .m2 = {.min = 65, .max = 130},
-	 .p = {.min = 5, .max = 90},
-	 .p1 = {.min = 1, .max = 9},
-	 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
-	 },
-	{			/* CDV_DAC_HDMI_96MHz */
-	 .dot = {.min = 20000, .max = 400000},
-	 .vco = {.min = 1800000, .max = 3600000},
-	 .n = {.min = 2, .max = 6},
-	 .m = {.min = 60, .max = 160},
-	 .m1 = {.min = 0, .max = 0},
-	 .m2 = {.min = 58, .max = 158},
-	 .p = {.min = 5, .max = 100},
-	 .p1 = {.min = 1, .max = 10},
-	 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
-	 },
-};
-
-#define _wait_for(COND, MS, W) ({ \
-	unsigned long timeout__ = jiffies + msecs_to_jiffies(MS);	\
-	int ret__ = 0;							\
-	while (!(COND)) {						\
-		if (time_after(jiffies, timeout__)) {			\
-			ret__ = -ETIMEDOUT;				\
-			break;						\
-		}							\
-		if (W && !in_dbg_master())				\
-			msleep(W);					\
-	}								\
-	ret__;								\
-})
-
-#define wait_for(COND, MS) _wait_for(COND, MS, 1)
-
-
-static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
-{
-	int ret;
-
-	ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
-	if (ret) {
-		DRM_ERROR("timeout waiting for SB to idle before read\n");
-		return ret;
-	}
-
-	REG_WRITE(SB_ADDR, reg);
-	REG_WRITE(SB_PCKT,
-		   SET_FIELD(SB_OPCODE_READ, SB_OPCODE) |
-		   SET_FIELD(SB_DEST_DPLL, SB_DEST) |
-		   SET_FIELD(0xf, SB_BYTE_ENABLE));
-
-	ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
-	if (ret) {
-		DRM_ERROR("timeout waiting for SB to idle after read\n");
-		return ret;
-	}
-
-	*val = REG_READ(SB_DATA);
-
-	return 0;
-}
-
-static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
-{
-	int ret;
-	static bool dpio_debug = true;
-	u32 temp;
-
-	if (dpio_debug) {
-		if (cdv_sb_read(dev, reg, &temp) == 0)
-			DRM_DEBUG_KMS("0x%08x: 0x%08x (before)\n", reg, temp);
-		DRM_DEBUG_KMS("0x%08x: 0x%08x\n", reg, val);
-	}
-
-	ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
-	if (ret) {
-		DRM_ERROR("timeout waiting for SB to idle before write\n");
-		return ret;
-	}
-
-	REG_WRITE(SB_ADDR, reg);
-	REG_WRITE(SB_DATA, val);
-	REG_WRITE(SB_PCKT,
-		   SET_FIELD(SB_OPCODE_WRITE, SB_OPCODE) |
-		   SET_FIELD(SB_DEST_DPLL, SB_DEST) |
-		   SET_FIELD(0xf, SB_BYTE_ENABLE));
-
-	ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000);
-	if (ret) {
-		DRM_ERROR("timeout waiting for SB to idle after write\n");
-		return ret;
-	}
-
-	if (dpio_debug) {
-		if (cdv_sb_read(dev, reg, &temp) == 0)
-			DRM_DEBUG_KMS("0x%08x: 0x%08x (after)\n", reg, temp);
-	}
-
-	return 0;
-}
-
-/* Reset the DPIO configuration register.  The BIOS does this at every
- * mode set.
- */
-static void cdv_sb_reset(struct drm_device *dev)
-{
-
-	REG_WRITE(DPIO_CFG, 0);
-	REG_READ(DPIO_CFG);
-	REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N);
-}
-
-/* Unlike most Intel display engines, on Cedarview the DPLL registers
- * are behind this sideband bus.  They must be programmed while the
- * DPLL reference clock is on in the DPLL control register, but before
- * the DPLL is enabled in the DPLL control register.
- */
-static int
-cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
-			       struct cdv_intel_clock_t *clock)
-{
-	struct psb_intel_crtc *psb_crtc =
-				to_psb_intel_crtc(crtc);
-	int pipe = psb_crtc->pipe;
-	u32 m, n_vco, p;
-	int ret = 0;
-	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-	u32 ref_value;
-
-	cdv_sb_reset(dev);
-
-	if ((REG_READ(dpll_reg) & DPLL_SYNCLOCK_ENABLE) == 0) {
-		DRM_ERROR("Attempting to set DPLL with refclk disabled\n");
-		return -EBUSY;
-	}
-
-	/* Follow the BIOS and write the REF/SFR Register. Hardcoded value */
-	ref_value = 0x68A701;
-
-	cdv_sb_write(dev, SB_REF_SFR(pipe), ref_value);
-
-	/* We don't know what the other fields of these regs are, so
-	 * leave them in place.
-	 */
-	ret = cdv_sb_read(dev, SB_M(pipe), &m);
-	if (ret)
-		return ret;
-	m &= ~SB_M_DIVIDER_MASK;
-	m |= ((clock->m2) << SB_M_DIVIDER_SHIFT);
-	ret = cdv_sb_write(dev, SB_M(pipe), m);
-	if (ret)
-		return ret;
-
-	ret = cdv_sb_read(dev, SB_N_VCO(pipe), &n_vco);
-	if (ret)
-		return ret;
-
-	/* Follow the BIOS to program the N_DIVIDER REG */
-	n_vco &= 0xFFFF;
-	n_vco |= 0x107;
-	n_vco &= ~(SB_N_VCO_SEL_MASK |
-		   SB_N_DIVIDER_MASK |
-		   SB_N_CB_TUNE_MASK);
-
-	n_vco |= ((clock->n) << SB_N_DIVIDER_SHIFT);
-
-	if (clock->vco < 2250000) {
-		n_vco |= (2 << SB_N_CB_TUNE_SHIFT);
-		n_vco |= (0 << SB_N_VCO_SEL_SHIFT);
-	} else if (clock->vco < 2750000) {
-		n_vco |= (1 << SB_N_CB_TUNE_SHIFT);
-		n_vco |= (1 << SB_N_VCO_SEL_SHIFT);
-	} else if (clock->vco < 3300000) {
-		n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
-		n_vco |= (2 << SB_N_VCO_SEL_SHIFT);
-	} else {
-		n_vco |= (0 << SB_N_CB_TUNE_SHIFT);
-		n_vco |= (3 << SB_N_VCO_SEL_SHIFT);
-	}
-
-	ret = cdv_sb_write(dev, SB_N_VCO(pipe), n_vco);
-	if (ret)
-		return ret;
-
-	ret = cdv_sb_read(dev, SB_P(pipe), &p);
-	if (ret)
-		return ret;
-	p &= ~(SB_P2_DIVIDER_MASK | SB_P1_DIVIDER_MASK);
-	p |= SET_FIELD(clock->p1, SB_P1_DIVIDER);
-	switch (clock->p2) {
-	case 5:
-		p |= SET_FIELD(SB_P2_5, SB_P2_DIVIDER);
-		break;
-	case 10:
-		p |= SET_FIELD(SB_P2_10, SB_P2_DIVIDER);
-		break;
-	case 14:
-		p |= SET_FIELD(SB_P2_14, SB_P2_DIVIDER);
-		break;
-	case 7:
-		p |= SET_FIELD(SB_P2_7, SB_P2_DIVIDER);
-		break;
-	default:
-		DRM_ERROR("Bad P2 clock: %d\n", clock->p2);
-		return -EINVAL;
-	}
-	ret = cdv_sb_write(dev, SB_P(pipe), p);
-	if (ret)
-		return ret;
-
-	/* always Program the Lane Register for the Pipe A*/
-	if (pipe == 0) {
-		/* Program the Lane0/1 for HDMI B */
-		u32 lane_reg, lane_value;
-
-		lane_reg = PSB_LANE0;
-		cdv_sb_read(dev, lane_reg, &lane_value);
-		lane_value &= ~(LANE_PLL_MASK);
-		lane_value |= LANE_PLL_ENABLE;
-		cdv_sb_write(dev, lane_reg, lane_value);
-
-		lane_reg = PSB_LANE1;
-		cdv_sb_read(dev, lane_reg, &lane_value);
-		lane_value &= ~(LANE_PLL_MASK);
-		lane_value |= LANE_PLL_ENABLE;
-		cdv_sb_write(dev, lane_reg, lane_value);
-
-		/* Program the Lane2/3 for HDMI C */
-		lane_reg = PSB_LANE2;
-		cdv_sb_read(dev, lane_reg, &lane_value);
-		lane_value &= ~(LANE_PLL_MASK);
-		lane_value |= LANE_PLL_ENABLE;
-		cdv_sb_write(dev, lane_reg, lane_value);
-
-		lane_reg = PSB_LANE3;
-		cdv_sb_read(dev, lane_reg, &lane_value);
-		lane_value &= ~(LANE_PLL_MASK);
-		lane_value |= LANE_PLL_ENABLE;
-		cdv_sb_write(dev, lane_reg, lane_value);
-	}
-
-	return 0;
-}
-
-/*
- * Returns whether any output on the specified pipe is of the specified type
- */
-bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_mode_config *mode_config = &dev->mode_config;
-	struct drm_connector *l_entry;
-
-	list_for_each_entry(l_entry, &mode_config->connector_list, head) {
-		if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
-			struct psb_intel_output *psb_intel_output =
-			    to_psb_intel_output(l_entry);
-			if (psb_intel_output->type == type)
-				return true;
-		}
-	}
-	return false;
-}
-
-static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
-							int refclk)
-{
-	const struct cdv_intel_limit_t *limit;
-	if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-		/*
-		 * Now only single-channel LVDS is supported on CDV. If it is
-		 * incorrect, please add the dual-channel LVDS.
-		 */
-		if (refclk == 96000)
-			limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
-		else
-			limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
-	} else {
-		if (refclk == 27000)
-			limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27];
-		else
-			limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_96];
-	}
-	return limit;
-}
-
-/* m1 is reserved as 0 in CDV, n is a ring counter */
-static void cdv_intel_clock(struct drm_device *dev,
-			int refclk, struct cdv_intel_clock_t *clock)
-{
-	clock->m = clock->m2 + 2;
-	clock->p = clock->p1 * clock->p2;
-	clock->vco = (refclk * clock->m) / clock->n;
-	clock->dot = clock->vco / clock->p;
-}
-
-
-#define INTELPllInvalid(s)   { /* ErrorF (s) */; return false; }
-static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc,
-				const struct cdv_intel_limit_t *limit,
-			       struct cdv_intel_clock_t *clock)
-{
-	if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
-		INTELPllInvalid("p1 out of range\n");
-	if (clock->p < limit->p.min || limit->p.max < clock->p)
-		INTELPllInvalid("p out of range\n");
-	/* unnecessary to check the range of m(m1/M2)/n again */
-	if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
-		INTELPllInvalid("vco out of range\n");
-	/* XXX: We may need to be checking "Dot clock"
-	 * depending on the multiplier, connector, etc.,
-	 * rather than just a single range.
-	 */
-	if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
-		INTELPllInvalid("dot out of range\n");
-
-	return true;
-}
-
-static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target,
-				int refclk,
-				struct cdv_intel_clock_t *best_clock)
-{
-	struct drm_device *dev = crtc->dev;
-	struct cdv_intel_clock_t clock;
-	const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk);
-	int err = target;
-
-
-	if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
-	    (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
-		/*
-		 * For LVDS, if the panel is on, just rely on its current
-		 * settings for dual-channel.  We haven't figured out how to
-		 * reliably set up different single/dual channel state, if we
-		 * even can.
-		 */
-		if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
-			clock.p2 = limit->p2.p2_fast;
-		else
-			clock.p2 = limit->p2.p2_slow;
-	} else {
-		if (target < limit->p2.dot_limit)
-			clock.p2 = limit->p2.p2_slow;
-		else
-			clock.p2 = limit->p2.p2_fast;
-	}
-
-	memset(best_clock, 0, sizeof(*best_clock));
-	clock.m1 = 0;
-	/* m1 is reserved as 0 in CDV, n is a ring counter.
-	   So skip the m1 loop */
-	for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
-		for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max;
-					     clock.m2++) {
-			for (clock.p1 = limit->p1.min;
-					clock.p1 <= limit->p1.max;
-					clock.p1++) {
-				int this_err;
-
-				cdv_intel_clock(dev, refclk, &clock);
-
-				if (!cdv_intel_PLL_is_valid(crtc,
-								limit, &clock))
-						continue;
-
-				this_err = abs(clock.dot - target);
-				if (this_err < err) {
-					*best_clock = clock;
-					err = this_err;
-				}
-			}
-		}
-	}
-
-	return err != target;
-}
-
-int cdv_intel_pipe_set_base(struct drm_crtc *crtc,
-			    int x, int y, struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-	int pipe = psb_intel_crtc->pipe;
-	unsigned long start, offset;
-	int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
-	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
-	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	u32 dspcntr;
-	int ret = 0;
-
-	if (!gma_power_begin(dev, true))
-		return 0;
-
-	/* no fb bound */
-	if (!crtc->fb) {
-		dev_err(dev->dev, "No FB bound\n");
-		goto psb_intel_pipe_cleaner;
-	}
-
-
-	/* We are displaying this buffer, make sure it is actually loaded
-	   into the GTT */
-	ret = psb_gtt_pin(psbfb->gtt);
-	if (ret < 0)
-		goto psb_intel_pipe_set_base_exit;
-	start = psbfb->gtt->offset;
-	offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
-	REG_WRITE(dspstride, crtc->fb->pitches[0]);
-
-	dspcntr = REG_READ(dspcntr_reg);
-	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
-	switch (crtc->fb->bits_per_pixel) {
-	case 8:
-		dspcntr |= DISPPLANE_8BPP;
-		break;
-	case 16:
-		if (crtc->fb->depth == 15)
-			dspcntr |= DISPPLANE_15_16BPP;
-		else
-			dspcntr |= DISPPLANE_16BPP;
-		break;
-	case 24:
-	case 32:
-		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-		break;
-	default:
-		dev_err(dev->dev, "Unknown color depth\n");
-		ret = -EINVAL;
-		goto psb_intel_pipe_set_base_exit;
-	}
-	REG_WRITE(dspcntr_reg, dspcntr);
-
-	dev_dbg(dev->dev,
-		"Writing base %08lX %08lX %d %d\n", start, offset, x, y);
-
-	REG_WRITE(dspbase, offset);
-	REG_READ(dspbase);
-	REG_WRITE(dspsurf, start);
-	REG_READ(dspsurf);
-
-psb_intel_pipe_cleaner:
-	/* If there was a previous display we can now unpin it */
-	if (old_fb)
-		psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
-
-psb_intel_pipe_set_base_exit:
-	gma_power_end(dev);
-	return ret;
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
-	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-	u32 temp;
-	bool enabled;
-
-	/* XXX: When our outputs are all unaware of DPMS modes other than off
-	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-	 */
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-		/* Enable the DPLL */
-		temp = REG_READ(dpll_reg);
-		if ((temp & DPLL_VCO_ENABLE) == 0) {
-			REG_WRITE(dpll_reg, temp);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-		}
-
-		/* Jim Bish - switch plan and pipe per scott */
-		/* Enable the plane */
-		temp = REG_READ(dspcntr_reg);
-		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-			REG_WRITE(dspcntr_reg,
-				  temp | DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-		}
-
-		udelay(150);
-
-		/* Enable the pipe */
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_ENABLE) == 0)
-			REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
-
-		psb_intel_crtc_load_lut(crtc);
-
-		/* Give the overlay scaler a chance to enable
-		 * if it's on this pipe */
-		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
-		break;
-	case DRM_MODE_DPMS_OFF:
-		/* Give the overlay scaler a chance to disable
-		 * if it's on this pipe */
-		/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-
-		/* Disable the VGA plane that we never use */
-		REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-		/* Jim Bish - changed pipe/plane here as well. */
-
-		/* Wait for vblank for the disable to take effect */
-		cdv_intel_wait_for_vblank(dev);
-
-		/* Next, disable display pipes */
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_ENABLE) != 0) {
-			REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
-			REG_READ(pipeconf_reg);
-		}
-
-		/* Wait for vblank for the disable to take effect. */
-		cdv_intel_wait_for_vblank(dev);
-
-		udelay(150);
-
-		/* Disable display plane */
-		temp = REG_READ(dspcntr_reg);
-		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-			REG_WRITE(dspcntr_reg,
-				  temp & ~DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-			REG_READ(dspbase_reg);
-		}
-
-		temp = REG_READ(dpll_reg);
-		if ((temp & DPLL_VCO_ENABLE) != 0) {
-			REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-		}
-
-		/* Wait for the clocks to turn off. */
-		udelay(150);
-		break;
-	}
-	enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-	/*Set FIFO Watermarks*/
-	REG_WRITE(DSPARB, 0x3F3E);
-}
-
-static void cdv_intel_crtc_prepare(struct drm_crtc *crtc)
-{
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void cdv_intel_crtc_commit(struct drm_crtc *crtc)
-{
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-void cdv_intel_encoder_prepare(struct drm_encoder *encoder)
-{
-	struct drm_encoder_helper_funcs *encoder_funcs =
-	    encoder->helper_private;
-	/* lvds has its own version of prepare see cdv_intel_lvds_prepare */
-	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-void cdv_intel_encoder_commit(struct drm_encoder *encoder)
-{
-	struct drm_encoder_helper_funcs *encoder_funcs =
-	    encoder->helper_private;
-	/* lvds has its own version of commit see cdv_intel_lvds_commit */
-	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static bool cdv_intel_crtc_mode_fixup(struct drm_crtc *crtc,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int cdv_intel_panel_fitter_pipe(struct drm_device *dev)
-{
-	u32 pfit_control;
-
-	pfit_control = REG_READ(PFIT_CONTROL);
-
-	/* See if the panel fitter is in use */
-	if ((pfit_control & PFIT_ENABLE) == 0)
-		return -1;
-	return (pfit_control >> 29) & 0x3;
-}
-
-static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode,
-			       int x, int y,
-			       struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-	int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-	int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
-	int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
-	int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
-	int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
-	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
-	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-	int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
-	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
-	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-	int refclk;
-	struct cdv_intel_clock_t clock;
-	u32 dpll = 0, dspcntr, pipeconf;
-	bool ok, is_sdvo = false, is_dvo = false;
-	bool is_crt = false, is_lvds = false, is_tv = false;
-	bool is_hdmi = false;
-	struct drm_mode_config *mode_config = &dev->mode_config;
-	struct drm_connector *connector;
-
-	list_for_each_entry(connector, &mode_config->connector_list, head) {
-		struct psb_intel_output *psb_intel_output =
-		    to_psb_intel_output(connector);
-
-		if (!connector->encoder
-		    || connector->encoder->crtc != crtc)
-			continue;
-
-		switch (psb_intel_output->type) {
-		case INTEL_OUTPUT_LVDS:
-			is_lvds = true;
-			break;
-		case INTEL_OUTPUT_SDVO:
-			is_sdvo = true;
-			break;
-		case INTEL_OUTPUT_DVO:
-			is_dvo = true;
-			break;
-		case INTEL_OUTPUT_TVOUT:
-			is_tv = true;
-			break;
-		case INTEL_OUTPUT_ANALOG:
-			is_crt = true;
-			break;
-		case INTEL_OUTPUT_HDMI:
-			is_hdmi = true;
-			break;
-		}
-	}
-
-	refclk = 96000;
-
-	/* Hack selection about ref clk for CRT */
-	/* Select 27MHz as the reference clk for HDMI */
-	if (is_crt || is_hdmi)
-		refclk = 27000;
-
-	drm_mode_debug_printmodeline(adjusted_mode);
-
-	ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
-				 &clock);
-	if (!ok) {
-		dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
-		return 0;
-	}
-
-	dpll = DPLL_VGA_MODE_DIS;
-	if (is_tv) {
-		/* XXX: just matching BIOS for now */
-/*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
-		dpll |= 3;
-	}
-		dpll |= PLL_REF_INPUT_DREFCLK;
-
-	dpll |= DPLL_SYNCLOCK_ENABLE;
-	dpll |= DPLL_VGA_MODE_DIS;
-	if (is_lvds)
-		dpll |= DPLLB_MODE_LVDS;
-	else
-		dpll |= DPLLB_MODE_DAC_SERIAL;
-	/* dpll |= (2 << 11); */
-
-	/* setup pipeconf */
-	pipeconf = REG_READ(pipeconf_reg);
-
-	/* Set up the display plane register */
-	dspcntr = DISPPLANE_GAMMA_ENABLE;
-
-	if (pipe == 0)
-		dspcntr |= DISPPLANE_SEL_PIPE_A;
-	else
-		dspcntr |= DISPPLANE_SEL_PIPE_B;
-
-	dspcntr |= DISPLAY_PLANE_ENABLE;
-	pipeconf |= PIPEACONF_ENABLE;
-
-	REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE);
-	REG_READ(dpll_reg);
-
-	cdv_dpll_set_clock_cdv(dev, crtc, &clock);
-
-	udelay(150);
-
-
-	/* The LVDS pin pair needs to be on before the DPLLs are enabled.
-	 * This is an exception to the general rule that mode_set doesn't turn
-	 * things on.
-	 */
-	if (is_lvds) {
-		u32 lvds = REG_READ(LVDS);
-
-		lvds |=
-		    LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
-		    LVDS_PIPEB_SELECT;
-		/* Set the B0-B3 data pairs corresponding to
-		 * whether we're going to
-		 * set the DPLLs for dual-channel mode or not.
-		 */
-		if (clock.p2 == 7)
-			lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
-		else
-			lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
-
-		/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
-		 * appropriately here, but we need to look more
-		 * thoroughly into how panels behave in the two modes.
-		 */
-
-		REG_WRITE(LVDS, lvds);
-		REG_READ(LVDS);
-	}
-
-	dpll |= DPLL_VCO_ENABLE;
-
-	/* Disable the panel fitter if it was on our pipe */
-	if (cdv_intel_panel_fitter_pipe(dev) == pipe)
-		REG_WRITE(PFIT_CONTROL, 0);
-
-	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
-	drm_mode_debug_printmodeline(mode);
-
-	REG_WRITE(dpll_reg,
-		(REG_READ(dpll_reg) & ~DPLL_LOCK) | DPLL_VCO_ENABLE);
-	REG_READ(dpll_reg);
-	/* Wait for the clocks to stabilize. */
-	udelay(150); /* 42 usec w/o calibration, 110 with.  rounded up. */
-
-	if (!(REG_READ(dpll_reg) & DPLL_LOCK)) {
-		dev_err(dev->dev, "Failed to get DPLL lock\n");
-		return -EBUSY;
-	}
-
-	{
-		int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
-		REG_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
-	}
-
-	REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
-		  ((adjusted_mode->crtc_htotal - 1) << 16));
-	REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
-		  ((adjusted_mode->crtc_hblank_end - 1) << 16));
-	REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
-		  ((adjusted_mode->crtc_hsync_end - 1) << 16));
-	REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
-		  ((adjusted_mode->crtc_vtotal - 1) << 16));
-	REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
-		  ((adjusted_mode->crtc_vblank_end - 1) << 16));
-	REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
-		  ((adjusted_mode->crtc_vsync_end - 1) << 16));
-	/* pipesrc and dspsize control the size that is scaled from,
-	 * which should always be the user's requested size.
-	 */
-	REG_WRITE(dspsize_reg,
-		  ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
-	REG_WRITE(dsppos_reg, 0);
-	REG_WRITE(pipesrc_reg,
-		  ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
-	REG_WRITE(pipeconf_reg, pipeconf);
-	REG_READ(pipeconf_reg);
-
-	cdv_intel_wait_for_vblank(dev);
-
-	REG_WRITE(dspcntr_reg, dspcntr);
-
-	/* Flush the plane changes */
-	{
-		struct drm_crtc_helper_funcs *crtc_funcs =
-		    crtc->helper_private;
-		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-	}
-
-	cdv_intel_wait_for_vblank(dev);
-
-	return 0;
-}
-
-/** Loads the palette/gamma unit for the CRTC with the prepared values */
-void cdv_intel_crtc_load_lut(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private *dev_priv =
-				(struct drm_psb_private *)dev->dev_private;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int palreg = PALETTE_A;
-	int i;
-
-	/* The clocks have to be on to load the palette. */
-	if (!crtc->enabled)
-		return;
-
-	switch (psb_intel_crtc->pipe) {
-	case 0:
-		break;
-	case 1:
-		palreg = PALETTE_B;
-		break;
-	case 2:
-		palreg = PALETTE_C;
-		break;
-	default:
-		dev_err(dev->dev, "Illegal Pipe Number.\n");
-		return;
-	}
-
-	if (gma_power_begin(dev, false)) {
-		for (i = 0; i < 256; i++) {
-			REG_WRITE(palreg + 4 * i,
-				  ((psb_intel_crtc->lut_r[i] +
-				  psb_intel_crtc->lut_adj[i]) << 16) |
-				  ((psb_intel_crtc->lut_g[i] +
-				  psb_intel_crtc->lut_adj[i]) << 8) |
-				  (psb_intel_crtc->lut_b[i] +
-				  psb_intel_crtc->lut_adj[i]));
-		}
-		gma_power_end(dev);
-	} else {
-		for (i = 0; i < 256; i++) {
-			dev_priv->save_palette_a[i] =
-				  ((psb_intel_crtc->lut_r[i] +
-				  psb_intel_crtc->lut_adj[i]) << 16) |
-				  ((psb_intel_crtc->lut_g[i] +
-				  psb_intel_crtc->lut_adj[i]) << 8) |
-				  (psb_intel_crtc->lut_b[i] +
-				  psb_intel_crtc->lut_adj[i]);
-		}
-
-	}
-}
-
-/**
- * Save HW states of giving crtc
- */
-static void cdv_intel_crtc_save(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	/* struct drm_psb_private *dev_priv =
-			(struct drm_psb_private *)dev->dev_private; */
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
-	int pipeA = (psb_intel_crtc->pipe == 0);
-	uint32_t paletteReg;
-	int i;
-
-	if (!crtc_state) {
-		dev_dbg(dev->dev, "No CRTC state found\n");
-		return;
-	}
-
-	crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
-	crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
-	crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
-	crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
-	crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
-	crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
-	crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
-	crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
-	crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
-	crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
-	crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
-	crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
-	crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
-
-	/*NOTE: DSPSIZE DSPPOS only for psb*/
-	crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
-	crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
-
-	crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
-
-	DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
-			crtc_state->saveDSPCNTR,
-			crtc_state->savePIPECONF,
-			crtc_state->savePIPESRC,
-			crtc_state->saveFP0,
-			crtc_state->saveFP1,
-			crtc_state->saveDPLL,
-			crtc_state->saveHTOTAL,
-			crtc_state->saveHBLANK,
-			crtc_state->saveHSYNC,
-			crtc_state->saveVTOTAL,
-			crtc_state->saveVBLANK,
-			crtc_state->saveVSYNC,
-			crtc_state->saveDSPSTRIDE,
-			crtc_state->saveDSPSIZE,
-			crtc_state->saveDSPPOS,
-			crtc_state->saveDSPBASE
-		);
-
-	paletteReg = pipeA ? PALETTE_A : PALETTE_B;
-	for (i = 0; i < 256; ++i)
-		crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
-}
-
-/**
- * Restore HW states of giving crtc
- */
-static void cdv_intel_crtc_restore(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	/* struct drm_psb_private * dev_priv =
-				(struct drm_psb_private *)dev->dev_private; */
-	struct psb_intel_crtc *psb_intel_crtc =  to_psb_intel_crtc(crtc);
-	struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
-	/* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
-	int pipeA = (psb_intel_crtc->pipe == 0);
-	uint32_t paletteReg;
-	int i;
-
-	if (!crtc_state) {
-		dev_dbg(dev->dev, "No crtc state\n");
-		return;
-	}
-
-	DRM_DEBUG(
-		"current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
-		REG_READ(pipeA ? DSPACNTR : DSPBCNTR),
-		REG_READ(pipeA ? PIPEACONF : PIPEBCONF),
-		REG_READ(pipeA ? PIPEASRC : PIPEBSRC),
-		REG_READ(pipeA ? FPA0 : FPB0),
-		REG_READ(pipeA ? FPA1 : FPB1),
-		REG_READ(pipeA ? DPLL_A : DPLL_B),
-		REG_READ(pipeA ? HTOTAL_A : HTOTAL_B),
-		REG_READ(pipeA ? HBLANK_A : HBLANK_B),
-		REG_READ(pipeA ? HSYNC_A : HSYNC_B),
-		REG_READ(pipeA ? VTOTAL_A : VTOTAL_B),
-		REG_READ(pipeA ? VBLANK_A : VBLANK_B),
-		REG_READ(pipeA ? VSYNC_A : VSYNC_B),
-		REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE),
-		REG_READ(pipeA ? DSPASIZE : DSPBSIZE),
-		REG_READ(pipeA ? DSPAPOS : DSPBPOS),
-		REG_READ(pipeA ? DSPABASE : DSPBBASE)
-		);
-
-	DRM_DEBUG(
-		"saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
-		crtc_state->saveDSPCNTR,
-		crtc_state->savePIPECONF,
-		crtc_state->savePIPESRC,
-		crtc_state->saveFP0,
-		crtc_state->saveFP1,
-		crtc_state->saveDPLL,
-		crtc_state->saveHTOTAL,
-		crtc_state->saveHBLANK,
-		crtc_state->saveHSYNC,
-		crtc_state->saveVTOTAL,
-		crtc_state->saveVBLANK,
-		crtc_state->saveVSYNC,
-		crtc_state->saveDSPSTRIDE,
-		crtc_state->saveDSPSIZE,
-		crtc_state->saveDSPPOS,
-		crtc_state->saveDSPBASE
-		);
-
-
-	if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
-		REG_WRITE(pipeA ? DPLL_A : DPLL_B,
-			crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
-		REG_READ(pipeA ? DPLL_A : DPLL_B);
-		DRM_DEBUG("write dpll: %x\n",
-				REG_READ(pipeA ? DPLL_A : DPLL_B));
-		udelay(150);
-	}
-
-	REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
-	REG_READ(pipeA ? FPA0 : FPB0);
-
-	REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
-	REG_READ(pipeA ? FPA1 : FPB1);
-
-	REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
-	REG_READ(pipeA ? DPLL_A : DPLL_B);
-	udelay(150);
-
-	REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
-	REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
-	REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
-	REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
-	REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
-	REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
-	REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
-
-	REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
-	REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
-
-	REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
-	REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-	REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
-
-	cdv_intel_wait_for_vblank(dev);
-
-	REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
-	REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-
-	cdv_intel_wait_for_vblank(dev);
-
-	paletteReg = pipeA ? PALETTE_A : PALETTE_B;
-	for (i = 0; i < 256; ++i)
-		REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
-}
-
-static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
-				 struct drm_file *file_priv,
-				 uint32_t handle,
-				 uint32_t width, uint32_t height)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
-	uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
-	uint32_t temp;
-	size_t addr = 0;
-	struct gtt_range *gt;
-	struct drm_gem_object *obj;
-	int ret;
-
-	/* if we want to turn of the cursor ignore width and height */
-	if (!handle) {
-		/* turn off the cursor */
-		temp = CURSOR_MODE_DISABLE;
-
-		if (gma_power_begin(dev, false)) {
-			REG_WRITE(control, temp);
-			REG_WRITE(base, 0);
-			gma_power_end(dev);
-		}
-
-		/* unpin the old GEM object */
-		if (psb_intel_crtc->cursor_obj) {
-			gt = container_of(psb_intel_crtc->cursor_obj,
-							struct gtt_range, gem);
-			psb_gtt_unpin(gt);
-			drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-			psb_intel_crtc->cursor_obj = NULL;
-		}
-
-		return 0;
-	}
-
-	/* Currently we only support 64x64 cursors */
-	if (width != 64 || height != 64) {
-		dev_dbg(dev->dev, "we currently only support 64x64 cursors\n");
-		return -EINVAL;
-	}
-
-	obj = drm_gem_object_lookup(dev, file_priv, handle);
-	if (!obj)
-		return -ENOENT;
-
-	if (obj->size < width * height * 4) {
-		dev_dbg(dev->dev, "buffer is to small\n");
-		return -ENOMEM;
-	}
-
-	gt = container_of(obj, struct gtt_range, gem);
-
-	/* Pin the memory into the GTT */
-	ret = psb_gtt_pin(gt);
-	if (ret) {
-		dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-		return ret;
-	}
-
-	addr = gt->offset;	/* Or resource.start ??? */
-
-	psb_intel_crtc->cursor_addr = addr;
-
-	temp = 0;
-	/* set the pipe for the cursor */
-	temp |= (pipe << 28);
-	temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-
-	if (gma_power_begin(dev, false)) {
-		REG_WRITE(control, temp);
-		REG_WRITE(base, addr);
-		gma_power_end(dev);
-	}
-
-	/* unpin the old GEM object */
-	if (psb_intel_crtc->cursor_obj) {
-		gt = container_of(psb_intel_crtc->cursor_obj,
-							struct gtt_range, gem);
-		psb_gtt_unpin(gt);
-		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-		psb_intel_crtc->cursor_obj = obj;
-	}
-	return 0;
-}
-
-static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	uint32_t temp = 0;
-	uint32_t adder;
-
-
-	if (x < 0) {
-		temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
-		x = -x;
-	}
-	if (y < 0) {
-		temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
-		y = -y;
-	}
-
-	temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
-	temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
-	adder = psb_intel_crtc->cursor_addr;
-
-	if (gma_power_begin(dev, false)) {
-		REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
-		REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
-		gma_power_end(dev);
-	}
-	return 0;
-}
-
-static void cdv_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
-			 u16 *green, u16 *blue, uint32_t start, uint32_t size)
-{
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int i;
-	int end = (start + size > 256) ? 256 : start + size;
-
-	for (i = start; i < end; i++) {
-		psb_intel_crtc->lut_r[i] = red[i] >> 8;
-		psb_intel_crtc->lut_g[i] = green[i] >> 8;
-		psb_intel_crtc->lut_b[i] = blue[i] >> 8;
-	}
-
-	cdv_intel_crtc_load_lut(crtc);
-}
-
-static int cdv_crtc_set_config(struct drm_mode_set *set)
-{
-	int ret = 0;
-	struct drm_device *dev = set->crtc->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (!dev_priv->rpm_enabled)
-		return drm_crtc_helper_set_config(set);
-
-	pm_runtime_forbid(&dev->pdev->dev);
-
-	ret = drm_crtc_helper_set_config(set);
-
-	pm_runtime_allow(&dev->pdev->dev);
-
-	return ret;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-
-/* FIXME: why are we using this, should it be cdv_ in this tree ? */
-
-static void i8xx_clock(int refclk, struct cdv_intel_clock_t *clock)
-{
-	clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
-	clock->p = clock->p1 * clock->p2;
-	clock->vco = refclk * clock->m / (clock->n + 2);
-	clock->dot = clock->vco / clock->p;
-}
-
-/* Returns the clock of the currently programmed mode of the given pipe. */
-static int cdv_intel_crtc_clock_get(struct drm_device *dev,
-				struct drm_crtc *crtc)
-{
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	u32 dpll;
-	u32 fp;
-	struct cdv_intel_clock_t clock;
-	bool is_lvds;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (gma_power_begin(dev, false)) {
-		dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
-		if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-			fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
-		else
-			fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
-		is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
-		gma_power_end(dev);
-	} else {
-		dpll = (pipe == 0) ?
-			dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
-
-		if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-			fp = (pipe == 0) ?
-				dev_priv->saveFPA0 :
-				dev_priv->saveFPB0;
-		else
-			fp = (pipe == 0) ?
-				dev_priv->saveFPA1 :
-				dev_priv->saveFPB1;
-
-		is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
-	}
-
-	clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
-	clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
-	clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
-
-	if (is_lvds) {
-		clock.p1 =
-		    ffs((dpll &
-			 DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
-			DPLL_FPA01_P1_POST_DIV_SHIFT);
-		if (clock.p1 == 0) {
-			clock.p1 = 4;
-			dev_err(dev->dev, "PLL %d\n", dpll);
-		}
-		clock.p2 = 14;
-
-		if ((dpll & PLL_REF_INPUT_MASK) ==
-		    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
-			/* XXX: might not be 66MHz */
-			i8xx_clock(66000, &clock);
-		} else
-			i8xx_clock(48000, &clock);
-	} else {
-		if (dpll & PLL_P1_DIVIDE_BY_TWO)
-			clock.p1 = 2;
-		else {
-			clock.p1 =
-			    ((dpll &
-			      DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
-			     DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
-		}
-		if (dpll & PLL_P2_DIVIDE_BY_4)
-			clock.p2 = 4;
-		else
-			clock.p2 = 2;
-
-		i8xx_clock(48000, &clock);
-	}
-
-	/* XXX: It would be nice to validate the clocks, but we can't reuse
-	 * i830PllIsValid() because it relies on the xf86_config connector
-	 * configuration being accurate, which it isn't necessarily.
-	 */
-
-	return clock.dot;
-}
-
-/** Returns the currently programmed mode of the given pipe. */
-struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev,
-					     struct drm_crtc *crtc)
-{
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	struct drm_display_mode *mode;
-	int htot;
-	int hsync;
-	int vtot;
-	int vsync;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (gma_power_begin(dev, false)) {
-		htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
-		hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
-		vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
-		vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
-		gma_power_end(dev);
-	} else {
-		htot = (pipe == 0) ?
-			dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
-		hsync = (pipe == 0) ?
-			dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
-		vtot = (pipe == 0) ?
-			dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
-		vsync = (pipe == 0) ?
-			dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
-	}
-
-	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-	if (!mode)
-		return NULL;
-
-	mode->clock = cdv_intel_crtc_clock_get(dev, crtc);
-	mode->hdisplay = (htot & 0xffff) + 1;
-	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
-	mode->hsync_start = (hsync & 0xffff) + 1;
-	mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
-	mode->vdisplay = (vtot & 0xffff) + 1;
-	mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
-	mode->vsync_start = (vsync & 0xffff) + 1;
-	mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
-
-	drm_mode_set_name(mode);
-	drm_mode_set_crtcinfo(mode, 0);
-
-	return mode;
-}
-
-static void cdv_intel_crtc_destroy(struct drm_crtc *crtc)
-{
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-
-	kfree(psb_intel_crtc->crtc_state);
-	drm_crtc_cleanup(crtc);
-	kfree(psb_intel_crtc);
-}
-
-const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
-	.dpms = cdv_intel_crtc_dpms,
-	.mode_fixup = cdv_intel_crtc_mode_fixup,
-	.mode_set = cdv_intel_crtc_mode_set,
-	.mode_set_base = cdv_intel_pipe_set_base,
-	.prepare = cdv_intel_crtc_prepare,
-	.commit = cdv_intel_crtc_commit,
-};
-
-const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
-	.save = cdv_intel_crtc_save,
-	.restore = cdv_intel_crtc_restore,
-	.cursor_set = cdv_intel_crtc_cursor_set,
-	.cursor_move = cdv_intel_crtc_cursor_move,
-	.gamma_set = cdv_intel_crtc_gamma_set,
-	.set_config = cdv_crtc_set_config,
-	.destroy = cdv_intel_crtc_destroy,
-};
-
-/*
- * Set the default value of cursor control and base register
- * to zero. This is a workaround for h/w defect on oaktrail
- */
-void cdv_intel_cursor_init(struct drm_device *dev, int pipe)
-{
-	uint32_t control;
-	uint32_t base;
-
-	switch (pipe) {
-	case 0:
-		control = CURACNTR;
-		base = CURABASE;
-		break;
-	case 1:
-		control = CURBCNTR;
-		base = CURBBASE;
-		break;
-	case 2:
-		control = CURCCNTR;
-		base = CURCBASE;
-		break;
-	default:
-		return;
-	}
-
-	REG_WRITE(control, 0);
-	REG_WRITE(base, 0);
-}
-
diff --git a/drivers/staging/gma500/cdv_intel_hdmi.c b/drivers/staging/gma500/cdv_intel_hdmi.c
deleted file mode 100644
index cbca2b0..0000000
--- a/drivers/staging/gma500/cdv_intel_hdmi.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *	jim liu <jim.liu@intel.com>
- *
- * FIXME:
- *	We should probably make this generic and share it with Medfield
- */
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-#include "psb_intel_drv.h"
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include <linux/pm_runtime.h>
-
-/* hdmi control bits */
-#define HDMI_NULL_PACKETS_DURING_VSYNC	(1 << 9)
-#define HDMI_BORDER_ENABLE		(1 << 7)
-#define HDMI_AUDIO_ENABLE		(1 << 6)
-#define HDMI_VSYNC_ACTIVE_HIGH		(1 << 4)
-#define HDMI_HSYNC_ACTIVE_HIGH		(1 << 3)
-/* hdmi-b control bits */
-#define	HDMIB_PIPE_B_SELECT		(1 << 30)
-
-
-struct mid_intel_hdmi_priv {
-	u32 hdmi_reg;
-	u32 save_HDMIB;
-	bool has_hdmi_sink;
-	bool has_hdmi_audio;
-	/* Should set this when detect hotplug */
-	bool hdmi_device_connected;
-	struct mdfld_hdmi_i2c *i2c_bus;
-	struct i2c_adapter *hdmi_i2c_adapter;	/* for control functions */
-	struct drm_device *dev;
-};
-
-static void cdv_hdmi_mode_set(struct drm_encoder *encoder,
-			struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-	u32 hdmib;
-	struct drm_crtc *crtc = encoder->crtc;
-	struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
-
-	hdmib = (2 << 10);
-
-	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
-		hdmib |= HDMI_VSYNC_ACTIVE_HIGH;
-	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
-		hdmib |= HDMI_HSYNC_ACTIVE_HIGH;
-
-	if (intel_crtc->pipe == 1)
-		hdmib |= HDMIB_PIPE_B_SELECT;
-
-	if (hdmi_priv->has_hdmi_audio) {
-		hdmib |= HDMI_AUDIO_ENABLE;
-		hdmib |= HDMI_NULL_PACKETS_DURING_VSYNC;
-	}
-
-	REG_WRITE(hdmi_priv->hdmi_reg, hdmib);
-	REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-	u32 hdmib;
-
-	hdmib = REG_READ(hdmi_priv->hdmi_reg);
-
-	if (mode != DRM_MODE_DPMS_ON)
-		REG_WRITE(hdmi_priv->hdmi_reg, hdmib & ~HDMIB_PORT_EN);
-	else
-		REG_WRITE(hdmi_priv->hdmi_reg, hdmib | HDMIB_PORT_EN);
-	REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static void cdv_hdmi_save(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct psb_intel_output *output = to_psb_intel_output(connector);
-	struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-
-	hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static void cdv_hdmi_restore(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct psb_intel_output *output = to_psb_intel_output(connector);
-	struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
-
-	REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB);
-	REG_READ(hdmi_priv->hdmi_reg);
-}
-
-static enum drm_connector_status cdv_hdmi_detect(
-				struct drm_connector *connector, bool force)
-{
-	struct psb_intel_output *psb_intel_output =
-						to_psb_intel_output(connector);
-	struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_output->dev_priv;
-	struct edid *edid = NULL;
-	enum drm_connector_status status = connector_status_disconnected;
-
-	edid = drm_get_edid(&psb_intel_output->base,
-			 psb_intel_output->hdmi_i2c_adapter);
-
-	hdmi_priv->has_hdmi_sink = false;
-	hdmi_priv->has_hdmi_audio = false;
-	if (edid) {
-		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
-			status = connector_status_connected;
-			hdmi_priv->has_hdmi_sink =
-						drm_detect_hdmi_monitor(edid);
-			hdmi_priv->has_hdmi_audio =
-						drm_detect_monitor_audio(edid);
-		}
-
-		psb_intel_output->base.display_info.raw_edid = NULL;
-		kfree(edid);
-	}
-	return status;
-}
-
-static int cdv_hdmi_set_property(struct drm_connector *connector,
-				       struct drm_property *property,
-				       uint64_t value)
-{
-	struct drm_encoder *encoder = connector->encoder;
-
-	if (!strcmp(property->name, "scaling mode") && encoder) {
-		struct psb_intel_crtc *crtc = to_psb_intel_crtc(encoder->crtc);
-		bool centre;
-		uint64_t curValue;
-
-		if (!crtc)
-			return -1;
-
-		switch (value) {
-		case DRM_MODE_SCALE_FULLSCREEN:
-			break;
-		case DRM_MODE_SCALE_NO_SCALE:
-			break;
-		case DRM_MODE_SCALE_ASPECT:
-			break;
-		default:
-			return -1;
-		}
-
-		if (drm_connector_property_get_value(connector,
-							property, &curValue))
-			return -1;
-
-		if (curValue == value)
-			return 0;
-
-		if (drm_connector_property_set_value(connector,
-							property, value))
-			return -1;
-
-		centre = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
-			(value == DRM_MODE_SCALE_NO_SCALE);
-
-		if (crtc->saved_mode.hdisplay != 0 &&
-		    crtc->saved_mode.vdisplay != 0) {
-			if (centre) {
-				if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode,
-					    encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
-					return -1;
-			} else {
-				struct drm_encoder_helper_funcs *helpers
-						    = encoder->helper_private;
-				helpers->mode_set(encoder, &crtc->saved_mode,
-					     &crtc->saved_adjusted_mode);
-			}
-		}
-	}
-	return 0;
-}
-
-/*
- * Return the list of HDMI DDC modes if available.
- */
-static int cdv_hdmi_get_modes(struct drm_connector *connector)
-{
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-	struct edid *edid = NULL;
-	int ret = 0;
-
-	edid = drm_get_edid(&psb_intel_output->base,
-			 psb_intel_output->hdmi_i2c_adapter);
-	if (edid) {
-		drm_mode_connector_update_edid_property(&psb_intel_output->
-							base, edid);
-		ret = drm_add_edid_modes(&psb_intel_output->base, edid);
-		kfree(edid);
-	}
-	return ret;
-}
-
-static int cdv_hdmi_mode_valid(struct drm_connector *connector,
-				 struct drm_display_mode *mode)
-{
-
-	if (mode->clock > 165000)
-		return MODE_CLOCK_HIGH;
-	if (mode->clock < 20000)
-		return MODE_CLOCK_HIGH;
-
-	/* just in case */
-	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-		return MODE_NO_DBLESCAN;
-
-	/* just in case */
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-		return MODE_NO_INTERLACE;
-
-	/*
-	 * FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it
-	 * will go beyond the stolen memory size allocated to the framebuffer
-	 */
-	if (mode->hdisplay > 1680)
-		return MODE_PANEL;
-	if (mode->vdisplay > 1050)
-		return MODE_PANEL;
-	return MODE_OK;
-}
-
-static void cdv_hdmi_destroy(struct drm_connector *connector)
-{
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-
-	if (psb_intel_output->ddc_bus)
-		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-	drm_sysfs_connector_remove(connector);
-	drm_connector_cleanup(connector);
-	kfree(connector);
-}
-
-static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = {
-	.dpms = cdv_hdmi_dpms,
-	.mode_fixup = cdv_hdmi_mode_fixup,
-	.prepare = psb_intel_encoder_prepare,
-	.mode_set = cdv_hdmi_mode_set,
-	.commit = psb_intel_encoder_commit,
-};
-
-static const struct drm_connector_helper_funcs
-					cdv_hdmi_connector_helper_funcs = {
-	.get_modes = cdv_hdmi_get_modes,
-	.mode_valid = cdv_hdmi_mode_valid,
-	.best_encoder = psb_intel_best_encoder,
-};
-
-static const struct drm_connector_funcs cdv_hdmi_connector_funcs = {
-	.dpms = drm_helper_connector_dpms,
-	.save = cdv_hdmi_save,
-	.restore = cdv_hdmi_restore,
-	.detect = cdv_hdmi_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.set_property = cdv_hdmi_set_property,
-	.destroy = cdv_hdmi_destroy,
-};
-
-void cdv_hdmi_init(struct drm_device *dev,
-			struct psb_intel_mode_device *mode_dev, int reg)
-{
-	struct psb_intel_output *psb_intel_output;
-	struct drm_connector *connector;
-	struct drm_encoder *encoder;
-	struct mid_intel_hdmi_priv *hdmi_priv;
-	int ddc_bus;
-
-	psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
-			       sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL);
-	if (!psb_intel_output)
-		return;
-
-	hdmi_priv = (struct mid_intel_hdmi_priv *)(psb_intel_output + 1);
-	psb_intel_output->mode_dev = mode_dev;
-	connector = &psb_intel_output->base;
-	encoder = &psb_intel_output->enc;
-	drm_connector_init(dev, &psb_intel_output->base,
-			   &cdv_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_DVID);
-
-	drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
-			 DRM_MODE_ENCODER_TMDS);
-
-	drm_mode_connector_attach_encoder(&psb_intel_output->base,
-					  &psb_intel_output->enc);
-	psb_intel_output->type = INTEL_OUTPUT_HDMI;
-	hdmi_priv->hdmi_reg = reg;
-	hdmi_priv->has_hdmi_sink = false;
-	psb_intel_output->dev_priv = hdmi_priv;
-
-	drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs);
-	drm_connector_helper_add(connector,
-				 &cdv_hdmi_connector_helper_funcs);
-	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-	connector->interlace_allowed = false;
-	connector->doublescan_allowed = false;
-
-	drm_connector_attach_property(connector,
-	    dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
-
-	switch (reg) {
-	case SDVOB:
-		ddc_bus = GPIOE;
-		break;
-	case SDVOC:
-		ddc_bus = GPIOD;
-		break;
-	default:
-		DRM_ERROR("unknown reg 0x%x for HDMI\n", reg);
-		goto failed_ddc;
-		break;
-	}
-
-	psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
-				ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC");
-
-	if (!psb_intel_output->ddc_bus) {
-		dev_err(dev->dev, "No ddc adapter available!\n");
-		goto failed_ddc;
-	}
-	psb_intel_output->hdmi_i2c_adapter =
-				&(psb_intel_output->ddc_bus->adapter);
-	hdmi_priv->dev = dev;
-	drm_sysfs_connector_add(connector);
-	return;
-
-failed_ddc:
-	drm_encoder_cleanup(&psb_intel_output->enc);
-	drm_connector_cleanup(&psb_intel_output->base);
-	kfree(psb_intel_output);
-}
diff --git a/drivers/staging/gma500/cdv_intel_lvds.c b/drivers/staging/gma500/cdv_intel_lvds.c
deleted file mode 100644
index 988b2d0..0000000
--- a/drivers/staging/gma500/cdv_intel_lvds.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- *	Dave Airlie <airlied@linux.ie>
- *	Jesse Barnes <jesse.barnes@intel.com>
- */
-
-#include <linux/i2c.h>
-#include <linux/dmi.h>
-#include <drm/drmP.h>
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include <linux/pm_runtime.h>
-#include "cdv_device.h"
-
-/**
- * LVDS I2C backlight control macros
- */
-#define BRIGHTNESS_MAX_LEVEL 100
-#define BRIGHTNESS_MASK 0xFF
-#define BLC_I2C_TYPE	0x01
-#define BLC_PWM_TYPT	0x02
-
-#define BLC_POLARITY_NORMAL 0
-#define BLC_POLARITY_INVERSE 1
-
-#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
-#define PSB_BLC_MIN_PWM_REG_FREQ	(0x2)
-#define PSB_BLC_PWM_PRECISION_FACTOR	(10)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-
-struct cdv_intel_lvds_priv {
-	/**
-	 * Saved LVDO output states
-	 */
-	uint32_t savePP_ON;
-	uint32_t savePP_OFF;
-	uint32_t saveLVDS;
-	uint32_t savePP_CONTROL;
-	uint32_t savePP_CYCLE;
-	uint32_t savePFIT_CONTROL;
-	uint32_t savePFIT_PGM_RATIOS;
-	uint32_t saveBLC_PWM_CTL;
-};
-
-/*
- * Returns the maximum level of the backlight duty cycle field.
- */
-static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 retval;
-
-	if (gma_power_begin(dev, false)) {
-		retval = ((REG_READ(BLC_PWM_CTL) &
-			  BACKLIGHT_MODULATION_FREQ_MASK) >>
-			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
-		gma_power_end(dev);
-	} else
-		retval = ((dev_priv->saveBLC_PWM_CTL &
-			  BACKLIGHT_MODULATION_FREQ_MASK) >>
-			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
-	return retval;
-}
-
-/*
- * Set LVDS backlight level by I2C command
- */
-static int cdv_lvds_i2c_set_brightness(struct drm_device *dev,
-					unsigned int level)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
-	u8 out_buf[2];
-	unsigned int blc_i2c_brightness;
-
-	struct i2c_msg msgs[] = {
-		{
-			.addr = lvds_i2c_bus->slave_addr,
-			.flags = 0,
-			.len = 2,
-			.buf = out_buf,
-		}
-	};
-
-	blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
-			     BRIGHTNESS_MASK /
-			     BRIGHTNESS_MAX_LEVEL);
-
-	if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
-		blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
-
-	out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
-	out_buf[1] = (u8)blc_i2c_brightness;
-
-	if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1)
-		return 0;
-
-	DRM_ERROR("I2C transfer error\n");
-	return -1;
-}
-
-
-static int cdv_lvds_pwm_set_brightness(struct drm_device *dev, int level)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	u32 max_pwm_blc;
-	u32 blc_pwm_duty_cycle;
-
-	max_pwm_blc = cdv_intel_lvds_get_max_backlight(dev);
-
-	/*BLC_PWM_CTL Should be initiated while backlight device init*/
-	BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0);
-
-	blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
-
-	if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
-		blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
-
-	blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
-	REG_WRITE(BLC_PWM_CTL,
-		  (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
-		  (blc_pwm_duty_cycle));
-
-	return 0;
-}
-
-/*
- * Set LVDS backlight level either by I2C or PWM
- */
-void cdv_intel_lvds_set_brightness(struct drm_device *dev, int level)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (!dev_priv->lvds_bl) {
-		DRM_ERROR("NO LVDS Backlight Info\n");
-		return;
-	}
-
-	if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
-		cdv_lvds_i2c_set_brightness(dev, level);
-	else
-		cdv_lvds_pwm_set_brightness(dev, level);
-}
-
-/**
- * Sets the backlight level.
- *
- * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight().
- */
-static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 blc_pwm_ctl;
-
-	if (gma_power_begin(dev, false)) {
-		blc_pwm_ctl =
-			REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-		REG_WRITE(BLC_PWM_CTL,
-				(blc_pwm_ctl |
-				(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
-		gma_power_end(dev);
-	} else {
-		blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
-				~BACKLIGHT_DUTY_CYCLE_MASK;
-		dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
-					(level << BACKLIGHT_DUTY_CYCLE_SHIFT));
-	}
-}
-
-/**
- * Sets the power state for the panel.
- */
-static void cdv_intel_lvds_set_power(struct drm_device *dev,
-				 struct psb_intel_output *output, bool on)
-{
-	u32 pp_status;
-
-	if (!gma_power_begin(dev, true))
-		return;
-
-	if (on) {
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
-			  POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while ((pp_status & PP_ON) == 0);
-
-		cdv_intel_lvds_set_backlight(dev,
-					 output->
-					 mode_dev->backlight_duty_cycle);
-	} else {
-		cdv_intel_lvds_set_backlight(dev, 0);
-
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
-			  ~POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while (pp_status & PP_ON);
-	}
-	gma_power_end(dev);
-}
-
-static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	if (mode == DRM_MODE_DPMS_ON)
-		cdv_intel_lvds_set_power(dev, output, true);
-	else
-		cdv_intel_lvds_set_power(dev, output, false);
-	/* XXX: We never power down the LVDS pairs. */
-}
-
-static void cdv_intel_lvds_save(struct drm_connector *connector)
-{
-}
-
-static void cdv_intel_lvds_restore(struct drm_connector *connector)
-{
-}
-
-int cdv_intel_lvds_mode_valid(struct drm_connector *connector,
-				 struct drm_display_mode *mode)
-{
-	struct psb_intel_output *psb_intel_output =
-				to_psb_intel_output(connector);
-	struct drm_display_mode *fixed_mode =
-	    psb_intel_output->mode_dev->panel_fixed_mode;
-
-	/* just in case */
-	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-		return MODE_NO_DBLESCAN;
-
-	/* just in case */
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-		return MODE_NO_INTERLACE;
-
-	if (fixed_mode) {
-		if (mode->hdisplay > fixed_mode->hdisplay)
-			return MODE_PANEL;
-		if (mode->vdisplay > fixed_mode->vdisplay)
-			return MODE_PANEL;
-	}
-	return MODE_OK;
-}
-
-bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
-{
-	struct psb_intel_mode_device *mode_dev =
-	    enc_to_psb_intel_output(encoder)->mode_dev;
-	struct drm_device *dev = encoder->dev;
-	struct drm_encoder *tmp_encoder;
-	struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
-
-	/* Should never happen!! */
-	list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
-			    head) {
-		if (tmp_encoder != encoder
-		    && tmp_encoder->crtc == encoder->crtc) {
-			printk(KERN_ERR "Can't enable LVDS and another "
-			       "encoder on the same pipe\n");
-			return false;
-		}
-	}
-
-	/*
-	 * If we have timings from the BIOS for the panel, put them in
-	 * to the adjusted mode.  The CRTC will be set up for this mode,
-	 * with the panel scaling set up to source from the H/VDisplay
-	 * of the original mode.
-	 */
-	if (panel_fixed_mode != NULL) {
-		adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
-		adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
-		adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
-		adjusted_mode->htotal = panel_fixed_mode->htotal;
-		adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
-		adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
-		adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
-		adjusted_mode->vtotal = panel_fixed_mode->vtotal;
-		adjusted_mode->clock = panel_fixed_mode->clock;
-		drm_mode_set_crtcinfo(adjusted_mode,
-				      CRTC_INTERLACE_HALVE_V);
-	}
-
-	/*
-	 * XXX: It would be nice to support lower refresh rates on the
-	 * panels to reduce power consumption, and perhaps match the
-	 * user's requested refresh rate.
-	 */
-
-	return true;
-}
-
-static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-	if (!gma_power_begin(dev, true))
-		return;
-
-	mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
-	mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
-					  BACKLIGHT_DUTY_CYCLE_MASK);
-
-	cdv_intel_lvds_set_power(dev, output, false);
-
-	gma_power_end(dev);
-}
-
-static void cdv_intel_lvds_commit(struct drm_encoder *encoder)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-	if (mode_dev->backlight_duty_cycle == 0)
-		mode_dev->backlight_duty_cycle =
-		    cdv_intel_lvds_get_max_backlight(dev);
-
-	cdv_intel_lvds_set_power(dev, output, true);
-}
-
-static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 pfit_control;
-
-	/*
-	 * The LVDS pin pair will already have been turned on in the
-	 * cdv_intel_crtc_mode_set since it has a large impact on the DPLL
-	 * settings.
-	 */
-
-	/*
-	 * Enable automatic panel scaling so that non-native modes fill the
-	 * screen.  Should be enabled before the pipe is enabled, according to
-	 * register description and PRM.
-	 */
-	if (mode->hdisplay != adjusted_mode->hdisplay ||
-	    mode->vdisplay != adjusted_mode->vdisplay)
-		pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
-				HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
-				HORIZ_INTERP_BILINEAR);
-	else
-		pfit_control = 0;
-
-	if (dev_priv->lvds_dither)
-		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-
-	REG_WRITE(PFIT_CONTROL, pfit_control);
-}
-
-/**
- * Detect the LVDS connection.
- *
- * This always returns CONNECTOR_STATUS_CONNECTED.
- * This connector should only have
- * been set up if the LVDS was actually connected anyway.
- */
-static enum drm_connector_status cdv_intel_lvds_detect(
-				struct drm_connector *connector, bool force)
-{
-	return connector_status_connected;
-}
-
-/**
- * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
- */
-static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-	struct psb_intel_mode_device *mode_dev =
-					psb_intel_output->mode_dev;
-	int ret;
-
-	ret = psb_intel_ddc_get_modes(psb_intel_output);
-
-	if (ret)
-		return ret;
-
-	/* Didn't get an EDID, so
-	 * Set wide sync ranges so we get all modes
-	 * handed to valid_mode for checking
-	 */
-	connector->display_info.min_vfreq = 0;
-	connector->display_info.max_vfreq = 200;
-	connector->display_info.min_hfreq = 0;
-	connector->display_info.max_hfreq = 200;
-	if (mode_dev->panel_fixed_mode != NULL) {
-		struct drm_display_mode *mode =
-		    drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
-		drm_mode_probed_add(connector, mode);
-		return 1;
-	}
-
-	return 0;
-}
-
-/**
- * cdv_intel_lvds_destroy - unregister and free LVDS structures
- * @connector: connector to free
- *
- * Unregister the DDC bus for this connector then free the driver private
- * structure.
- */
-void cdv_intel_lvds_destroy(struct drm_connector *connector)
-{
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-
-	if (psb_intel_output->ddc_bus)
-		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-	drm_sysfs_connector_remove(connector);
-	drm_connector_cleanup(connector);
-	kfree(connector);
-}
-
-int cdv_intel_lvds_set_property(struct drm_connector *connector,
-				       struct drm_property *property,
-				       uint64_t value)
-{
-	struct drm_encoder *encoder = connector->encoder;
-
-	if (!strcmp(property->name, "scaling mode") && encoder) {
-		struct psb_intel_crtc *crtc =
-					to_psb_intel_crtc(encoder->crtc);
-		uint64_t curValue;
-
-		if (!crtc)
-			return -1;
-
-		switch (value) {
-		case DRM_MODE_SCALE_FULLSCREEN:
-			break;
-		case DRM_MODE_SCALE_NO_SCALE:
-			break;
-		case DRM_MODE_SCALE_ASPECT:
-			break;
-		default:
-			return -1;
-		}
-
-		if (drm_connector_property_get_value(connector,
-						     property,
-						     &curValue))
-			return -1;
-
-		if (curValue == value)
-			return 0;
-
-		if (drm_connector_property_set_value(connector,
-							property,
-							value))
-			return -1;
-
-		if (crtc->saved_mode.hdisplay != 0 &&
-		    crtc->saved_mode.vdisplay != 0) {
-			if (!drm_crtc_helper_set_mode(encoder->crtc,
-						      &crtc->saved_mode,
-						      encoder->crtc->x,
-						      encoder->crtc->y,
-						      encoder->crtc->fb))
-				return -1;
-		}
-	} else if (!strcmp(property->name, "backlight") && encoder) {
-		if (drm_connector_property_set_value(connector,
-							property,
-							value))
-			return -1;
-		else {
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-			struct drm_psb_private *dev_priv =
-						encoder->dev->dev_private;
-			struct backlight_device *bd =
-						dev_priv->backlight_device;
-			bd->props.brightness = value;
-			backlight_update_status(bd);
-#endif
-		}
-	} else if (!strcmp(property->name, "DPMS") && encoder) {
-		struct drm_encoder_helper_funcs *helpers =
-					encoder->helper_private;
-		helpers->dpms(encoder, value);
-	}
-	return 0;
-}
-
-static const struct drm_encoder_helper_funcs
-					cdv_intel_lvds_helper_funcs = {
-	.dpms = cdv_intel_lvds_encoder_dpms,
-	.mode_fixup = cdv_intel_lvds_mode_fixup,
-	.prepare = cdv_intel_lvds_prepare,
-	.mode_set = cdv_intel_lvds_mode_set,
-	.commit = cdv_intel_lvds_commit,
-};
-
-static const struct drm_connector_helper_funcs
-				cdv_intel_lvds_connector_helper_funcs = {
-	.get_modes = cdv_intel_lvds_get_modes,
-	.mode_valid = cdv_intel_lvds_mode_valid,
-	.best_encoder = psb_intel_best_encoder,
-};
-
-static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
-	.dpms = drm_helper_connector_dpms,
-	.save = cdv_intel_lvds_save,
-	.restore = cdv_intel_lvds_restore,
-	.detect = cdv_intel_lvds_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.set_property = cdv_intel_lvds_set_property,
-	.destroy = cdv_intel_lvds_destroy,
-};
-
-
-static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
-	.destroy = cdv_intel_lvds_enc_destroy,
-};
-
-/**
- * cdv_intel_lvds_init - setup LVDS connectors on this device
- * @dev: drm device
- *
- * Create the connector, register the LVDS DDC bus, and try to figure out what
- * modes we can display on the LVDS panel (if present).
- */
-void cdv_intel_lvds_init(struct drm_device *dev,
-		     struct psb_intel_mode_device *mode_dev)
-{
-	struct psb_intel_output *psb_intel_output;
-	struct cdv_intel_lvds_priv *lvds_priv;
-	struct drm_connector *connector;
-	struct drm_encoder *encoder;
-	struct drm_display_mode *scan;
-	struct drm_crtc *crtc;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 lvds;
-	int pipe;
-
-	psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
-			sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);
-	if (!psb_intel_output)
-		return;
-
-	lvds_priv = (struct cdv_intel_lvds_priv *)(psb_intel_output + 1);
-
-	psb_intel_output->dev_priv = lvds_priv;
-
-	psb_intel_output->mode_dev = mode_dev;
-	connector = &psb_intel_output->base;
-	encoder = &psb_intel_output->enc;
-
-
-	drm_connector_init(dev, &psb_intel_output->base,
-			   &cdv_intel_lvds_connector_funcs,
-			   DRM_MODE_CONNECTOR_LVDS);
-
-	drm_encoder_init(dev, &psb_intel_output->enc,
-			 &cdv_intel_lvds_enc_funcs,
-			 DRM_MODE_ENCODER_LVDS);
-
-
-	drm_mode_connector_attach_encoder(&psb_intel_output->base,
-					  &psb_intel_output->enc);
-	psb_intel_output->type = INTEL_OUTPUT_LVDS;
-
-	drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);
-	drm_connector_helper_add(connector,
-				 &cdv_intel_lvds_connector_helper_funcs);
-	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-	connector->interlace_allowed = false;
-	connector->doublescan_allowed = false;
-
-	/*Attach connector properties*/
-	drm_connector_attach_property(connector,
-				      dev->mode_config.scaling_mode_property,
-				      DRM_MODE_SCALE_FULLSCREEN);
-	drm_connector_attach_property(connector,
-				      dev_priv->backlight_property,
-				      BRIGHTNESS_MAX_LEVEL);
-
-	/**
-	 * Set up I2C bus
-	 * FIXME: distroy i2c_bus when exit
-	 */
-	psb_intel_output->i2c_bus = psb_intel_i2c_create(dev,
-							 GPIOB,
-							 "LVDSBLC_B");
-	if (!psb_intel_output->i2c_bus) {
-		dev_printk(KERN_ERR,
-			&dev->pdev->dev, "I2C bus registration failed.\n");
-		goto failed_blc_i2c;
-	}
-	psb_intel_output->i2c_bus->slave_addr = 0x2C;
-	dev_priv->lvds_i2c_bus =  psb_intel_output->i2c_bus;
-
-	/*
-	 * LVDS discovery:
-	 * 1) check for EDID on DDC
-	 * 2) check for VBT data
-	 * 3) check to see if LVDS is already on
-	 *    if none of the above, no panel
-	 * 4) make sure lid is open
-	 *    if closed, act like it's not there for now
-	 */
-
-	/* Set up the DDC bus. */
-	psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
-							 GPIOC,
-							 "LVDSDDC_C");
-	if (!psb_intel_output->ddc_bus) {
-		dev_printk(KERN_ERR, &dev->pdev->dev,
-			   "DDC bus registration " "failed.\n");
-		goto failed_ddc;
-	}
-
-	/*
-	 * Attempt to get the fixed panel mode from DDC.  Assume that the
-	 * preferred mode is the right one.
-	 */
-	psb_intel_ddc_get_modes(psb_intel_output);
-	list_for_each_entry(scan, &connector->probed_modes, head) {
-		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
-			mode_dev->panel_fixed_mode =
-			    drm_mode_duplicate(dev, scan);
-			goto out;	/* FIXME: check for quirks */
-		}
-	}
-
-	/* Failed to get EDID, what about VBT? do we need this?*/
-	if (dev_priv->lfp_lvds_vbt_mode) {
-		mode_dev->panel_fixed_mode =
-			drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
-		if (mode_dev->panel_fixed_mode) {
-			mode_dev->panel_fixed_mode->type |=
-				DRM_MODE_TYPE_PREFERRED;
-			goto out;	/* FIXME: check for quirks */
-		}
-	}
-	/*
-	 * If we didn't get EDID, try checking if the panel is already turned
-	 * on.	If so, assume that whatever is currently programmed is the
-	 * correct mode.
-	 */
-	lvds = REG_READ(LVDS);
-	pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
-	crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
-
-	if (crtc && (lvds & LVDS_PORT_EN)) {
-		mode_dev->panel_fixed_mode =
-		    cdv_intel_crtc_mode_get(dev, crtc);
-		if (mode_dev->panel_fixed_mode) {
-			mode_dev->panel_fixed_mode->type |=
-			    DRM_MODE_TYPE_PREFERRED;
-			goto out;	/* FIXME: check for quirks */
-		}
-	}
-
-	/* If we still don't have a mode after all that, give up. */
-	if (!mode_dev->panel_fixed_mode) {
-		DRM_DEBUG
-			("Found no modes on the lvds, ignoring the LVDS\n");
-		goto failed_find;
-	}
-
-out:
-	drm_sysfs_connector_add(connector);
-	return;
-
-failed_find:
-	printk(KERN_ERR "Failed find\n");
-	if (psb_intel_output->ddc_bus)
-		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-failed_ddc:
-	printk(KERN_ERR "Failed DDC\n");
-	if (psb_intel_output->i2c_bus)
-		psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-failed_blc_i2c:
-	printk(KERN_ERR "Failed BLC\n");
-	drm_encoder_cleanup(encoder);
-	drm_connector_cleanup(connector);
-	kfree(connector);
-}
diff --git a/drivers/staging/gma500/displays/hdmi.h b/drivers/staging/gma500/displays/hdmi.h
deleted file mode 100644
index d58ba9b..0000000
--- a/drivers/staging/gma500/displays/hdmi.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#ifndef HDMI_H
-#define HDMI_H
-
-extern void hdmi_init(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/pyr_cmd.h b/drivers/staging/gma500/displays/pyr_cmd.h
deleted file mode 100644
index 84bae5c..0000000
--- a/drivers/staging/gma500/displays/pyr_cmd.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#ifndef PYR_CMD_H
-#define PYR_CMD_H
-
-extern void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-
-#endif
-
diff --git a/drivers/staging/gma500/displays/pyr_vid.h b/drivers/staging/gma500/displays/pyr_vid.h
deleted file mode 100644
index ce98860..0000000
--- a/drivers/staging/gma500/displays/pyr_vid.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#ifndef PYR_VID_H
-#define PYR_VID_H
-
-extern void pyr_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *pyr_vid_get_config_mode(struct drm_device* dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tmd_cmd.h b/drivers/staging/gma500/displays/tmd_cmd.h
deleted file mode 100644
index 641e85e..0000000
--- a/drivers/staging/gma500/displays/tmd_cmd.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#ifndef TMD_CMD_H
-#define TMD_CMD_H
-
-extern void tmd_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *tmd_cmd_get_config_mode(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tmd_vid.h b/drivers/staging/gma500/displays/tmd_vid.h
deleted file mode 100644
index 7a5fa3b..0000000
--- a/drivers/staging/gma500/displays/tmd_vid.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#ifndef TMD_VID_H
-#define TMD_VID_H
-
-extern void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-extern struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/displays/tpo_cmd.h b/drivers/staging/gma500/displays/tpo_cmd.h
deleted file mode 100644
index 6105527..0000000
--- a/drivers/staging/gma500/displays/tpo_cmd.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#ifndef TPO_CMD_H
-#define TPO_CMD_H
-
-extern void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-/* extern struct drm_display_mode * */
-/* tpo_cmd_get_config_mode(struct drm_device *dev); */
-
-#endif
diff --git a/drivers/staging/gma500/displays/tpo_vid.h b/drivers/staging/gma500/displays/tpo_vid.h
deleted file mode 100644
index c24f057..0000000
--- a/drivers/staging/gma500/displays/tpo_vid.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#ifndef TPO_VID_H
-#define TPO_VID_H
-
-extern void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
-
-#endif
diff --git a/drivers/staging/gma500/framebuffer.c b/drivers/staging/gma500/framebuffer.c
deleted file mode 100644
index b00761c..0000000
--- a/drivers/staging/gma500/framebuffer.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/console.h>
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_fb_helper.h>
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_drv.h"
-#include "framebuffer.h"
-#include "gtt.h"
-
-#include "mdfld_output.h"
-
-static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
-static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
-					      struct drm_file *file_priv,
-					      unsigned int *handle);
-
-static const struct drm_framebuffer_funcs psb_fb_funcs = {
-	.destroy = psb_user_framebuffer_destroy,
-	.create_handle = psb_user_framebuffer_create_handle,
-};
-
-#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
-
-static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			   unsigned blue, unsigned transp,
-			   struct fb_info *info)
-{
-	struct psb_fbdev *fbdev = info->par;
-	struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
-	uint32_t v;
-
-	if (!fb)
-		return -ENOMEM;
-
-	if (regno > 255)
-		return 1;
-
-	red = CMAP_TOHW(red, info->var.red.length);
-	blue = CMAP_TOHW(blue, info->var.blue.length);
-	green = CMAP_TOHW(green, info->var.green.length);
-	transp = CMAP_TOHW(transp, info->var.transp.length);
-
-	v = (red << info->var.red.offset) |
-	    (green << info->var.green.offset) |
-	    (blue << info->var.blue.offset) |
-	    (transp << info->var.transp.offset);
-
-	if (regno < 16) {
-		switch (fb->bits_per_pixel) {
-		case 16:
-			((uint32_t *) info->pseudo_palette)[regno] = v;
-			break;
-		case 24:
-		case 32:
-			((uint32_t *) info->pseudo_palette)[regno] = v;
-			break;
-		}
-	}
-
-	return 0;
-}
-
-static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	struct psb_fbdev *fbdev = info->par;
-	struct psb_framebuffer *psbfb = &fbdev->pfb;
-	struct drm_device *dev = psbfb->base.dev;
-
-	/*
-	 *	We have to poke our nose in here. The core fb code assumes
-	 *	panning is part of the hardware that can be invoked before
-	 *	the actual fb is mapped. In our case that isn't quite true.
-	 */
-	if (psbfb->gtt->npage)
-        	psb_gtt_roll(dev, psbfb->gtt, var->yoffset);
-	return 0;
-}
-
-void psbfb_suspend(struct drm_device *dev)
-{
-	struct drm_framebuffer *fb = 0;
-	struct psb_framebuffer *psbfb = to_psb_fb(fb);
-
-	console_lock();
-	mutex_lock(&dev->mode_config.mutex);
-	list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
-		struct fb_info *info = psbfb->fbdev;
-		fb_set_suspend(info, 1);
-		drm_fb_helper_blank(FB_BLANK_POWERDOWN, info);
-	}
-	mutex_unlock(&dev->mode_config.mutex);
-	console_unlock();
-}
-
-void psbfb_resume(struct drm_device *dev)
-{
-	struct drm_framebuffer *fb = 0;
-	struct psb_framebuffer *psbfb = to_psb_fb(fb);
-
-	console_lock();
-	mutex_lock(&dev->mode_config.mutex);
-	list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
-		struct fb_info *info = psbfb->fbdev;
-		fb_set_suspend(info, 0);
-		drm_fb_helper_blank(FB_BLANK_UNBLANK, info);
-	}
-	mutex_unlock(&dev->mode_config.mutex);
-	console_unlock();
-	drm_helper_disable_unused_functions(dev);
-}
-
-static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	struct psb_framebuffer *psbfb = vma->vm_private_data;
-	struct drm_device *dev = psbfb->base.dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int page_num;
-	int i;
-	unsigned long address;
-	int ret;
-	unsigned long pfn;
-	/* FIXME: assumes fb at stolen base which may not be true */
-	unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
-
-	page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-	address = (unsigned long)vmf->virtual_address;
-
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-	for (i = 0; i < page_num; i++) {
-		pfn = (phys_addr >> PAGE_SHIFT);
-
-		ret = vm_insert_mixed(vma, address, pfn);
-		if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
-			break;
-		else if (unlikely(ret != 0)) {
-			ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
-			return ret;
-		}
-		address += PAGE_SIZE;
-		phys_addr += PAGE_SIZE;
-	}
-	return VM_FAULT_NOPAGE;
-}
-
-static void psbfb_vm_open(struct vm_area_struct *vma)
-{
-}
-
-static void psbfb_vm_close(struct vm_area_struct *vma)
-{
-}
-
-static struct vm_operations_struct psbfb_vm_ops = {
-	.fault	= psbfb_vm_fault,
-	.open	= psbfb_vm_open,
-	.close	= psbfb_vm_close
-};
-
-static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-	struct psb_fbdev *fbdev = info->par;
-	struct psb_framebuffer *psbfb = &fbdev->pfb;
-
-	if (vma->vm_pgoff != 0)
-		return -EINVAL;
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-		return -EINVAL;
-
-	if (!psbfb->addr_space)
-		psbfb->addr_space = vma->vm_file->f_mapping;
-	/*
-	 * If this is a GEM object then info->screen_base is the virtual
-	 * kernel remapping of the object. FIXME: Review if this is
-	 * suitable for our mmap work
-	 */
-	vma->vm_ops = &psbfb_vm_ops;
-	vma->vm_private_data = (void *)psbfb;
-	vma->vm_flags |= VM_RESERVED | VM_IO |
-					VM_MIXEDMAP | VM_DONTEXPAND;
-	return 0;
-}
-
-static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,
-						unsigned long arg)
-{
-	return -ENOTTY;
-}
-
-static struct fb_ops psbfb_ops = {
-	.owner = THIS_MODULE,
-	.fb_check_var = drm_fb_helper_check_var,
-	.fb_set_par = drm_fb_helper_set_par,
-	.fb_blank = drm_fb_helper_blank,
-	.fb_setcolreg = psbfb_setcolreg,
-	.fb_fillrect = cfb_fillrect,
-	.fb_copyarea = psbfb_copyarea,
-	.fb_imageblit = cfb_imageblit,
-	.fb_mmap = psbfb_mmap,
-	.fb_sync = psbfb_sync,
-	.fb_ioctl = psbfb_ioctl,
-};
-
-static struct fb_ops psbfb_roll_ops = {
-	.owner = THIS_MODULE,
-	.fb_check_var = drm_fb_helper_check_var,
-	.fb_set_par = drm_fb_helper_set_par,
-	.fb_blank = drm_fb_helper_blank,
-	.fb_setcolreg = psbfb_setcolreg,
-	.fb_fillrect = cfb_fillrect,
-	.fb_copyarea = cfb_copyarea,
-	.fb_imageblit = cfb_imageblit,
-	.fb_pan_display = psbfb_pan,
-	.fb_mmap = psbfb_mmap,
-	.fb_sync = psbfb_sync,
-	.fb_ioctl = psbfb_ioctl,
-};
-
-static struct fb_ops psbfb_unaccel_ops = {
-	.owner = THIS_MODULE,
-	.fb_check_var = drm_fb_helper_check_var,
-	.fb_set_par = drm_fb_helper_set_par,
-	.fb_blank = drm_fb_helper_blank,
-	.fb_setcolreg = psbfb_setcolreg,
-	.fb_fillrect = cfb_fillrect,
-	.fb_copyarea = cfb_copyarea,
-	.fb_imageblit = cfb_imageblit,
-	.fb_mmap = psbfb_mmap,
-	.fb_ioctl = psbfb_ioctl,
-};
-
-/**
- *	psb_framebuffer_init	-	initialize a framebuffer
- *	@dev: our DRM device
- *	@fb: framebuffer to set up
- *	@mode_cmd: mode description
- *	@gt: backing object
- *
- *	Configure and fill in the boilerplate for our frame buffer. Return
- *	0 on success or an error code if we fail.
- */
-static int psb_framebuffer_init(struct drm_device *dev,
-					struct psb_framebuffer *fb,
-					struct drm_mode_fb_cmd2 *mode_cmd,
-					struct gtt_range *gt)
-{
-	u32 bpp, depth;
-	int ret;
-
-	drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
-
-	if (mode_cmd->pitches[0] & 63)
-		return -EINVAL;
-	switch (bpp) {
-	case 8:
-	case 16:
-	case 24:
-	case 32:
-		break;
-	default:
-		return -EINVAL;
-	}
-	ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
-	if (ret) {
-		dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
-		return ret;
-	}
-	drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
-	fb->gtt = gt;
-	return 0;
-}
-
-/**
- *	psb_framebuffer_create	-	create a framebuffer backed by gt
- *	@dev: our DRM device
- *	@mode_cmd: the description of the requested mode
- *	@gt: the backing object
- *
- *	Create a framebuffer object backed by the gt, and fill in the
- *	boilerplate required
- *
- *	TODO: review object references
- */
-
-static struct drm_framebuffer *psb_framebuffer_create
-			(struct drm_device *dev,
-			 struct drm_mode_fb_cmd2 *mode_cmd,
-			 struct gtt_range *gt)
-{
-	struct psb_framebuffer *fb;
-	int ret;
-
-	fb = kzalloc(sizeof(*fb), GFP_KERNEL);
-	if (!fb)
-		return ERR_PTR(-ENOMEM);
-
-	ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);
-	if (ret) {
-		kfree(fb);
-		return ERR_PTR(ret);
-	}
-	return &fb->base;
-}
-
-/**
- *	psbfb_alloc		-	allocate frame buffer memory
- *	@dev: the DRM device
- *	@aligned_size: space needed
- *	@force: fall back to GEM buffers if need be
- *
- *	Allocate the frame buffer. In the usual case we get a GTT range that
- *	is stolen memory backed and life is simple. If there isn't sufficient
- *	stolen memory or the system has no stolen memory we allocate a range
- *	and back it with a GEM object.
- *
- *	In this case the GEM object has no handle.
- */
-static struct gtt_range *psbfb_alloc(struct drm_device *dev,
-						int aligned_size, int force)
-{
-	struct gtt_range *backing;
-	/* Begin by trying to use stolen memory backing */
-	backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
-	if (backing) {
-		if (drm_gem_private_object_init(dev,
-					&backing->gem, aligned_size) == 0)
-			return backing;
-		psb_gtt_free_range(dev, backing);
-	}
-	if (!force)
-		return NULL;
-
-	/* Next try using GEM host memory */
-	backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0);
-	if (backing == NULL)
-		return NULL;
-
-	/* Now back it with an object */
-	if (drm_gem_object_init(dev, &backing->gem, aligned_size) != 0) {
-		psb_gtt_free_range(dev, backing);
-		return NULL;
-	}
-	return backing;
-}
-
-/**
- *	psbfb_create		-	create a framebuffer
- *	@fbdev: the framebuffer device
- *	@sizes: specification of the layout
- *
- *	Create a framebuffer to the specifications provided
- */
-static int psbfb_create(struct psb_fbdev *fbdev,
-				struct drm_fb_helper_surface_size *sizes)
-{
-	struct drm_device *dev = fbdev->psb_fb_helper.dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct fb_info *info;
-	struct drm_framebuffer *fb;
-	struct psb_framebuffer *psbfb = &fbdev->pfb;
-	struct drm_mode_fb_cmd2 mode_cmd;
-	struct device *device = &dev->pdev->dev;
-	int size;
-	int ret;
-	struct gtt_range *backing;
-	int gtt_roll = 1;
-	u32 bpp, depth;
-
-	mode_cmd.width = sizes->surface_width;
-	mode_cmd.height = sizes->surface_height;
-	bpp = sizes->surface_bpp;
-
-	/* No 24bit packed */
-	if (bpp == 24)
-		bpp = 32;
-
-	/* Acceleration via the GTT requires pitch to be 4096 byte aligned 
-	   (ie 1024 or 2048 pixels in normal use) */
-	mode_cmd.pitches[0] =  ALIGN(mode_cmd.width * ((bpp + 7) / 8), 4096);
-	depth = sizes->surface_depth;
-
-	size = mode_cmd.pitches[0] * mode_cmd.height;
-	size = ALIGN(size, PAGE_SIZE);
-
-	/* Allocate the framebuffer in the GTT with stolen page backing */
-	backing = psbfb_alloc(dev, size, 0);
-	if (backing == NULL) {
-		/*
-		 *	We couldn't get the space we wanted, fall back to the
-		 *	display engine requirement instead.  The HW requires
-		 *	the pitch to be 64 byte aligned
-		 */
-
-		gtt_roll = 0;	/* Don't use GTT accelerated scrolling */
-
-		mode_cmd.pitches[0] =  ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64);
-		depth = sizes->surface_depth;
-
-		size = mode_cmd.pitches[0] * mode_cmd.height;
-		size = ALIGN(size, PAGE_SIZE);
-
-		/* Allocate the framebuffer in the GTT with stolen page
-		   backing when there is room */
-		backing = psbfb_alloc(dev, size, 1);
-		if (backing == NULL)
-			return -ENOMEM;
-	}
-
-	mutex_lock(&dev->struct_mutex);
-
-	info = framebuffer_alloc(0, device);
-	if (!info) {
-		ret = -ENOMEM;
-		goto out_err1;
-	}
-	info->par = fbdev;
-
-	mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
-
-	ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
-	if (ret)
-		goto out_unref;
-
-	fb = &psbfb->base;
-	psbfb->fbdev = info;
-
-	fbdev->psb_fb_helper.fb = fb;
-	fbdev->psb_fb_helper.fbdev = info;
-
-	strcpy(info->fix.id, "psbfb");
-
-	info->flags = FBINFO_DEFAULT;
-	if (gtt_roll) {	/* GTT rolling seems best */
-		info->fbops = &psbfb_roll_ops;
-		info->flags |= FBINFO_HWACCEL_YPAN;
-        }
-	else if (dev_priv->ops->accel_2d)	/* 2D engine */
-		info->fbops = &psbfb_ops;
-	else	/* Software */
-		info->fbops = &psbfb_unaccel_ops;
-
-	ret = fb_alloc_cmap(&info->cmap, 256, 0);
-	if (ret) {
-		ret = -ENOMEM;
-		goto out_unref;
-	}
-
-	info->fix.smem_start = dev->mode_config.fb_base;
-	info->fix.smem_len = size;
-	info->fix.ywrapstep = gtt_roll;
-	info->fix.ypanstep = gtt_roll;
-
-	if (backing->stolen) {
-		/* Accessed stolen memory directly */
-		info->screen_base = (char *)dev_priv->vram_addr +
-							backing->offset;
-	} else {
-		/* Pin the pages into the GTT and create a mapping to them */
-		psb_gtt_pin(backing);
-		info->screen_base = vm_map_ram(backing->pages, backing->npage,
-				-1, PAGE_KERNEL);
-		if (info->screen_base == NULL) {
-			psb_gtt_unpin(backing);
-			ret = -ENOMEM;
-			goto out_unref;
-		}
-		psbfb->vm_map = 1;
-	}
-	info->screen_size = size;
-
-	if (dev_priv->gtt.stolen_size) {
-		info->apertures = alloc_apertures(1);
-		if (!info->apertures) {
-			ret = -ENOMEM;
-			goto out_unref;
-		}
-		info->apertures->ranges[0].base = dev->mode_config.fb_base;
-		info->apertures->ranges[0].size = dev_priv->gtt.stolen_size;
-	}
-
-	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
-	drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
-				sizes->fb_width, sizes->fb_height);
-
-	info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
-	info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
-
-	info->pixmap.size = 64 * 1024;
-	info->pixmap.buf_align = 8;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 1;
-
-	dev_info(dev->dev, "allocated %dx%d fb\n",
-					psbfb->base.width, psbfb->base.height);
-
-	mutex_unlock(&dev->struct_mutex);
-	return 0;
-out_unref:
-	if (backing->stolen)
-		psb_gtt_free_range(dev, backing);
-	else {
-		if (psbfb->vm_map)
-			vm_unmap_ram(info->screen_base, backing->npage);
-		drm_gem_object_unreference(&backing->gem);
-	}
-out_err1:
-	mutex_unlock(&dev->struct_mutex);
-	psb_gtt_free_range(dev, backing);
-	return ret;
-}
-
-/**
- *	psb_user_framebuffer_create	-	create framebuffer
- *	@dev: our DRM device
- *	@filp: client file
- *	@cmd: mode request
- *
- *	Create a new framebuffer backed by a userspace GEM object
- */
-static struct drm_framebuffer *psb_user_framebuffer_create
-			(struct drm_device *dev, struct drm_file *filp,
-			 struct drm_mode_fb_cmd2 *cmd)
-{
-	struct gtt_range *r;
-	struct drm_gem_object *obj;
-
-	/*
-	 *	Find the GEM object and thus the gtt range object that is
-	 *	to back this space
-	 */
-	obj = drm_gem_object_lookup(dev, filp, cmd->handles[0]);
-	if (obj == NULL)
-		return ERR_PTR(-ENOENT);
-
-	/* Let the core code do all the work */
-	r = container_of(obj, struct gtt_range, gem);
-	return psb_framebuffer_create(dev, cmd, r);
-}
-
-static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
-							u16 blue, int regno)
-{
-}
-
-static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
-					u16 *green, u16 *blue, int regno)
-{
-}
-
-static int psbfb_probe(struct drm_fb_helper *helper,
-				struct drm_fb_helper_surface_size *sizes)
-{
-	struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper;
-	int new_fb = 0;
-	int ret;
-
-	if (!helper->fb) {
-		ret = psbfb_create(psb_fbdev, sizes);
-		if (ret)
-			return ret;
-		new_fb = 1;
-	}
-	return new_fb;
-}
-
-struct drm_fb_helper_funcs psb_fb_helper_funcs = {
-	.gamma_set = psbfb_gamma_set,
-	.gamma_get = psbfb_gamma_get,
-	.fb_probe = psbfb_probe,
-};
-
-int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
-{
-	struct fb_info *info;
-	struct psb_framebuffer *psbfb = &fbdev->pfb;
-
-	if (fbdev->psb_fb_helper.fbdev) {
-		info = fbdev->psb_fb_helper.fbdev;
-
-		/* If this is our base framebuffer then kill any virtual map
-		   for the framebuffer layer and unpin it */
-		if (psbfb->vm_map) {
-			vm_unmap_ram(info->screen_base, psbfb->gtt->npage);
-			psb_gtt_unpin(psbfb->gtt);
-		}
-		unregister_framebuffer(info);
-		if (info->cmap.len)
-			fb_dealloc_cmap(&info->cmap);
-		framebuffer_release(info);
-	}
-	drm_fb_helper_fini(&fbdev->psb_fb_helper);
-	drm_framebuffer_cleanup(&psbfb->base);
-
-	if (psbfb->gtt)
-		drm_gem_object_unreference(&psbfb->gtt->gem);
-	return 0;
-}
-
-int psb_fbdev_init(struct drm_device *dev)
-{
-	struct psb_fbdev *fbdev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
-	if (!fbdev) {
-		dev_err(dev->dev, "no memory\n");
-		return -ENOMEM;
-	}
-
-	dev_priv->fbdev = fbdev;
-	fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs;
-
-	drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs,
-							INTELFB_CONN_LIMIT);
-
-	drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
-	drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
-	return 0;
-}
-
-void psb_fbdev_fini(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (!dev_priv->fbdev)
-		return;
-
-	psb_fbdev_destroy(dev, dev_priv->fbdev);
-	kfree(dev_priv->fbdev);
-	dev_priv->fbdev = NULL;
-}
-
-static void psbfb_output_poll_changed(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_fbdev *fbdev = (struct psb_fbdev *)dev_priv->fbdev;
-	drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
-}
-
-/**
- *	psb_user_framebuffer_create_handle - add hamdle to a framebuffer
- *	@fb: framebuffer
- *	@file_priv: our DRM file
- *	@handle: returned handle
- *
- *	Our framebuffer object is a GTT range which also contains a GEM
- *	object. We need to turn it into a handle for userspace. GEM will do
- *	the work for us
- */
-static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
-					      struct drm_file *file_priv,
-					      unsigned int *handle)
-{
-	struct psb_framebuffer *psbfb = to_psb_fb(fb);
-	struct gtt_range *r = psbfb->gtt;
-	return drm_gem_handle_create(file_priv, &r->gem, handle);
-}
-
-/**
- *	psb_user_framebuffer_destroy	-	destruct user created fb
- *	@fb: framebuffer
- *
- *	User framebuffers are backed by GEM objects so all we have to do is
- *	clean up a bit and drop the reference, GEM will handle the fallout
- */
-static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
-{
-	struct psb_framebuffer *psbfb = to_psb_fb(fb);
-	struct gtt_range *r = psbfb->gtt;
-	struct drm_device *dev = fb->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_fbdev *fbdev = dev_priv->fbdev;
-	struct drm_crtc *crtc;
-	int reset = 0;
-
-	/* Should never get stolen memory for a user fb */
-	WARN_ON(r->stolen);
-
-	/* Check if we are erroneously live */
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-		if (crtc->fb == fb)
-			reset = 1;
-
-	if (reset)
-		/*
-		 * Now force a sane response before we permit the DRM CRTC
-		 * layer to do stupid things like blank the display. Instead
-		 * we reset this framebuffer as if the user had forced a reset.
-		 * We must do this before the cleanup so that the DRM layer
-		 * doesn't get a chance to stick its oar in where it isn't
-		 * wanted.
-		 */
-		drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
-
-	/* Let DRM do its clean up */
-	drm_framebuffer_cleanup(fb);
-	/*  We are no longer using the resource in GEM */
-	drm_gem_object_unreference_unlocked(&r->gem);
-	kfree(fb);
-}
-
-static const struct drm_mode_config_funcs psb_mode_funcs = {
-	.fb_create = psb_user_framebuffer_create,
-	.output_poll_changed = psbfb_output_poll_changed,
-};
-
-static int psb_create_backlight_property(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_property *backlight;
-
-	if (dev_priv->backlight_property)
-		return 0;
-
-	backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE,
-							"backlight", 2);
-	backlight->values[0] = 0;
-	backlight->values[1] = 100;
-
-	dev_priv->backlight_property = backlight;
-
-	return 0;
-}
-
-static void psb_setup_outputs(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_connector *connector;
-
-	drm_mode_create_scaling_mode_property(dev);
-	psb_create_backlight_property(dev);
-
-	dev_priv->ops->output_init(dev);
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list,
-			    head) {
-		struct psb_intel_output *psb_intel_output =
-		    to_psb_intel_output(connector);
-		struct drm_encoder *encoder = &psb_intel_output->enc;
-		int crtc_mask = 0, clone_mask = 0;
-
-		/* valid crtcs */
-		switch (psb_intel_output->type) {
-		case INTEL_OUTPUT_ANALOG:
-			crtc_mask = (1 << 0);
-			clone_mask = (1 << INTEL_OUTPUT_ANALOG);
-			break;
-		case INTEL_OUTPUT_SDVO:
-			crtc_mask = ((1 << 0) | (1 << 1));
-			clone_mask = (1 << INTEL_OUTPUT_SDVO);
-			break;
-		case INTEL_OUTPUT_LVDS:
-			if (IS_MRST(dev))
-				crtc_mask = (1 << 0);
-			else
-				crtc_mask = (1 << 1);
-			clone_mask = (1 << INTEL_OUTPUT_LVDS);
-			break;
-		case INTEL_OUTPUT_MIPI:
-			crtc_mask = (1 << 0);
-			clone_mask = (1 << INTEL_OUTPUT_MIPI);
-			break;
-		case INTEL_OUTPUT_MIPI2:
-			crtc_mask = (1 << 2);
-			clone_mask = (1 << INTEL_OUTPUT_MIPI2);
-			break;
-		case INTEL_OUTPUT_HDMI:
-		        /* HDMI on crtc 1 for SoC devices and crtc 0 for
-                           Cedarview. HDMI on Poulsbo is only via external
-			   logic */
-			if (IS_MFLD(dev) || IS_MRST(dev))
-				crtc_mask = (1 << 1);
-			else
-				crtc_mask = (1 << 0);	/* Cedarview */
-			clone_mask = (1 << INTEL_OUTPUT_HDMI);
-			break;
-		}
-		encoder->possible_crtcs = crtc_mask;
-		encoder->possible_clones =
-		    psb_intel_connector_clones(dev, clone_mask);
-	}
-}
-
-void psb_modeset_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-	struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
-	int i;
-
-	drm_mode_config_init(dev);
-
-	dev->mode_config.min_width = 0;
-	dev->mode_config.min_height = 0;
-
-	dev->mode_config.funcs = (void *) &psb_mode_funcs;
-
-	/* set memory base */
-	/* MRST and PSB should use BAR 2*/
-	pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *)
-					&(dev->mode_config.fb_base));
-
-	/* num pipes is 2 for PSB but 1 for Mrst */
-	for (i = 0; i < dev_priv->num_pipe; i++)
-		psb_intel_crtc_init(dev, i, mode_dev);
-
-	dev->mode_config.max_width = 2048;
-	dev->mode_config.max_height = 2048;
-
-	psb_setup_outputs(dev);
-}
-
-void psb_modeset_cleanup(struct drm_device *dev)
-{
-	mutex_lock(&dev->struct_mutex);
-
-	drm_kms_helper_poll_fini(dev);
-	psb_fbdev_fini(dev);
-	drm_mode_config_cleanup(dev);
-
-	mutex_unlock(&dev->struct_mutex);
-}
diff --git a/drivers/staging/gma500/framebuffer.h b/drivers/staging/gma500/framebuffer.h
deleted file mode 100644
index d1b2289..0000000
--- a/drivers/staging/gma500/framebuffer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2008-2011, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *      Eric Anholt <eric@anholt.net>
- *
- */
-
-#ifndef _FRAMEBUFFER_H_
-#define _FRAMEBUFFER_H_
-
-#include <drm/drmP.h>
-#include <drm/drm_fb_helper.h>
-
-#include "psb_drv.h"
-
-struct psb_framebuffer {
-	struct drm_framebuffer base;
-	struct address_space *addr_space;
-	struct fb_info *fbdev;
-	struct gtt_range *gtt;
-	bool vm_map;		/* True if we must undo a vm_map_ram */
-};
-
-struct psb_fbdev {
-	struct drm_fb_helper psb_fb_helper;
-	struct psb_framebuffer pfb;
-};
-
-#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
-
-extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
-
-#endif
-
diff --git a/drivers/staging/gma500/gem.c b/drivers/staging/gma500/gem.c
deleted file mode 100644
index f6433c0..0000000
--- a/drivers/staging/gma500/gem.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- *  psb GEM interface
- *
- * Copyright (c) 2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Alan Cox
- *
- * TODO:
- *	-	we need to work out if the MMU is relevant (eg for
- *		accelerated operations on a GEM object)
- */
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-
-int psb_gem_init_object(struct drm_gem_object *obj)
-{
-	return -EINVAL;
-}
-
-void psb_gem_free_object(struct drm_gem_object *obj)
-{
-	struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
-	drm_gem_object_release_wrap(obj);
-	/* This must occur last as it frees up the memory of the GEM object */
-	psb_gtt_free_range(obj->dev, gtt);
-}
-
-int psb_gem_get_aperture(struct drm_device *dev, void *data,
-				struct drm_file *file)
-{
-	return -EINVAL;
-}
-
-/**
- *	psb_gem_dumb_map_gtt	-	buffer mapping for dumb interface
- *	@file: our drm client file
- *	@dev: drm device
- *	@handle: GEM handle to the object (from dumb_create)
- *
- *	Do the necessary setup to allow the mapping of the frame buffer
- *	into user memory. We don't have to do much here at the moment.
- */
-int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
-			 uint32_t handle, uint64_t *offset)
-{
-	int ret = 0;
-	struct drm_gem_object *obj;
-
-	if (!(dev->driver->driver_features & DRIVER_GEM))
-		return -ENODEV;
-
-	mutex_lock(&dev->struct_mutex);
-
-	/* GEM does all our handle to object mapping */
-	obj = drm_gem_object_lookup(dev, file, handle);
-	if (obj == NULL) {
-		ret = -ENOENT;
-		goto unlock;
-	}
-	/* What validation is needed here ? */
-
-	/* Make it mmapable */
-	if (!obj->map_list.map) {
-		ret = gem_create_mmap_offset(obj);
-		if (ret)
-			goto out;
-	}
-	/* GEM should really work out the hash offsets for us */
-	*offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
-out:
-	drm_gem_object_unreference(obj);
-unlock:
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
-}
-
-/**
- *	psb_gem_create		-	create a mappable object
- *	@file: the DRM file of the client
- *	@dev: our device
- *	@size: the size requested
- *	@handlep: returned handle (opaque number)
- *
- *	Create a GEM object, fill in the boilerplate and attach a handle to
- *	it so that userspace can speak about it. This does the core work
- *	for the various methods that do/will create GEM objects for things
- */
-static int psb_gem_create(struct drm_file *file,
-	struct drm_device *dev, uint64_t size, uint32_t *handlep)
-{
-	struct gtt_range *r;
-	int ret;
-	u32 handle;
-
-	size = roundup(size, PAGE_SIZE);
-
-	/* Allocate our object - for now a direct gtt range which is not
-	   stolen memory backed */
-	r = psb_gtt_alloc_range(dev, size, "gem", 0);
-	if (r == NULL) {
-		dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
-		return -ENOSPC;
-	}
-	/* Initialize the extra goodies GEM needs to do all the hard work */
-	if (drm_gem_object_init(dev, &r->gem, size) != 0) {
-		psb_gtt_free_range(dev, r);
-		/* GEM doesn't give an error code so use -ENOMEM */
-		dev_err(dev->dev, "GEM init failed for %lld\n", size);
-		return -ENOMEM;
-	}
-	/* Give the object a handle so we can carry it more easily */
-	ret = drm_gem_handle_create(file, &r->gem, &handle);
-	if (ret) {
-		dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
-							&r->gem, size);
-		drm_gem_object_release(&r->gem);
-		psb_gtt_free_range(dev, r);
-		return ret;
-	}
-	/* We have the initial and handle reference but need only one now */
-	drm_gem_object_unreference(&r->gem);
-	*handlep = handle;
-	return 0;
-}
-
-/**
- *	psb_gem_dumb_create	-	create a dumb buffer
- *	@drm_file: our client file
- *	@dev: our device
- *	@args: the requested arguments copied from userspace
- *
- *	Allocate a buffer suitable for use for a frame buffer of the
- *	form described by user space. Give userspace a handle by which
- *	to reference it.
- */
-int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
-			struct drm_mode_create_dumb *args)
-{
-	args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
-	args->size = args->pitch * args->height;
-	return psb_gem_create(file, dev, args->size, &args->handle);
-}
-
-/**
- *	psb_gem_dumb_destroy	-	destroy a dumb buffer
- *	@file: client file
- *	@dev: our DRM device
- *	@handle: the object handle
- *
- *	Destroy a handle that was created via psb_gem_dumb_create, at least
- *	we hope it was created that way. i915 seems to assume the caller
- *	does the checking but that might be worth review ! FIXME
- */
-int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
-			uint32_t handle)
-{
-	/* No special work needed, drop the reference and see what falls out */
-	return drm_gem_handle_delete(file, handle);
-}
-
-/**
- *	psb_gem_fault		-	pagefault handler for GEM objects
- *	@vma: the VMA of the GEM object
- *	@vmf: fault detail
- *
- *	Invoked when a fault occurs on an mmap of a GEM managed area. GEM
- *	does most of the work for us including the actual map/unmap calls
- *	but we need to do the actual page work.
- *
- *	This code eventually needs to handle faulting objects in and out
- *	of the GTT and repacking it when we run out of space. We can put
- *	that off for now and for our simple uses
- *
- *	The VMA was set up by GEM. In doing so it also ensured that the
- *	vma->vm_private_data points to the GEM object that is backing this
- *	mapping.
- */
-int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	struct drm_gem_object *obj;
-	struct gtt_range *r;
-	int ret;
-	unsigned long pfn;
-	pgoff_t page_offset;
-	struct drm_device *dev;
-	struct drm_psb_private *dev_priv;
-
-	obj = vma->vm_private_data;	/* GEM object */
-	dev = obj->dev;
-	dev_priv = dev->dev_private;
-
-	r = container_of(obj, struct gtt_range, gem);	/* Get the gtt range */
-
-	/* Make sure we don't parallel update on a fault, nor move or remove
-	   something from beneath our feet */
-	mutex_lock(&dev->struct_mutex);
-
-	/* For now the mmap pins the object and it stays pinned. As things
-	   stand that will do us no harm */
-	if (r->mmapping == 0) {
-		ret = psb_gtt_pin(r);
-		if (ret < 0) {
-			dev_err(dev->dev, "gma500: pin failed: %d\n", ret);
-			goto fail;
-		}
-		r->mmapping = 1;
-	}
-
-	/* Page relative to the VMA start - we must calculate this ourselves
-	   because vmf->pgoff is the fake GEM offset */
-	page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
-				>> PAGE_SHIFT;
-
-	/* CPU view of the page, don't go via the GART for CPU writes */
-	if (r->stolen)
-		pfn = (dev_priv->stolen_base + r->offset) >> PAGE_SHIFT;
-	else
-		pfn = page_to_pfn(r->pages[page_offset]);
-	ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
-
-fail:
-	mutex_unlock(&dev->struct_mutex);
-	switch (ret) {
-	case 0:
-	case -ERESTARTSYS:
-	case -EINTR:
-		return VM_FAULT_NOPAGE;
-	case -ENOMEM:
-		return VM_FAULT_OOM;
-	default:
-		return VM_FAULT_SIGBUS;
-	}
-}
-
-static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev,
-						int size, u32 *handle)
-{
-	struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1);
-	if (gtt == NULL)
-		return -ENOMEM;
-	if (drm_gem_private_object_init(dev, &gtt->gem, size) != 0)
-		goto free_gtt;
-	if (drm_gem_handle_create(file, &gtt->gem, handle) == 0)
-		return 0;
-free_gtt:
-	psb_gtt_free_range(dev, gtt);
-	return -ENOMEM;
-}
-
-/*
- *	GEM interfaces for our specific client
- */
-int psb_gem_create_ioctl(struct drm_device *dev, void *data,
-					struct drm_file *file)
-{
-	struct drm_psb_gem_create *args = data;
-	int ret;
-	if (args->flags & PSB_GEM_CREATE_STOLEN) {
-		ret = psb_gem_create_stolen(file, dev, args->size,
-							&args->handle);
-		if (ret == 0)
-			return 0;
-		/* Fall throguh */
-		args->flags &= ~PSB_GEM_CREATE_STOLEN;
-	}
-	return psb_gem_create(file, dev, args->size, &args->handle);
-}
-
-int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
-					struct drm_file *file)
-{
-	struct drm_psb_gem_mmap *args = data;
-	return dev->driver->dumb_map_offset(file, dev,
-						args->handle, &args->offset);
-}
-
diff --git a/drivers/staging/gma500/gem_glue.c b/drivers/staging/gma500/gem_glue.c
deleted file mode 100644
index daac121..0000000
--- a/drivers/staging/gma500/gem_glue.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-
-void drm_gem_object_release_wrap(struct drm_gem_object *obj)
-{
-	/* Remove the list map if one is present */
-	if (obj->map_list.map) {
-		struct drm_gem_mm *mm = obj->dev->mm_private;
-		struct drm_map_list *list = &obj->map_list;
-		drm_ht_remove_item(&mm->offset_hash, &list->hash);
-		drm_mm_put_block(list->file_offset_node);
-		kfree(list->map);
-		list->map = NULL;
-	}
-	drm_gem_object_release(obj);
-}
-
-/**
- *	gem_create_mmap_offset		-	invent an mmap offset
- *	@obj: our object
- *
- *	Standard implementation of offset generation for mmap as is
- *	duplicated in several drivers. This belongs in GEM.
- */
-int gem_create_mmap_offset(struct drm_gem_object *obj)
-{
-	struct drm_device *dev = obj->dev;
-	struct drm_gem_mm *mm = dev->mm_private;
-	struct drm_map_list *list;
-	struct drm_local_map *map;
-	int ret;
-
-	list = &obj->map_list;
-	list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
-	if (list->map == NULL)
-		return -ENOMEM;
-	map = list->map;
-	map->type = _DRM_GEM;
-	map->size = obj->size;
-	map->handle = obj;
-
-	list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
-					obj->size / PAGE_SIZE, 0, 0);
-	if (!list->file_offset_node) {
-		dev_err(dev->dev, "failed to allocate offset for bo %d\n",
-								obj->name);
-		ret = -ENOSPC;
-		goto free_it;
-	}
-	list->file_offset_node = drm_mm_get_block(list->file_offset_node,
-					obj->size / PAGE_SIZE, 0);
-	if (!list->file_offset_node) {
-		ret = -ENOMEM;
-		goto free_it;
-	}
-	list->hash.key = list->file_offset_node->start;
-	ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
-	if (ret) {
-		dev_err(dev->dev, "failed to add to map hash\n");
-		goto free_mm;
-	}
-	return 0;
-
-free_mm:
-	drm_mm_put_block(list->file_offset_node);
-free_it:
-	kfree(list->map);
-	list->map = NULL;
-	return ret;
-}
diff --git a/drivers/staging/gma500/gem_glue.h b/drivers/staging/gma500/gem_glue.h
deleted file mode 100644
index ce5ce30..0000000
--- a/drivers/staging/gma500/gem_glue.h
+++ /dev/null
@@ -1,2 +0,0 @@
-extern void drm_gem_object_release_wrap(struct drm_gem_object *obj);
-extern int gem_create_mmap_offset(struct drm_gem_object *obj);
diff --git a/drivers/staging/gma500/gtt.c b/drivers/staging/gma500/gtt.c
deleted file mode 100644
index e770bd1..0000000
--- a/drivers/staging/gma500/gtt.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
- *	    Alan Cox <alan@linux.intel.com>
- */
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-
-
-/*
- *	GTT resource allocator - manage page mappings in GTT space
- */
-
-/**
- *	psb_gtt_mask_pte	-	generate GTT pte entry
- *	@pfn: page number to encode
- *	@type: type of memory in the GTT
- *
- *	Set the GTT entry for the appropriate memory type.
- */
-static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
-{
-	uint32_t mask = PSB_PTE_VALID;
-
-	if (type & PSB_MMU_CACHED_MEMORY)
-		mask |= PSB_PTE_CACHED;
-	if (type & PSB_MMU_RO_MEMORY)
-		mask |= PSB_PTE_RO;
-	if (type & PSB_MMU_WO_MEMORY)
-		mask |= PSB_PTE_WO;
-
-	return (pfn << PAGE_SHIFT) | mask;
-}
-
-/**
- *	psb_gtt_entry		-	find the GTT entries for a gtt_range
- *	@dev: our DRM device
- *	@r: our GTT range
- *
- *	Given a gtt_range object return the GTT offset of the page table
- *	entries for this gtt_range
- */
-u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long offset;
-
-	offset = r->resource.start - dev_priv->gtt_mem->start;
-
-	return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
-}
-
-/**
- *	psb_gtt_insert	-	put an object into the GTT
- *	@dev: our DRM device
- *	@r: our GTT range
- *
- *	Take our preallocated GTT range and insert the GEM object into
- *	the GTT. This is protected via the gtt mutex which the caller
- *	must hold.
- */
-static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
-{
-	u32 *gtt_slot, pte;
-	struct page **pages;
-	int i;
-
-	if (r->pages == NULL) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	WARN_ON(r->stolen);	/* refcount these maybe ? */
-
-	gtt_slot = psb_gtt_entry(dev, r);
-	pages = r->pages;
-
-	/* Make sure changes are visible to the GPU */
-	set_pages_array_uc(pages, r->npage);
-
-	/* Write our page entries into the GTT itself */
-	for (i = r->roll; i < r->npage; i++) {
-		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
-		iowrite32(pte, gtt_slot++);
-	}
-	for (i = 0; i < r->roll; i++) {
-		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
-		iowrite32(pte, gtt_slot++);
-	}
-	/* Make sure all the entries are set before we return */
-	ioread32(gtt_slot - 1);
-
-	return 0;
-}
-
-/**
- *	psb_gtt_remove	-	remove an object from the GTT
- *	@dev: our DRM device
- *	@r: our GTT range
- *
- *	Remove a preallocated GTT range from the GTT. Overwrite all the
- *	page table entries with the dummy page. This is protected via the gtt
- *	mutex which the caller must hold.
- */
-static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 *gtt_slot, pte;
-	int i;
-
-	WARN_ON(r->stolen);
-
-	gtt_slot = psb_gtt_entry(dev, r);
-	pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);
-
-	for (i = 0; i < r->npage; i++)
-		iowrite32(pte, gtt_slot++);
-	ioread32(gtt_slot - 1);
-	set_pages_array_wb(r->pages, r->npage);
-}
-
-/**
- *	psb_gtt_roll	-	set scrolling position
- *	@dev: our DRM device
- *	@r: the gtt mapping we are using
- *	@roll: roll offset
- *
- *	Roll an existing pinned mapping by moving the pages through the GTT.
- *	This allows us to implement hardware scrolling on the consoles without
- *	a 2D engine
- */
-void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
-{
-	u32 *gtt_slot, pte;
-	int i;
-
-	if (roll >= r->npage) {
-		WARN_ON(1);
-		return;
-	}
-
-	r->roll = roll;
-
-	/* Not currently in the GTT - no worry we will write the mapping at
-	   the right position when it gets pinned */
-	if (!r->stolen && !r->in_gart)
-		return;
-
-	gtt_slot = psb_gtt_entry(dev, r);
-
-	for (i = r->roll; i < r->npage; i++) {
-		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
-		iowrite32(pte, gtt_slot++);
-	}
-	for (i = 0; i < r->roll; i++) {
-		pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
-		iowrite32(pte, gtt_slot++);
-	}
-	ioread32(gtt_slot - 1);
-}
-
-/**
- *	psb_gtt_attach_pages	-	attach and pin GEM pages
- *	@gt: the gtt range
- *
- *	Pin and build an in kernel list of the pages that back our GEM object.
- *	While we hold this the pages cannot be swapped out. This is protected
- *	via the gtt mutex which the caller must hold.
- */
-static int psb_gtt_attach_pages(struct gtt_range *gt)
-{
-	struct inode *inode;
-	struct address_space *mapping;
-	int i;
-	struct page *p;
-	int pages = gt->gem.size / PAGE_SIZE;
-
-	WARN_ON(gt->pages);
-
-	/* This is the shared memory object that backs the GEM resource */
-	inode = gt->gem.filp->f_path.dentry->d_inode;
-	mapping = inode->i_mapping;
-
-	gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
-	if (gt->pages == NULL)
-		return -ENOMEM;
-	gt->npage = pages;
-
-	for (i = 0; i < pages; i++) {
-		/* FIXME: needs updating as per mail from Hugh Dickins */
-		p = read_cache_page_gfp(mapping, i,
-					__GFP_COLD | GFP_KERNEL);
-		if (IS_ERR(p))
-			goto err;
-		gt->pages[i] = p;
-	}
-	return 0;
-
-err:
-	while (i--)
-		page_cache_release(gt->pages[i]);
-	kfree(gt->pages);
-	gt->pages = NULL;
-	return PTR_ERR(p);
-}
-
-/**
- *	psb_gtt_detach_pages	-	attach and pin GEM pages
- *	@gt: the gtt range
- *
- *	Undo the effect of psb_gtt_attach_pages. At this point the pages
- *	must have been removed from the GTT as they could now be paged out
- *	and move bus address. This is protected via the gtt mutex which the
- *	caller must hold.
- */
-static void psb_gtt_detach_pages(struct gtt_range *gt)
-{
-	int i;
-	for (i = 0; i < gt->npage; i++) {
-		/* FIXME: do we need to force dirty */
-		set_page_dirty(gt->pages[i]);
-		page_cache_release(gt->pages[i]);
-	}
-	kfree(gt->pages);
-	gt->pages = NULL;
-}
-
-/**
- *	psb_gtt_pin		-	pin pages into the GTT
- *	@gt: range to pin
- *
- *	Pin a set of pages into the GTT. The pins are refcounted so that
- *	multiple pins need multiple unpins to undo.
- *
- *	Non GEM backed objects treat this as a no-op as they are always GTT
- *	backed objects.
- */
-int psb_gtt_pin(struct gtt_range *gt)
-{
-	int ret = 0;
-	struct drm_device *dev = gt->gem.dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	mutex_lock(&dev_priv->gtt_mutex);
-
-	if (gt->in_gart == 0 && gt->stolen == 0) {
-		ret = psb_gtt_attach_pages(gt);
-		if (ret < 0)
-			goto out;
-		ret = psb_gtt_insert(dev, gt);
-		if (ret < 0) {
-			psb_gtt_detach_pages(gt);
-			goto out;
-		}
-	}
-	gt->in_gart++;
-out:
-	mutex_unlock(&dev_priv->gtt_mutex);
-	return ret;
-}
-
-/**
- *	psb_gtt_unpin		-	Drop a GTT pin requirement
- *	@gt: range to pin
- *
- *	Undoes the effect of psb_gtt_pin. On the last drop the GEM object
- *	will be removed from the GTT which will also drop the page references
- *	and allow the VM to clean up or page stuff.
- *
- *	Non GEM backed objects treat this as a no-op as they are always GTT
- *	backed objects.
- */
-void psb_gtt_unpin(struct gtt_range *gt)
-{
-	struct drm_device *dev = gt->gem.dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	mutex_lock(&dev_priv->gtt_mutex);
-
-	WARN_ON(!gt->in_gart);
-
-	gt->in_gart--;
-	if (gt->in_gart == 0 && gt->stolen == 0) {
-		psb_gtt_remove(dev, gt);
-		psb_gtt_detach_pages(gt);
-	}
-	mutex_unlock(&dev_priv->gtt_mutex);
-}
-
-/*
- *	GTT resource allocator - allocate and manage GTT address space
- */
-
-/**
- *	psb_gtt_alloc_range	-	allocate GTT address space
- *	@dev: Our DRM device
- *	@len: length (bytes) of address space required
- *	@name: resource name
- *	@backed: resource should be backed by stolen pages
- *
- *	Ask the kernel core to find us a suitable range of addresses
- *	to use for a GTT mapping.
- *
- *	Returns a gtt_range structure describing the object, or NULL on
- *	error. On successful return the resource is both allocated and marked
- *	as in use.
- */
-struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
-						const char *name, int backed)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct gtt_range *gt;
-	struct resource *r = dev_priv->gtt_mem;
-	int ret;
-	unsigned long start, end;
-
-	if (backed) {
-		/* The start of the GTT is the stolen pages */
-		start = r->start;
-		end = r->start + dev_priv->gtt.stolen_size - 1;
-	} else {
-		/* The rest we will use for GEM backed objects */
-		start = r->start + dev_priv->gtt.stolen_size;
-		end = r->end;
-	}
-
-	gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
-	if (gt == NULL)
-		return NULL;
-	gt->resource.name = name;
-	gt->stolen = backed;
-	gt->in_gart = backed;
-	gt->roll = 0;
-	/* Ensure this is set for non GEM objects */
-	gt->gem.dev = dev;
-	ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
-				len, start, end, PAGE_SIZE, NULL, NULL);
-	if (ret == 0) {
-		gt->offset = gt->resource.start - r->start;
-		return gt;
-	}
-	kfree(gt);
-	return NULL;
-}
-
-/**
- *	psb_gtt_free_range	-	release GTT address space
- *	@dev: our DRM device
- *	@gt: a mapping created with psb_gtt_alloc_range
- *
- *	Release a resource that was allocated with psb_gtt_alloc_range. If the
- *	object has been pinned by mmap users we clean this up here currently.
- */
-void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
-{
-	/* Undo the mmap pin if we are destroying the object */
-	if (gt->mmapping) {
-		psb_gtt_unpin(gt);
-		gt->mmapping = 0;
-	}
-	WARN_ON(gt->in_gart && !gt->stolen);
-	release_resource(&gt->resource);
-	kfree(gt);
-}
-
-void psb_gtt_alloc(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	init_rwsem(&dev_priv->gtt.sem);
-}
-
-void psb_gtt_takedown(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (dev_priv->gtt_map) {
-		iounmap(dev_priv->gtt_map);
-		dev_priv->gtt_map = NULL;
-	}
-	if (dev_priv->gtt_initialized) {
-		pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
-				      dev_priv->gmch_ctrl);
-		PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
-		(void) PSB_RVDC32(PSB_PGETBL_CTL);
-	}
-	if (dev_priv->vram_addr)
-		iounmap(dev_priv->gtt_map);
-}
-
-int psb_gtt_init(struct drm_device *dev, int resume)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned gtt_pages;
-	unsigned long stolen_size, vram_stolen_size;
-	unsigned i, num_pages;
-	unsigned pfn_base;
-	uint32_t vram_pages;
-	uint32_t dvmt_mode = 0;
-	struct psb_gtt *pg;
-
-	int ret = 0;
-	uint32_t pte;
-
-	mutex_init(&dev_priv->gtt_mutex);
-
-	psb_gtt_alloc(dev);
-	pg = &dev_priv->gtt;
-
-	/* Enable the GTT */
-	pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
-	pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
-			      dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
-
-	dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
-	PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
-	(void) PSB_RVDC32(PSB_PGETBL_CTL);
-
-	/* The root resource we allocate address space from */
-	dev_priv->gtt_initialized = 1;
-
-	pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
-
-	/*
-	 *	The video mmu has a hw bug when accessing 0x0D0000000.
-	 *	Make gatt start at 0x0e000,0000. This doesn't actually
-	 *	matter for us but may do if the video acceleration ever
-	 *	gets opened up.
-	 */
-	pg->mmu_gatt_start = 0xE0000000;
-
-	pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
-	gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)
-								>> PAGE_SHIFT;
-	/* Some CDV firmware doesn't report this currently. In which case the
-	   system has 64 gtt pages */
-	if (pg->gtt_start == 0 || gtt_pages == 0) {
-		dev_err(dev->dev, "GTT PCI BAR not initialized.\n");
-		gtt_pages = 64;
-		pg->gtt_start = dev_priv->pge_ctl;
-	}
-
-	pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
-	pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
-								>> PAGE_SHIFT;
-	dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
-
-	if (pg->gatt_pages == 0 || pg->gatt_start == 0) {
-		static struct resource fudge;	/* Preferably peppermint */
-		/* This can occur on CDV SDV systems. Fudge it in this case.
-		   We really don't care what imaginary space is being allocated
-		   at this point */
-		dev_err(dev->dev, "GATT PCI BAR not initialized.\n");
-		pg->gatt_start = 0x40000000;
-		pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT;
-		/* This is a little confusing but in fact the GTT is providing
-		   a view from the GPU into memory and not vice versa. As such
-		   this is really allocating space that is not the same as the
-		   CPU address space on CDV */
-		fudge.start = 0x40000000;
-		fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
-		fudge.name = "fudge";
-		fudge.flags = IORESOURCE_MEM;
-		dev_priv->gtt_mem = &fudge;
-	}
-
-	pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
-	vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base
-								- PAGE_SIZE;
-
-	stolen_size = vram_stolen_size;
-
-	printk(KERN_INFO "Stolen memory information\n");
-	printk(KERN_INFO "       base in RAM: 0x%x\n", dev_priv->stolen_base);
-	printk(KERN_INFO "       size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
-		vram_stolen_size/1024);
-	dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7;
-	printk(KERN_INFO "      the correct size should be: %dM(dvmt mode=%d)\n",
-		(dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
-
-	if (resume && (gtt_pages != pg->gtt_pages) &&
-	    (stolen_size != pg->stolen_size)) {
-		dev_err(dev->dev, "GTT resume error.\n");
-		ret = -EINVAL;
-		goto out_err;
-	}
-
-	pg->gtt_pages = gtt_pages;
-	pg->stolen_size = stolen_size;
-	dev_priv->vram_stolen_size = vram_stolen_size;
-
-	/*
-	 *	Map the GTT and the stolen memory area
-	 */
-	dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
-						gtt_pages << PAGE_SHIFT);
-	if (!dev_priv->gtt_map) {
-		dev_err(dev->dev, "Failure to map gtt.\n");
-		ret = -ENOMEM;
-		goto out_err;
-	}
-
-	dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
-	if (!dev_priv->vram_addr) {
-		dev_err(dev->dev, "Failure to map stolen base.\n");
-		ret = -ENOMEM;
-		goto out_err;
-	}
-
-	/*
-	 * Insert vram stolen pages into the GTT
-	 */
-
-	pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
-	vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
-	printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
-		num_pages, pfn_base << PAGE_SHIFT, 0);
-	for (i = 0; i < num_pages; ++i) {
-		pte = psb_gtt_mask_pte(pfn_base + i, 0);
-		iowrite32(pte, dev_priv->gtt_map + i);
-	}
-
-	/*
-	 * Init rest of GTT to the scratch page to avoid accidents or scribbles
-	 */
-
-	pfn_base = page_to_pfn(dev_priv->scratch_page);
-	pte = psb_gtt_mask_pte(pfn_base, 0);
-	for (; i < gtt_pages; ++i)
-		iowrite32(pte, dev_priv->gtt_map + i);
-
-	(void) ioread32(dev_priv->gtt_map + i - 1);
-	return 0;
-
-out_err:
-	psb_gtt_takedown(dev);
-	return ret;
-}
diff --git a/drivers/staging/gma500/gtt.h b/drivers/staging/gma500/gtt.h
deleted file mode 100644
index aa17423..0000000
--- a/drivers/staging/gma500/gtt.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2008, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#ifndef _PSB_GTT_H_
-#define _PSB_GTT_H_
-
-#include <drm/drmP.h>
-
-/* This wants cleaning up with respect to the psb_dev and un-needed stuff */
-struct psb_gtt {
-	uint32_t gatt_start;
-	uint32_t mmu_gatt_start;
-	uint32_t gtt_start;
-	uint32_t gtt_phys_start;
-	unsigned gtt_pages;
-	unsigned gatt_pages;
-	unsigned long stolen_size;
-	unsigned long vram_stolen_size;
-	struct rw_semaphore sem;
-};
-
-/* Exported functions */
-extern int psb_gtt_init(struct drm_device *dev, int resume);
-extern void psb_gtt_takedown(struct drm_device *dev);
-
-/* Each gtt_range describes an allocation in the GTT area */
-struct gtt_range {
-	struct resource resource;	/* Resource for our allocation */
-	u32 offset;			/* GTT offset of our object */
-	struct drm_gem_object gem;	/* GEM high level stuff */
-	int in_gart;			/* Currently in the GART (ref ct) */
-	bool stolen;			/* Backed from stolen RAM */
-	bool mmapping;			/* Is mmappable */
-	struct page **pages;		/* Backing pages if present */
-	int npage;			/* Number of backing pages */
-	int roll;			/* Roll applied to the GTT entries */
-};
-
-extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
-						const char *name, int backed);
-extern void psb_gtt_kref_put(struct gtt_range *gt);
-extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
-extern int psb_gtt_pin(struct gtt_range *gt);
-extern void psb_gtt_unpin(struct gtt_range *gt);
-extern void psb_gtt_roll(struct drm_device *dev,
-					struct gtt_range *gt, int roll);
-
-#endif
diff --git a/drivers/staging/gma500/intel_bios.c b/drivers/staging/gma500/intel_bios.c
deleted file mode 100644
index 096757f..0000000
--- a/drivers/staging/gma500/intel_bios.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (c) 2006 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *
- */
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-
-
-static void *find_section(struct bdb_header *bdb, int section_id)
-{
-	u8 *base = (u8 *)bdb;
-	int index = 0;
-	u16 total, current_size;
-	u8 current_id;
-
-	/* skip to first section */
-	index += bdb->header_size;
-	total = bdb->bdb_size;
-
-	/* walk the sections looking for section_id */
-	while (index < total) {
-		current_id = *(base + index);
-		index++;
-		current_size = *((u16 *)(base + index));
-		index += 2;
-		if (current_id == section_id)
-			return base + index;
-		index += current_size;
-	}
-
-	return NULL;
-}
-
-static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
-			struct lvds_dvo_timing *dvo_timing)
-{
-	panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
-		dvo_timing->hactive_lo;
-	panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
-		((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
-	panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
-		dvo_timing->hsync_pulse_width;
-	panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
-		((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
-
-	panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
-		dvo_timing->vactive_lo;
-	panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
-		dvo_timing->vsync_off;
-	panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
-		dvo_timing->vsync_pulse_width;
-	panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
-		((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
-	panel_fixed_mode->clock = dvo_timing->clock * 10;
-	panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
-
-	/* Some VBTs have bogus h/vtotal values */
-	if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
-		panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
-	if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
-		panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
-
-	drm_mode_set_name(panel_fixed_mode);
-}
-
-static void parse_backlight_data(struct drm_psb_private *dev_priv,
-				struct bdb_header *bdb)
-{
-	struct bdb_lvds_backlight *vbt_lvds_bl = NULL;
-	struct bdb_lvds_backlight *lvds_bl;
-	u8 p_type = 0;
-	void *bl_start = NULL;
-	struct bdb_lvds_options *lvds_opts
-				= find_section(bdb, BDB_LVDS_OPTIONS);
-
-	dev_priv->lvds_bl = NULL;
-
-	if (lvds_opts)
-		p_type = lvds_opts->panel_type;
-	else
-		return;
-
-	bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
-	vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
-
-	lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL);
-	if (!lvds_bl) {
-		dev_err(dev_priv->dev->dev, "out of memory for backlight data\n");
-		return;
-	}
-	memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
-	dev_priv->lvds_bl = lvds_bl;
-}
-
-/* Try to find integrated panel data */
-static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
-			    struct bdb_header *bdb)
-{
-	struct bdb_lvds_options *lvds_options;
-	struct bdb_lvds_lfp_data *lvds_lfp_data;
-	struct bdb_lvds_lfp_data_entry *entry;
-	struct lvds_dvo_timing *dvo_timing;
-	struct drm_display_mode *panel_fixed_mode;
-
-	/* Defaults if we can't find VBT info */
-	dev_priv->lvds_dither = 0;
-	dev_priv->lvds_vbt = 0;
-
-	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
-	if (!lvds_options)
-		return;
-
-	dev_priv->lvds_dither = lvds_options->pixel_dither;
-	if (lvds_options->panel_type == 0xff)
-		return;
-
-	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
-	if (!lvds_lfp_data)
-		return;
-
-
-	entry = &lvds_lfp_data->data[lvds_options->panel_type];
-	dvo_timing = &entry->dvo_timing;
-
-	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode),
-				      GFP_KERNEL);
-	if (panel_fixed_mode == NULL) {
-		dev_err(dev_priv->dev->dev, "out of memory for fixed panel mode\n");
-		return;
-	}
-
-	dev_priv->lvds_vbt = 1;
-	fill_detail_timing_data(panel_fixed_mode, dvo_timing);
-
-	if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {
-		dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
-		drm_mode_debug_printmodeline(panel_fixed_mode);
-	} else {
-		dev_dbg(dev_priv->dev->dev, "ignoring invalid LVDS VBT\n");
-		dev_priv->lvds_vbt = 0;
-		kfree(panel_fixed_mode);
-	}
-	return;
-}
-
-/* Try to find sdvo panel data */
-static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv,
-		      struct bdb_header *bdb)
-{
-	struct bdb_sdvo_lvds_options *sdvo_lvds_options;
-	struct lvds_dvo_timing *dvo_timing;
-	struct drm_display_mode *panel_fixed_mode;
-
-	dev_priv->sdvo_lvds_vbt_mode = NULL;
-
-	sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
-	if (!sdvo_lvds_options)
-		return;
-
-	dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
-	if (!dvo_timing)
-		return;
-
-	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
-
-	if (!panel_fixed_mode)
-		return;
-
-	fill_detail_timing_data(panel_fixed_mode,
-			dvo_timing + sdvo_lvds_options->panel_type);
-
-	dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
-
-	return;
-}
-
-static void parse_general_features(struct drm_psb_private *dev_priv,
-		       struct bdb_header *bdb)
-{
-	struct bdb_general_features *general;
-
-	/* Set sensible defaults in case we can't find the general block */
-	dev_priv->int_tv_support = 1;
-	dev_priv->int_crt_support = 1;
-
-	general = find_section(bdb, BDB_GENERAL_FEATURES);
-	if (general) {
-		dev_priv->int_tv_support = general->int_tv_support;
-		dev_priv->int_crt_support = general->int_crt_support;
-		dev_priv->lvds_use_ssc = general->enable_ssc;
-
-		if (dev_priv->lvds_use_ssc) {
-			dev_priv->lvds_ssc_freq
-				= general->ssc_freq ? 100 : 96;
-		}
-	}
-}
-
-/**
- * psb_intel_init_bios - initialize VBIOS settings & find VBT
- * @dev: DRM device
- *
- * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers
- * to appropriate values.
- *
- * VBT existence is a sanity check that is relied on by other i830_bios.c code.
- * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
- * feed an updated VBT back through that, compared to what we'll fetch using
- * this method of groping around in the BIOS data.
- *
- * Returns 0 on success, nonzero on failure.
- */
-bool psb_intel_init_bios(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct pci_dev *pdev = dev->pdev;
-	struct vbt_header *vbt = NULL;
-	struct bdb_header *bdb;
-	u8 __iomem *bios;
-	size_t size;
-	int i;
-
-	bios = pci_map_rom(pdev, &size);
-	if (!bios)
-		return -1;
-
-	/* Scour memory looking for the VBT signature */
-	for (i = 0; i + 4 < size; i++) {
-		if (!memcmp(bios + i, "$VBT", 4)) {
-			vbt = (struct vbt_header *)(bios + i);
-			break;
-		}
-	}
-
-	if (!vbt) {
-		dev_err(dev->dev, "VBT signature missing\n");
-		pci_unmap_rom(pdev, bios);
-		return -1;
-	}
-
-	bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
-
-	/* Grab useful general definitions */
-	parse_general_features(dev_priv, bdb);
-	parse_lfp_panel_data(dev_priv, bdb);
-	parse_sdvo_panel_data(dev_priv, bdb);
-	parse_backlight_data(dev_priv, bdb);
-
-	pci_unmap_rom(pdev, bios);
-
-	return 0;
-}
-
-/**
- * Destroy and free VBT data
- */
-void psb_intel_destroy_bios(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_display_mode *sdvo_lvds_vbt_mode =
-				dev_priv->sdvo_lvds_vbt_mode;
-	struct drm_display_mode *lfp_lvds_vbt_mode =
-				dev_priv->lfp_lvds_vbt_mode;
-	struct bdb_lvds_backlight *lvds_bl =
-				dev_priv->lvds_bl;
-
-	/*free sdvo panel mode*/
-	if (sdvo_lvds_vbt_mode) {
-		dev_priv->sdvo_lvds_vbt_mode = NULL;
-		kfree(sdvo_lvds_vbt_mode);
-	}
-
-	if (lfp_lvds_vbt_mode) {
-		dev_priv->lfp_lvds_vbt_mode = NULL;
-		kfree(lfp_lvds_vbt_mode);
-	}
-
-	if (lvds_bl) {
-		dev_priv->lvds_bl = NULL;
-		kfree(lvds_bl);
-	}
-}
diff --git a/drivers/staging/gma500/intel_bios.h b/drivers/staging/gma500/intel_bios.h
deleted file mode 100644
index 70f1bf0..0000000
--- a/drivers/staging/gma500/intel_bios.h
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (c) 2006 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *
- */
-
-#ifndef _I830_BIOS_H_
-#define _I830_BIOS_H_
-
-#include <drm/drmP.h>
-
-struct vbt_header {
-	u8 signature[20];		/**< Always starts with 'VBT$' */
-	u16 version;			/**< decimal */
-	u16 header_size;		/**< in bytes */
-	u16 vbt_size;			/**< in bytes */
-	u8 vbt_checksum;
-	u8 reserved0;
-	u32 bdb_offset;			/**< from beginning of VBT */
-	u32 aim_offset[4];		/**< from beginning of VBT */
-} __attribute__((packed));
-
-
-struct bdb_header {
-	u8 signature[16];		/**< Always 'BIOS_DATA_BLOCK' */
-	u16 version;			/**< decimal */
-	u16 header_size;		/**< in bytes */
-	u16 bdb_size;			/**< in bytes */
-};
-
-/* strictly speaking, this is a "skip" block, but it has interesting info */
-struct vbios_data {
-	u8 type; /* 0 == desktop, 1 == mobile */
-	u8 relstage;
-	u8 chipset;
-	u8 lvds_present:1;
-	u8 tv_present:1;
-	u8 rsvd2:6; /* finish byte */
-	u8 rsvd3[4];
-	u8 signon[155];
-	u8 copyright[61];
-	u16 code_segment;
-	u8 dos_boot_mode;
-	u8 bandwidth_percent;
-	u8 rsvd4; /* popup memory size */
-	u8 resize_pci_bios;
-	u8 rsvd5; /* is crt already on ddc2 */
-} __attribute__((packed));
-
-/*
- * There are several types of BIOS data blocks (BDBs), each block has
- * an ID and size in the first 3 bytes (ID in first, size in next 2).
- * Known types are listed below.
- */
-#define BDB_GENERAL_FEATURES	  1
-#define BDB_GENERAL_DEFINITIONS	  2
-#define BDB_OLD_TOGGLE_LIST	  3
-#define BDB_MODE_SUPPORT_LIST	  4
-#define BDB_GENERIC_MODE_TABLE	  5
-#define BDB_EXT_MMIO_REGS	  6
-#define BDB_SWF_IO		  7
-#define BDB_SWF_MMIO		  8
-#define BDB_DOT_CLOCK_TABLE	  9
-#define BDB_MODE_REMOVAL_TABLE	 10
-#define BDB_CHILD_DEVICE_TABLE	 11
-#define BDB_DRIVER_FEATURES	 12
-#define BDB_DRIVER_PERSISTENCE	 13
-#define BDB_EXT_TABLE_PTRS	 14
-#define BDB_DOT_CLOCK_OVERRIDE	 15
-#define BDB_DISPLAY_SELECT	 16
-/* 17 rsvd */
-#define BDB_DRIVER_ROTATION	 18
-#define BDB_DISPLAY_REMOVE	 19
-#define BDB_OEM_CUSTOM		 20
-#define BDB_EFP_LIST		 21 /* workarounds for VGA hsync/vsync */
-#define BDB_SDVO_LVDS_OPTIONS	 22
-#define BDB_SDVO_PANEL_DTDS	 23
-#define BDB_SDVO_LVDS_PNP_IDS	 24
-#define BDB_SDVO_LVDS_POWER_SEQ	 25
-#define BDB_TV_OPTIONS		 26
-#define BDB_LVDS_OPTIONS	 40
-#define BDB_LVDS_LFP_DATA_PTRS	 41
-#define BDB_LVDS_LFP_DATA	 42
-#define BDB_LVDS_BACKLIGHT	 43
-#define BDB_LVDS_POWER		 44
-#define BDB_SKIP		254 /* VBIOS private block, ignore */
-
-struct bdb_general_features {
-	/* bits 1 */
-	u8 panel_fitting:2;
-	u8 flexaim:1;
-	u8 msg_enable:1;
-	u8 clear_screen:3;
-	u8 color_flip:1;
-
-	/* bits 2 */
-	u8 download_ext_vbt:1;
-	u8 enable_ssc:1;
-	u8 ssc_freq:1;
-	u8 enable_lfp_on_override:1;
-	u8 disable_ssc_ddt:1;
-	u8 rsvd8:3; /* finish byte */
-
-	/* bits 3 */
-	u8 disable_smooth_vision:1;
-	u8 single_dvi:1;
-	u8 rsvd9:6; /* finish byte */
-
-	/* bits 4 */
-	u8 legacy_monitor_detect;
-
-	/* bits 5 */
-	u8 int_crt_support:1;
-	u8 int_tv_support:1;
-	u8 rsvd11:6; /* finish byte */
-} __attribute__((packed));
-
-struct bdb_general_definitions {
-	/* DDC GPIO */
-	u8 crt_ddc_gmbus_pin;
-
-	/* DPMS bits */
-	u8 dpms_acpi:1;
-	u8 skip_boot_crt_detect:1;
-	u8 dpms_aim:1;
-	u8 rsvd1:5; /* finish byte */
-
-	/* boot device bits */
-	u8 boot_display[2];
-	u8 child_dev_size;
-
-	/* device info */
-	u8 tv_or_lvds_info[33];
-	u8 dev1[33];
-	u8 dev2[33];
-	u8 dev3[33];
-	u8 dev4[33];
-	/* may be another device block here on some platforms */
-};
-
-struct bdb_lvds_options {
-	u8 panel_type;
-	u8 rsvd1;
-	/* LVDS capabilities, stored in a dword */
-	u8 pfit_mode:2;
-	u8 pfit_text_mode_enhanced:1;
-	u8 pfit_gfx_mode_enhanced:1;
-	u8 pfit_ratio_auto:1;
-	u8 pixel_dither:1;
-	u8 lvds_edid:1;
-	u8 rsvd2:1;
-	u8 rsvd4;
-} __attribute__((packed));
-
-struct bdb_lvds_backlight {
-	u8 type:2;
-	u8 pol:1;
-	u8 gpio:3;
-	u8 gmbus:2;
-	u16 freq;
-	u8 minbrightness;
-	u8 i2caddr;
-	u8 brightnesscmd;
-	/*FIXME: more...*/
-} __attribute__((packed));
-
-/* LFP pointer table contains entries to the struct below */
-struct bdb_lvds_lfp_data_ptr {
-	u16 fp_timing_offset; /* offsets are from start of bdb */
-	u8 fp_table_size;
-	u16 dvo_timing_offset;
-	u8 dvo_table_size;
-	u16 panel_pnp_id_offset;
-	u8 pnp_table_size;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data_ptrs {
-	u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
-	struct bdb_lvds_lfp_data_ptr ptr[16];
-} __attribute__((packed));
-
-/* LFP data has 3 blocks per entry */
-struct lvds_fp_timing {
-	u16 x_res;
-	u16 y_res;
-	u32 lvds_reg;
-	u32 lvds_reg_val;
-	u32 pp_on_reg;
-	u32 pp_on_reg_val;
-	u32 pp_off_reg;
-	u32 pp_off_reg_val;
-	u32 pp_cycle_reg;
-	u32 pp_cycle_reg_val;
-	u32 pfit_reg;
-	u32 pfit_reg_val;
-	u16 terminator;
-} __attribute__((packed));
-
-struct lvds_dvo_timing {
-	u16 clock;		/**< In 10khz */
-	u8 hactive_lo;
-	u8 hblank_lo;
-	u8 hblank_hi:4;
-	u8 hactive_hi:4;
-	u8 vactive_lo;
-	u8 vblank_lo;
-	u8 vblank_hi:4;
-	u8 vactive_hi:4;
-	u8 hsync_off_lo;
-	u8 hsync_pulse_width;
-	u8 vsync_pulse_width:4;
-	u8 vsync_off:4;
-	u8 rsvd0:6;
-	u8 hsync_off_hi:2;
-	u8 h_image;
-	u8 v_image;
-	u8 max_hv;
-	u8 h_border;
-	u8 v_border;
-	u8 rsvd1:3;
-	u8 digital:2;
-	u8 vsync_positive:1;
-	u8 hsync_positive:1;
-	u8 rsvd2:1;
-} __attribute__((packed));
-
-struct lvds_pnp_id {
-	u16 mfg_name;
-	u16 product_code;
-	u32 serial;
-	u8 mfg_week;
-	u8 mfg_year;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data_entry {
-	struct lvds_fp_timing fp_timing;
-	struct lvds_dvo_timing dvo_timing;
-	struct lvds_pnp_id pnp_id;
-} __attribute__((packed));
-
-struct bdb_lvds_lfp_data {
-	struct bdb_lvds_lfp_data_entry data[16];
-} __attribute__((packed));
-
-struct aimdb_header {
-	char signature[16];
-	char oem_device[20];
-	u16 aimdb_version;
-	u16 aimdb_header_size;
-	u16 aimdb_size;
-} __attribute__((packed));
-
-struct aimdb_block {
-	u8 aimdb_id;
-	u16 aimdb_size;
-} __attribute__((packed));
-
-struct vch_panel_data {
-	u16 fp_timing_offset;
-	u8 fp_timing_size;
-	u16 dvo_timing_offset;
-	u8 dvo_timing_size;
-	u16 text_fitting_offset;
-	u8 text_fitting_size;
-	u16 graphics_fitting_offset;
-	u8 graphics_fitting_size;
-} __attribute__((packed));
-
-struct vch_bdb_22 {
-	struct aimdb_block aimdb_block;
-	struct vch_panel_data panels[16];
-} __attribute__((packed));
-
-struct bdb_sdvo_lvds_options {
-	u8 panel_backlight;
-	u8 h40_set_panel_type;
-	u8 panel_type;
-	u8 ssc_clk_freq;
-	u16 als_low_trip;
-	u16 als_high_trip;
-	u8 sclalarcoeff_tab_row_num;
-	u8 sclalarcoeff_tab_row_size;
-	u8 coefficient[8];
-	u8 panel_misc_bits_1;
-	u8 panel_misc_bits_2;
-	u8 panel_misc_bits_3;
-	u8 panel_misc_bits_4;
-} __attribute__((packed));
-
-
-extern bool psb_intel_init_bios(struct drm_device *dev);
-extern void psb_intel_destroy_bios(struct drm_device *dev);
-
-/*
- * Driver<->VBIOS interaction occurs through scratch bits in
- * GR18 & SWF*.
- */
-
-/* GR18 bits are set on display switch and hotkey events */
-#define GR18_DRIVER_SWITCH_EN	(1<<7) /* 0: VBIOS control, 1: driver control */
-#define GR18_HOTKEY_MASK	0x78 /* See also SWF4 15:0 */
-#define   GR18_HK_NONE		(0x0<<3)
-#define   GR18_HK_LFP_STRETCH	(0x1<<3)
-#define   GR18_HK_TOGGLE_DISP	(0x2<<3)
-#define   GR18_HK_DISP_SWITCH	(0x4<<3) /* see SWF14 15:0 for what to enable */
-#define   GR18_HK_POPUP_DISABLED (0x6<<3)
-#define   GR18_HK_POPUP_ENABLED	(0x7<<3)
-#define   GR18_HK_PFIT		(0x8<<3)
-#define   GR18_HK_APM_CHANGE	(0xa<<3)
-#define   GR18_HK_MULTIPLE	(0xc<<3)
-#define GR18_USER_INT_EN	(1<<2)
-#define GR18_A0000_FLUSH_EN	(1<<1)
-#define GR18_SMM_EN		(1<<0)
-
-/* Set by driver, cleared by VBIOS */
-#define SWF00_YRES_SHIFT	16
-#define SWF00_XRES_SHIFT	0
-#define SWF00_RES_MASK		0xffff
-
-/* Set by VBIOS at boot time and driver at runtime */
-#define SWF01_TV2_FORMAT_SHIFT	8
-#define SWF01_TV1_FORMAT_SHIFT	0
-#define SWF01_TV_FORMAT_MASK	0xffff
-
-#define SWF10_VBIOS_BLC_I2C_EN	(1<<29)
-#define SWF10_GTT_OVERRIDE_EN	(1<<28)
-#define SWF10_LFP_DPMS_OVR	(1<<27) /* override DPMS on display switch */
-#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
-#define   SWF10_OLD_TOGGLE	0x0
-#define   SWF10_TOGGLE_LIST_1	0x1
-#define   SWF10_TOGGLE_LIST_2	0x2
-#define   SWF10_TOGGLE_LIST_3	0x3
-#define   SWF10_TOGGLE_LIST_4	0x4
-#define SWF10_PANNING_EN	(1<<23)
-#define SWF10_DRIVER_LOADED	(1<<22)
-#define SWF10_EXTENDED_DESKTOP	(1<<21)
-#define SWF10_EXCLUSIVE_MODE	(1<<20)
-#define SWF10_OVERLAY_EN	(1<<19)
-#define SWF10_PLANEB_HOLDOFF	(1<<18)
-#define SWF10_PLANEA_HOLDOFF	(1<<17)
-#define SWF10_VGA_HOLDOFF	(1<<16)
-#define SWF10_ACTIVE_DISP_MASK	0xffff
-#define   SWF10_PIPEB_LFP2	(1<<15)
-#define   SWF10_PIPEB_EFP2	(1<<14)
-#define   SWF10_PIPEB_TV2	(1<<13)
-#define   SWF10_PIPEB_CRT2	(1<<12)
-#define   SWF10_PIPEB_LFP	(1<<11)
-#define   SWF10_PIPEB_EFP	(1<<10)
-#define   SWF10_PIPEB_TV	(1<<9)
-#define   SWF10_PIPEB_CRT	(1<<8)
-#define   SWF10_PIPEA_LFP2	(1<<7)
-#define   SWF10_PIPEA_EFP2	(1<<6)
-#define   SWF10_PIPEA_TV2	(1<<5)
-#define   SWF10_PIPEA_CRT2	(1<<4)
-#define   SWF10_PIPEA_LFP	(1<<3)
-#define   SWF10_PIPEA_EFP	(1<<2)
-#define   SWF10_PIPEA_TV	(1<<1)
-#define   SWF10_PIPEA_CRT	(1<<0)
-
-#define SWF11_MEMORY_SIZE_SHIFT	16
-#define SWF11_SV_TEST_EN	(1<<15)
-#define SWF11_IS_AGP		(1<<14)
-#define SWF11_DISPLAY_HOLDOFF	(1<<13)
-#define SWF11_DPMS_REDUCED	(1<<12)
-#define SWF11_IS_VBE_MODE	(1<<11)
-#define SWF11_PIPEB_ACCESS	(1<<10) /* 0 here means pipe a */
-#define SWF11_DPMS_MASK		0x07
-#define   SWF11_DPMS_OFF	(1<<2)
-#define   SWF11_DPMS_SUSPEND	(1<<1)
-#define   SWF11_DPMS_STANDBY	(1<<0)
-#define   SWF11_DPMS_ON		0
-
-#define SWF14_GFX_PFIT_EN	(1<<31)
-#define SWF14_TEXT_PFIT_EN	(1<<30)
-#define SWF14_LID_STATUS_CLOSED	(1<<29) /* 0 here means open */
-#define SWF14_POPUP_EN		(1<<28)
-#define SWF14_DISPLAY_HOLDOFF	(1<<27)
-#define SWF14_DISP_DETECT_EN	(1<<26)
-#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
-#define SWF14_DRIVER_STATUS	(1<<24)
-#define SWF14_OS_TYPE_WIN9X	(1<<23)
-#define SWF14_OS_TYPE_WINNT	(1<<22)
-/* 21:19 rsvd */
-#define SWF14_PM_TYPE_MASK	0x00070000
-#define   SWF14_PM_ACPI_VIDEO	(0x4 << 16)
-#define   SWF14_PM_ACPI		(0x3 << 16)
-#define   SWF14_PM_APM_12	(0x2 << 16)
-#define   SWF14_PM_APM_11	(0x1 << 16)
-#define SWF14_HK_REQUEST_MASK	0x0000ffff /* see GR18 6:3 for event type */
-	  /* if GR18 indicates a display switch */
-#define   SWF14_DS_PIPEB_LFP2_EN (1<<15)
-#define   SWF14_DS_PIPEB_EFP2_EN (1<<14)
-#define   SWF14_DS_PIPEB_TV2_EN  (1<<13)
-#define   SWF14_DS_PIPEB_CRT2_EN (1<<12)
-#define   SWF14_DS_PIPEB_LFP_EN  (1<<11)
-#define   SWF14_DS_PIPEB_EFP_EN  (1<<10)
-#define   SWF14_DS_PIPEB_TV_EN	 (1<<9)
-#define   SWF14_DS_PIPEB_CRT_EN  (1<<8)
-#define   SWF14_DS_PIPEA_LFP2_EN (1<<7)
-#define   SWF14_DS_PIPEA_EFP2_EN (1<<6)
-#define   SWF14_DS_PIPEA_TV2_EN  (1<<5)
-#define   SWF14_DS_PIPEA_CRT2_EN (1<<4)
-#define   SWF14_DS_PIPEA_LFP_EN  (1<<3)
-#define   SWF14_DS_PIPEA_EFP_EN  (1<<2)
-#define   SWF14_DS_PIPEA_TV_EN	 (1<<1)
-#define   SWF14_DS_PIPEA_CRT_EN  (1<<0)
-	  /* if GR18 indicates a panel fitting request */
-#define   SWF14_PFIT_EN		(1<<0) /* 0 means disable */
-	  /* if GR18 indicates an APM change request */
-#define   SWF14_APM_HIBERNATE	0x4
-#define   SWF14_APM_SUSPEND	0x3
-#define   SWF14_APM_STANDBY	0x1
-#define   SWF14_APM_RESTORE	0x0
-
-#endif /* _I830_BIOS_H_ */
diff --git a/drivers/staging/gma500/intel_i2c.c b/drivers/staging/gma500/intel_i2c.c
deleted file mode 100644
index 51cbf65..0000000
--- a/drivers/staging/gma500/intel_i2c.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright © 2006-2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/export.h>
-
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-
-/*
- * Intel GPIO access functions
- */
-
-#define I2C_RISEFALL_TIME 20
-
-static int get_clock(void *data)
-{
-	struct psb_intel_i2c_chan *chan = data;
-	struct drm_device *dev = chan->drm_dev;
-	u32 val;
-
-	val = REG_READ(chan->reg);
-	return (val & GPIO_CLOCK_VAL_IN) != 0;
-}
-
-static int get_data(void *data)
-{
-	struct psb_intel_i2c_chan *chan = data;
-	struct drm_device *dev = chan->drm_dev;
-	u32 val;
-
-	val = REG_READ(chan->reg);
-	return (val & GPIO_DATA_VAL_IN) != 0;
-}
-
-static void set_clock(void *data, int state_high)
-{
-	struct psb_intel_i2c_chan *chan = data;
-	struct drm_device *dev = chan->drm_dev;
-	u32 reserved = 0, clock_bits;
-
-	/* On most chips, these bits must be preserved in software. */
-	reserved =
-		    REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
-					   GPIO_CLOCK_PULLUP_DISABLE);
-
-	if (state_high)
-		clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
-	else
-		clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
-		    GPIO_CLOCK_VAL_MASK;
-	REG_WRITE(chan->reg, reserved | clock_bits);
-	udelay(I2C_RISEFALL_TIME);	/* wait for the line to change state */
-}
-
-static void set_data(void *data, int state_high)
-{
-	struct psb_intel_i2c_chan *chan = data;
-	struct drm_device *dev = chan->drm_dev;
-	u32 reserved = 0, data_bits;
-
-	/* On most chips, these bits must be preserved in software. */
-	reserved =
-		    REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
-					   GPIO_CLOCK_PULLUP_DISABLE);
-
-	if (state_high)
-		data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
-	else
-		data_bits =
-		    GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
-		    GPIO_DATA_VAL_MASK;
-
-	REG_WRITE(chan->reg, reserved | data_bits);
-	udelay(I2C_RISEFALL_TIME);	/* wait for the line to change state */
-}
-
-/**
- * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
- * @dev: DRM device
- * @output: driver specific output device
- * @reg: GPIO reg to use
- * @name: name for this bus
- *
- * Creates and registers a new i2c bus with the Linux i2c layer, for use
- * in output probing and control (e.g. DDC or SDVO control functions).
- *
- * Possible values for @reg include:
- *   %GPIOA
- *   %GPIOB
- *   %GPIOC
- *   %GPIOD
- *   %GPIOE
- *   %GPIOF
- *   %GPIOG
- *   %GPIOH
- * see PRM for details on how these different busses are used.
- */
-struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
-					const u32 reg, const char *name)
-{
-	struct psb_intel_i2c_chan *chan;
-
-	chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL);
-	if (!chan)
-		goto out_free;
-
-	chan->drm_dev = dev;
-	chan->reg = reg;
-	snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
-	chan->adapter.owner = THIS_MODULE;
-	chan->adapter.algo_data = &chan->algo;
-	chan->adapter.dev.parent = &dev->pdev->dev;
-	chan->algo.setsda = set_data;
-	chan->algo.setscl = set_clock;
-	chan->algo.getsda = get_data;
-	chan->algo.getscl = get_clock;
-	chan->algo.udelay = 20;
-	chan->algo.timeout = usecs_to_jiffies(2200);
-	chan->algo.data = chan;
-
-	i2c_set_adapdata(&chan->adapter, chan);
-
-	if (i2c_bit_add_bus(&chan->adapter))
-		goto out_free;
-
-	/* JJJ:  raise SCL and SDA? */
-	set_data(chan, 1);
-	set_clock(chan, 1);
-	udelay(20);
-
-	return chan;
-
-out_free:
-	kfree(chan);
-	return NULL;
-}
-
-/**
- * psb_intel_i2c_destroy - unregister and free i2c bus resources
- * @output: channel to free
- *
- * Unregister the adapter from the i2c layer, then free the structure.
- */
-void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan)
-{
-	if (!chan)
-		return;
-
-	i2c_del_adapter(&chan->adapter);
-	kfree(chan);
-}
diff --git a/drivers/staging/gma500/intel_opregion.c b/drivers/staging/gma500/intel_opregion.c
deleted file mode 100644
index d946bc1..0000000
--- a/drivers/staging/gma500/intel_opregion.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * FIXME: resolve with the i915 version
- */
-
-#include "psb_drv.h"
-
-struct opregion_header {
-	u8 signature[16];
-	u32 size;
-	u32 opregion_ver;
-	u8 bios_ver[32];
-	u8 vbios_ver[16];
-	u8 driver_ver[16];
-	u32 mboxes;
-	u8 reserved[164];
-} __packed;
-
-struct opregion_apci {
-	/*FIXME: add it later*/
-} __packed;
-
-struct opregion_swsci {
-	/*FIXME: add it later*/
-} __packed;
-
-struct opregion_acpi {
-	/*FIXME: add it later*/
-} __packed;
-
-int gma_intel_opregion_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 opregion_phy;
-	void *base;
-	u32 *lid_state;
-
-	dev_priv->lid_state = NULL;
-
-	pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy);
-	if (opregion_phy == 0)
-		return -ENOTSUPP;
-
-	base = ioremap(opregion_phy, 8*1024);
-	if (!base)
-		return -ENOMEM;
-
-	lid_state = base + 0x01ac;
-
-	dev_priv->lid_state = lid_state;
-	dev_priv->lid_last_state = readl(lid_state);
-	return 0;
-}
-
-int gma_intel_opregion_exit(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	if (dev_priv->lid_state)
-		iounmap(dev_priv->lid_state);
-	return 0;
-}
diff --git a/drivers/staging/gma500/mdfld_device.c b/drivers/staging/gma500/mdfld_device.c
deleted file mode 100644
index f47aeb7..0000000
--- a/drivers/staging/gma500/mdfld_device.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_output.h"
-#include "mid_bios.h"
-
-/*
- *	Provide the Medfield specific backlight management
- */
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-static int mdfld_brightness;
-struct backlight_device *mdfld_backlight_device;
-
-static int mfld_set_brightness(struct backlight_device *bd)
-{
-	struct drm_device *dev = bl_get_data(mdfld_backlight_device);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int level = bd->props.brightness;
-
-	/* Percentage 1-100% being valid */
-	if (level < 1)
-		level = 1;
-
-	if (gma_power_begin(dev, 0)) {
-		/* Calculate and set the brightness value */
-		u32 adjusted_level;
-
-		/* Adjust the backlight level with the percent in
-		 * dev_priv->blc_adj2;
-		 */
-		adjusted_level = level * dev_priv->blc_adj2;
-		adjusted_level = adjusted_level / 100;
-#if 0
-#ifndef CONFIG_MDFLD_DSI_DPU
-		if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) && 
-			(dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){
-			mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0);
-			dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level);
-		}
-#endif
-		mdfld_dsi_brightness_control(dev, 0, adjusted_level);
-
-		if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2))
-			mdfld_dsi_brightness_control(dev, 2, adjusted_level);
-#endif
-		gma_power_end(dev);
-	}
-	mdfld_brightness = level;
-	return 0;
-}
-
-int psb_get_brightness(struct backlight_device *bd)
-{
-	/* return locally cached var instead of HW read (due to DPST etc.) */
-	/* FIXME: ideally return actual value in case firmware fiddled with
-	   it */
-	return mdfld_brightness;
-}
-
-static const struct backlight_ops mfld_ops = {
-	.get_brightness = psb_get_brightness,
-	.update_status  = mfld_set_brightness,
-};
-
-static int mdfld_backlight_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct backlight_properties props;
-	memset(&props, 0, sizeof(struct backlight_properties));
-	props.max_brightness = 100;
-	props.type = BACKLIGHT_PLATFORM;
-
-	mdfld_backlight_device = backlight_device_register("mfld-bl",
-					NULL, (void *)dev, &mfld_ops, &props);
-					
-	if (IS_ERR(mdfld_backlight_device))
-		return PTR_ERR(mdfld_backlight_device);
-
-	dev_priv->blc_adj1 = 100;
-	dev_priv->blc_adj2 = 100;
-	mdfld_backlight_device->props.brightness = 100;
-	mdfld_backlight_device->props.max_brightness = 100;
-	backlight_update_status(mdfld_backlight_device);
-	dev_priv->backlight_device = mdfld_backlight_device;
-	return 0;
-}
-
-#endif
-
-/*
- *	Provide the Medfield specific chip logic and low level methods for
- *	power management.
- */
-
-static void mdfld_init_pm(struct drm_device *dev)
-{
-	/* No work needed here yet */
-}
-
-/**
- * mdfld_save_display_registers	-	save registers for pipe
- * @dev: our device
- * @pipe: pipe to save
- *
- * Save the pipe state of the device before we power it off. Keep everything
- * we need to put it back again
- */
-static int mdfld_save_display_registers(struct drm_device *dev, int pipe)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int i;
-
-	/* register */
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 fp_reg = MRST_FPA0;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 htot_reg = HTOTAL_A;
-	u32 hblank_reg = HBLANK_A;
-	u32 hsync_reg = HSYNC_A;
-	u32 vtot_reg = VTOTAL_A;
-	u32 vblank_reg = VBLANK_A;
-	u32 vsync_reg = VSYNC_A;
-	u32 pipesrc_reg = PIPEASRC;
-	u32 dspstride_reg = DSPASTRIDE;
-	u32 dsplinoff_reg = DSPALINOFF;
-	u32 dsptileoff_reg = DSPATILEOFF;
-	u32 dspsize_reg = DSPASIZE;
-	u32 dsppos_reg = DSPAPOS;
-	u32 dspsurf_reg = DSPASURF;
-	u32 mipi_reg = MIPI;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 dspstatus_reg = PIPEASTAT;
-	u32 palette_reg = PALETTE_A;
-
-	/* pointer to values */
-	u32 *dpll_val = &dev_priv->saveDPLL_A;
-	u32 *fp_val = &dev_priv->saveFPA0;
-	u32 *pipeconf_val = &dev_priv->savePIPEACONF;
-	u32 *htot_val = &dev_priv->saveHTOTAL_A;
-	u32 *hblank_val = &dev_priv->saveHBLANK_A;
-	u32 *hsync_val = &dev_priv->saveHSYNC_A;
-	u32 *vtot_val = &dev_priv->saveVTOTAL_A;
-	u32 *vblank_val = &dev_priv->saveVBLANK_A;
-	u32 *vsync_val = &dev_priv->saveVSYNC_A;
-	u32 *pipesrc_val = &dev_priv->savePIPEASRC;
-	u32 *dspstride_val = &dev_priv->saveDSPASTRIDE;
-	u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF;
-	u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF;
-	u32 *dspsize_val = &dev_priv->saveDSPASIZE;
-	u32 *dsppos_val = &dev_priv->saveDSPAPOS;
-	u32 *dspsurf_val = &dev_priv->saveDSPASURF;
-	u32 *mipi_val = &dev_priv->saveMIPI;
-	u32 *dspcntr_val = &dev_priv->saveDSPACNTR;
-	u32 *dspstatus_val = &dev_priv->saveDSPASTATUS;
-	u32 *palette_val = dev_priv->save_palette_a;
-
-	switch (pipe) {
-	case 0:
-		break;
-	case 1:
-		/* register */
-		dpll_reg = MDFLD_DPLL_B;
-		fp_reg = MDFLD_DPLL_DIV0;
-		pipeconf_reg = PIPEBCONF;
-		htot_reg = HTOTAL_B;
-		hblank_reg = HBLANK_B;
-		hsync_reg = HSYNC_B;
-		vtot_reg = VTOTAL_B;
-		vblank_reg = VBLANK_B;
-		vsync_reg = VSYNC_B;
-		pipesrc_reg = PIPEBSRC;
-		dspstride_reg = DSPBSTRIDE;
-		dsplinoff_reg = DSPBLINOFF;
-		dsptileoff_reg = DSPBTILEOFF;
-		dspsize_reg = DSPBSIZE;
-		dsppos_reg = DSPBPOS;
-		dspsurf_reg = DSPBSURF;
-		dspcntr_reg = DSPBCNTR;
-		dspstatus_reg = PIPEBSTAT;
-		palette_reg = PALETTE_B;
-
-		/* values */
-		dpll_val = &dev_priv->saveDPLL_B;
-		fp_val = &dev_priv->saveFPB0;
-		pipeconf_val = &dev_priv->savePIPEBCONF;
-		htot_val = &dev_priv->saveHTOTAL_B;
-		hblank_val = &dev_priv->saveHBLANK_B;
-		hsync_val = &dev_priv->saveHSYNC_B;
-		vtot_val = &dev_priv->saveVTOTAL_B;
-		vblank_val = &dev_priv->saveVBLANK_B;
-		vsync_val = &dev_priv->saveVSYNC_B;
-		pipesrc_val = &dev_priv->savePIPEBSRC;
-		dspstride_val = &dev_priv->saveDSPBSTRIDE;
-		dsplinoff_val = &dev_priv->saveDSPBLINOFF;
-		dsptileoff_val = &dev_priv->saveDSPBTILEOFF;
-		dspsize_val = &dev_priv->saveDSPBSIZE;
-		dsppos_val = &dev_priv->saveDSPBPOS;
-		dspsurf_val = &dev_priv->saveDSPBSURF;
-		dspcntr_val = &dev_priv->saveDSPBCNTR;
-		dspstatus_val = &dev_priv->saveDSPBSTATUS;
-		palette_val = dev_priv->save_palette_b;
-		break;
-	case 2:
-		/* register */
-		pipeconf_reg = PIPECCONF;
-		htot_reg = HTOTAL_C;
-		hblank_reg = HBLANK_C;
-		hsync_reg = HSYNC_C;
-		vtot_reg = VTOTAL_C;
-		vblank_reg = VBLANK_C;
-		vsync_reg = VSYNC_C;
-		pipesrc_reg = PIPECSRC;
-		dspstride_reg = DSPCSTRIDE;
-		dsplinoff_reg = DSPCLINOFF;
-		dsptileoff_reg = DSPCTILEOFF;
-		dspsize_reg = DSPCSIZE;
-		dsppos_reg = DSPCPOS;
-		dspsurf_reg = DSPCSURF;
-		mipi_reg = MIPI_C;
-		dspcntr_reg = DSPCCNTR;
-		dspstatus_reg = PIPECSTAT;
-		palette_reg = PALETTE_C;
-
-		/* pointer to values */
-		pipeconf_val = &dev_priv->savePIPECCONF;
-		htot_val = &dev_priv->saveHTOTAL_C;
-		hblank_val = &dev_priv->saveHBLANK_C;
-		hsync_val = &dev_priv->saveHSYNC_C;
-		vtot_val = &dev_priv->saveVTOTAL_C;
-		vblank_val = &dev_priv->saveVBLANK_C;
-		vsync_val = &dev_priv->saveVSYNC_C;
-		pipesrc_val = &dev_priv->savePIPECSRC;
-		dspstride_val = &dev_priv->saveDSPCSTRIDE;
-		dsplinoff_val = &dev_priv->saveDSPCLINOFF;
-		dsptileoff_val = &dev_priv->saveDSPCTILEOFF;
-		dspsize_val = &dev_priv->saveDSPCSIZE;
-		dsppos_val = &dev_priv->saveDSPCPOS;
-		dspsurf_val = &dev_priv->saveDSPCSURF;
-		mipi_val = &dev_priv->saveMIPI_C;
-		dspcntr_val = &dev_priv->saveDSPCCNTR;
-		dspstatus_val = &dev_priv->saveDSPCSTATUS;
-		palette_val = dev_priv->save_palette_c;
-		break;
-	default:
-		DRM_ERROR("%s, invalid pipe number.\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Pipe & plane A info */
-	*dpll_val = PSB_RVDC32(dpll_reg);
-	*fp_val = PSB_RVDC32(fp_reg);
-	*pipeconf_val = PSB_RVDC32(pipeconf_reg);
-	*htot_val = PSB_RVDC32(htot_reg);
-	*hblank_val = PSB_RVDC32(hblank_reg);
-	*hsync_val = PSB_RVDC32(hsync_reg);
-	*vtot_val = PSB_RVDC32(vtot_reg);
-	*vblank_val = PSB_RVDC32(vblank_reg);
-	*vsync_val = PSB_RVDC32(vsync_reg);
-	*pipesrc_val = PSB_RVDC32(pipesrc_reg);
-	*dspstride_val = PSB_RVDC32(dspstride_reg);
-	*dsplinoff_val = PSB_RVDC32(dsplinoff_reg);
-	*dsptileoff_val = PSB_RVDC32(dsptileoff_reg);
-	*dspsize_val = PSB_RVDC32(dspsize_reg);
-	*dsppos_val = PSB_RVDC32(dsppos_reg);
-	*dspsurf_val = PSB_RVDC32(dspsurf_reg);
-	*dspcntr_val = PSB_RVDC32(dspcntr_reg);
-	*dspstatus_val = PSB_RVDC32(dspstatus_reg);
-
-	/*save palette (gamma) */
-	for (i = 0; i < 256; i++)
-		palette_val[i] = PSB_RVDC32(palette_reg + (i<<2));
-
-	if (pipe == 1) {
-		dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
-		dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
-		dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
-		dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
-		return 0;
-	}
-	*mipi_val = PSB_RVDC32(mipi_reg);
-	return 0;
-}
-
-/**
- * mdfld_save_cursor_overlay_registers	-	save cursor overlay info
- * @dev: our device
- *
- * Save the cursor and overlay register state
- */
-static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	/* Save cursor regs */
-	dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
-	dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
-	dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
-
-	dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
-	dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
-	dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
-
-	dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
-	dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
-	dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);
-
-	/* HW overlay */
-	dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
-	dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
-	dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
-	dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
-	dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
-	dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
-	dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
-
-	dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET);
-	dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET);
-	dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET);
-	dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET);
-	dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET);
-	dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET);
-	dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET);
-
-	return 0;
-}
-/*
- * mdfld_restore_display_registers	-	restore the state of a pipe
- * @dev: our device
- * @pipe: the pipe to restore
- *
- * Restore the state of a pipe to that which was saved by the register save
- * functions.
- */
-static int mdfld_restore_display_registers(struct drm_device *dev, int pipe)
-{
-	/* To get  panel out of ULPS mode */
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dsi_config *dsi_config = NULL;
-	u32 i = 0;
-	u32 dpll = 0;
-	u32 timeout = 0;
-	u32 reg_offset = 0;
-
-	/* register */
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 fp_reg = MRST_FPA0;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 htot_reg = HTOTAL_A;
-	u32 hblank_reg = HBLANK_A;
-	u32 hsync_reg = HSYNC_A;
-	u32 vtot_reg = VTOTAL_A;
-	u32 vblank_reg = VBLANK_A;
-	u32 vsync_reg = VSYNC_A;
-	u32 pipesrc_reg = PIPEASRC;
-	u32 dspstride_reg = DSPASTRIDE;
-	u32 dsplinoff_reg = DSPALINOFF;
-	u32 dsptileoff_reg = DSPATILEOFF;
-	u32 dspsize_reg = DSPASIZE;
-	u32 dsppos_reg = DSPAPOS;
-	u32 dspsurf_reg = DSPASURF;
-	u32 dspstatus_reg = PIPEASTAT;
-	u32 mipi_reg = MIPI;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 palette_reg = PALETTE_A;
-
-	/* values */
-	u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE;
-	u32 fp_val = dev_priv->saveFPA0;
-	u32 pipeconf_val = dev_priv->savePIPEACONF;
-	u32 htot_val = dev_priv->saveHTOTAL_A;
-	u32 hblank_val = dev_priv->saveHBLANK_A;
-	u32 hsync_val = dev_priv->saveHSYNC_A;
-	u32 vtot_val = dev_priv->saveVTOTAL_A;
-	u32 vblank_val = dev_priv->saveVBLANK_A;
-	u32 vsync_val = dev_priv->saveVSYNC_A;
-	u32 pipesrc_val = dev_priv->savePIPEASRC;
-	u32 dspstride_val = dev_priv->saveDSPASTRIDE;
-	u32 dsplinoff_val = dev_priv->saveDSPALINOFF;
-	u32 dsptileoff_val = dev_priv->saveDSPATILEOFF;
-	u32 dspsize_val = dev_priv->saveDSPASIZE;
-	u32 dsppos_val = dev_priv->saveDSPAPOS;
-	u32 dspsurf_val = dev_priv->saveDSPASURF;
-	u32 dspstatus_val = dev_priv->saveDSPASTATUS;
-	u32 mipi_val = dev_priv->saveMIPI;
-	u32 dspcntr_val = dev_priv->saveDSPACNTR;
-	u32 *palette_val = dev_priv->save_palette_a;
-
-	switch (pipe) {
-	case 0:
-		dsi_config = dev_priv->dsi_configs[0];
-		break;
-	case 1:
-		/* register */
-		dpll_reg = MDFLD_DPLL_B;
-		fp_reg = MDFLD_DPLL_DIV0;
-		pipeconf_reg = PIPEBCONF;
-		htot_reg = HTOTAL_B;
-		hblank_reg = HBLANK_B;
-		hsync_reg = HSYNC_B;
-		vtot_reg = VTOTAL_B;
-		vblank_reg = VBLANK_B;
-		vsync_reg = VSYNC_B;
-		pipesrc_reg = PIPEBSRC;
-		dspstride_reg = DSPBSTRIDE;
-		dsplinoff_reg = DSPBLINOFF;
-		dsptileoff_reg = DSPBTILEOFF;
-		dspsize_reg = DSPBSIZE;
-		dsppos_reg = DSPBPOS;
-		dspsurf_reg = DSPBSURF;
-		dspcntr_reg = DSPBCNTR;
-		palette_reg = PALETTE_B;
-		dspstatus_reg = PIPEBSTAT;
-
-		/* values */
-		dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE;
-		fp_val = dev_priv->saveFPB0;
-		pipeconf_val = dev_priv->savePIPEBCONF;
-		htot_val = dev_priv->saveHTOTAL_B;
-		hblank_val = dev_priv->saveHBLANK_B;
-		hsync_val = dev_priv->saveHSYNC_B;
-		vtot_val = dev_priv->saveVTOTAL_B;
-		vblank_val = dev_priv->saveVBLANK_B;
-		vsync_val = dev_priv->saveVSYNC_B;
-		pipesrc_val = dev_priv->savePIPEBSRC;
-		dspstride_val = dev_priv->saveDSPBSTRIDE;
-		dsplinoff_val = dev_priv->saveDSPBLINOFF;
-		dsptileoff_val = dev_priv->saveDSPBTILEOFF;
-		dspsize_val = dev_priv->saveDSPBSIZE;
-		dsppos_val = dev_priv->saveDSPBPOS;
-		dspsurf_val = dev_priv->saveDSPBSURF;
-		dspcntr_val = dev_priv->saveDSPBCNTR;
-		dspstatus_val = dev_priv->saveDSPBSTATUS;
-		palette_val = dev_priv->save_palette_b;
-		break;
-	case 2:
-		reg_offset = MIPIC_REG_OFFSET;
-
-		/* register */
-		pipeconf_reg = PIPECCONF;
-		htot_reg = HTOTAL_C;
-		hblank_reg = HBLANK_C;
-		hsync_reg = HSYNC_C;
-		vtot_reg = VTOTAL_C;
-		vblank_reg = VBLANK_C;
-		vsync_reg = VSYNC_C;
-		pipesrc_reg = PIPECSRC;
-		dspstride_reg = DSPCSTRIDE;
-		dsplinoff_reg = DSPCLINOFF;
-		dsptileoff_reg = DSPCTILEOFF;
-		dspsize_reg = DSPCSIZE;
-		dsppos_reg = DSPCPOS;
-		dspsurf_reg = DSPCSURF;
-		mipi_reg = MIPI_C;
-		dspcntr_reg = DSPCCNTR;
-		palette_reg = PALETTE_C;
-		dspstatus_reg = PIPECSTAT;
-
-		/* values */
-		pipeconf_val = dev_priv->savePIPECCONF;
-		htot_val = dev_priv->saveHTOTAL_C;
-		hblank_val = dev_priv->saveHBLANK_C;
-		hsync_val = dev_priv->saveHSYNC_C;
-		vtot_val = dev_priv->saveVTOTAL_C;
-		vblank_val = dev_priv->saveVBLANK_C;
-		vsync_val = dev_priv->saveVSYNC_C;
-		pipesrc_val = dev_priv->savePIPECSRC;
-		dspstride_val = dev_priv->saveDSPCSTRIDE;
-		dsplinoff_val = dev_priv->saveDSPCLINOFF;
-		dsptileoff_val = dev_priv->saveDSPCTILEOFF;
-		dspsize_val = dev_priv->saveDSPCSIZE;
-		dsppos_val = dev_priv->saveDSPCPOS;
-		dspsurf_val = dev_priv->saveDSPCSURF;
-		dspstatus_val = dev_priv->saveDSPCSTATUS;
-		mipi_val = dev_priv->saveMIPI_C;
-		dspcntr_val = dev_priv->saveDSPCCNTR;
-		palette_val = dev_priv->save_palette_c;
-
-		dsi_config = dev_priv->dsi_configs[1];
-		break;
-	default:
-		DRM_ERROR("%s, invalid pipe number.\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Make sure VGA plane is off. it initializes to on after reset!*/
-	PSB_WVDC32(0x80000000, VGACNTRL);
-	if (pipe == 1) {
-		PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
-		PSB_RVDC32(dpll_reg);
-
-		PSB_WVDC32(fp_val, fp_reg);
-	} else {
-		dpll = PSB_RVDC32(dpll_reg);
-
-		if (!(dpll & DPLL_VCO_ENABLE)) {
-
-			/* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
-			if (dpll & MDFLD_PWR_GATE_EN) {
-				dpll &= ~MDFLD_PWR_GATE_EN;
-				PSB_WVDC32(dpll, dpll_reg);
-				udelay(500);	/* FIXME: 1 ? */
-			}
-
-			PSB_WVDC32(fp_val, fp_reg);
-			PSB_WVDC32(dpll_val, dpll_reg);
-			/* FIXME_MDFLD PO - change 500 to 1 after PO */
-			udelay(500);
-
-			dpll_val |= DPLL_VCO_ENABLE;
-			PSB_WVDC32(dpll_val, dpll_reg);
-			PSB_RVDC32(dpll_reg);
-
-			/* wait for DSI PLL to lock */
-			while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
-				udelay(150);
-				timeout++;
-			}
-
-			if (timeout == 20000) {
-				DRM_ERROR("%s, can't lock DSIPLL.\n",
-							__func__);
-				return -EINVAL;
-			}
-		}
-	}
-	/* Restore mode */
-	PSB_WVDC32(htot_val, htot_reg);
-	PSB_WVDC32(hblank_val, hblank_reg);
-	PSB_WVDC32(hsync_val, hsync_reg);
-	PSB_WVDC32(vtot_val, vtot_reg);
-	PSB_WVDC32(vblank_val, vblank_reg);
-	PSB_WVDC32(vsync_val, vsync_reg);
-	PSB_WVDC32(pipesrc_val, pipesrc_reg);
-	PSB_WVDC32(dspstatus_val, dspstatus_reg);
-
-	/* Set up the plane */
-	PSB_WVDC32(dspstride_val, dspstride_reg);
-	PSB_WVDC32(dsplinoff_val, dsplinoff_reg);
-	PSB_WVDC32(dsptileoff_val, dsptileoff_reg);
-	PSB_WVDC32(dspsize_val, dspsize_reg);
-	PSB_WVDC32(dsppos_val, dsppos_reg);
-	PSB_WVDC32(dspsurf_val, dspsurf_reg);
-
-	if (pipe == 1) {
-		PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
-		PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
-		PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL);
-		PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL);
-
-	} else {
-		/* Set up pipe related registers */
-		PSB_WVDC32(mipi_val, mipi_reg);
-		/* Setup MIPI adapter + MIPI IP registers */
-		mdfld_dsi_controller_init(dsi_config, pipe);
-		msleep(20);
-	}
-	/* Enable the plane */
-	PSB_WVDC32(dspcntr_val, dspcntr_reg);
-	msleep(20);
-	/* Enable the pipe */
-	PSB_WVDC32(pipeconf_val, pipeconf_reg);
-
-	for (i = 0; i < 256; i++)
-		PSB_WVDC32(palette_val[i], palette_reg + (i<<2));
-	if (pipe == 1)
-		return 0;
-	if (!mdfld_panel_dpi(dev))
-		mdfld_enable_te(dev, pipe);
-	return 0;
-}
-
-/**
- * mdfld_restore_cursor_overlay_registers	-	restore cursor
- * @dev: our device
- *
- * Restore the cursor and overlay state that was saved earlier
- */
-static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	/* Enable Cursor A */
-	PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
-	PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
-	PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
-
-	PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
-	PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
-	PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
-
-	PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
-	PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
-	PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);
-
-	/* Restore HW overlay */
-	PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
-
-	PSB_WVDC32(dev_priv->saveOV_OVADD_C, OV_OVADD + OV_C_OFFSET);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC0_C, OV_OGAMC0 + OV_C_OFFSET);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC1_C, OV_OGAMC1 + OV_C_OFFSET);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC2_C, OV_OGAMC2 + OV_C_OFFSET);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC3_C, OV_OGAMC3 + OV_C_OFFSET);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC4_C, OV_OGAMC4 + OV_C_OFFSET);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC5_C, OV_OGAMC5 + OV_C_OFFSET);
-
-	return 0;
-}
-
-/**
- *	mdfld_save_display_registers	-	save registers lost on suspend
- *	@dev: our DRM device
- *
- *	Save the state we need in order to be able to restore the interface
- *	upon resume from suspend
- */
-static int mdfld_save_registers(struct drm_device *dev)
-{
-	/* FIXME: We need to shut down panels here if using them
-	   and once the right bits are merged */
-	mdfld_save_cursor_overlay_registers(dev);
-	mdfld_save_display_registers(dev, 0);
-	mdfld_save_display_registers(dev, 0);
-	mdfld_save_display_registers(dev, 2);
-	mdfld_save_display_registers(dev, 1);
-	mdfld_disable_crtc(dev, 0);
-	mdfld_disable_crtc(dev, 2);
-	mdfld_disable_crtc(dev, 1);
-	return 0;
-}
-
-/**
- *	mdfld_restore_display_registers	-	restore lost register state
- *	@dev: our DRM device
- *
- *	Restore register state that was lost during suspend and resume.
- */
-static int mdfld_restore_registers(struct drm_device *dev)
-{
-	mdfld_restore_display_registers(dev, 1);
-	mdfld_restore_display_registers(dev, 0);
-	mdfld_restore_display_registers(dev, 2);
-	mdfld_restore_cursor_overlay_registers(dev);
-	return 0;
-}
-
-static int mdfld_power_down(struct drm_device *dev)
-{
-	/* FIXME */
-	return 0;
-}
-
-static int mdfld_power_up(struct drm_device *dev)
-{
-	/* FIXME */
-	return 0;
-}
-
-const struct psb_ops mdfld_chip_ops = {
-	.name = "Medfield",
-	.accel_2d = 0,
-	.pipes = 3,
-	.crtcs = 2,
-	.sgx_offset = MRST_SGX_OFFSET,
-
-	.chip_setup = mid_chip_setup,
-
-	.crtc_helper = &mdfld_helper_funcs,
-	.crtc_funcs = &mdfld_intel_crtc_funcs,
-
-	.output_init = mdfld_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	.backlight_init = mdfld_backlight_init,
-#endif
-
-	.init_pm = mdfld_init_pm,
-	.save_regs = mdfld_save_registers,
-	.restore_regs = mdfld_restore_registers,
-	.power_down = mdfld_power_down,
-	.power_up = mdfld_power_up,
-};
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.c b/drivers/staging/gma500/mdfld_dsi_dbi.c
deleted file mode 100644
index fd211f3..0000000
--- a/drivers/staging/gma500/mdfld_dsi_dbi.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *  jim liu <jim.liu@intel.com>
- *  Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "power.h"
-#include <linux/pm_runtime.h>
-
-int enable_gfx_rtpm;
-
-extern struct drm_device *gpDrmDevice;
-extern int gfxrtdelay;
-int enter_dsr;
-struct mdfld_dsi_dbi_output *gdbi_output;
-extern bool gbgfxsuspended;
-extern int enable_gfx_rtpm;
-extern int gfxrtdelay;
-
-#define MDFLD_DSR_MAX_IDLE_COUNT	2
-
-/*
- * set refreshing area
- */
-int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
-				u16 x1, u16 y1, u16 x2, u16 y2)
-{
-	struct mdfld_dsi_pkg_sender *sender =
-		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-	u8 param[4];
-	u8 cmd;
-	int err;
-
-	if (!sender) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	/* Set column */
-	cmd = DCS_SET_COLUMN_ADDRESS;
-	param[0] = x1 >> 8;
-	param[1] = x1;
-	param[2] = x2 >> 8;
-	param[3] = x2;
-
-	err = mdfld_dsi_send_dcs(sender,
-				 cmd,
-				 param,
-				 4,
-				 CMD_DATA_SRC_SYSTEM_MEM,
-				 MDFLD_DSI_QUEUE_PACKAGE);
-	if (err) {
-		dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
-		goto err_out;
-	}
-
-	/* Set page */
-	cmd = DCS_SET_PAGE_ADDRESS;
-	param[0] = y1 >> 8;
-	param[1] = y1;
-	param[2] = y2 >> 8;
-	param[3] = y2;
-
-	err = mdfld_dsi_send_dcs(sender,
-				 cmd,
-				 param,
-				 4,
-				 CMD_DATA_SRC_SYSTEM_MEM,
-				 MDFLD_DSI_QUEUE_PACKAGE);
-	if (err) {
-		dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
-		goto err_out;
-	}
-
-	/*update screen*/
-	err = mdfld_dsi_send_dcs(sender,
-				 write_mem_start,
-				 NULL,
-				 0,
-				 CMD_DATA_SRC_PIPE,
-				 MDFLD_DSI_QUEUE_PACKAGE);
-	if (err) {
-		dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
-		goto err_out;
-	}
-	mdfld_dsi_cmds_kick_out(sender);
-err_out:
-	return err;
-}
-
-/*
- * set panel's power state
- */
-int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
-								int mode)
-{
-	struct drm_device *dev = dbi_output->dev;
-	struct mdfld_dsi_pkg_sender *sender =
-		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-	u8 param = 0;
-	u32 err = 0;
-
-	if (!sender) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	if (mode == DRM_MODE_DPMS_ON) {
-		/* Exit sleep mode */
-		err = mdfld_dsi_send_dcs(sender,
-					 DCS_EXIT_SLEEP_MODE,
-					 NULL,
-					 0,
-					 CMD_DATA_SRC_SYSTEM_MEM,
-					 MDFLD_DSI_QUEUE_PACKAGE);
-		if (err) {
-			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-						DCS_EXIT_SLEEP_MODE);
-			goto power_err;
-		}
-
-		/* Set display on */
-		err = mdfld_dsi_send_dcs(sender,
-					 DCS_SET_DISPLAY_ON,
-					 NULL,
-					 0,
-					 CMD_DATA_SRC_SYSTEM_MEM,
-					 MDFLD_DSI_QUEUE_PACKAGE);
-		if (err) {
-			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							DCS_SET_DISPLAY_ON);
-			goto power_err;
-		}
-
-		/* set tear effect on */
-		err = mdfld_dsi_send_dcs(sender,
-					 DCS_SET_TEAR_ON,
-					 &param,
-					 1,
-					 CMD_DATA_SRC_SYSTEM_MEM,
-					 MDFLD_DSI_QUEUE_PACKAGE);
-		if (err) {
-			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							set_tear_on);
-			goto power_err;
-		}
-
-		/**
-		 * FIXME: remove this later
-		 */
-		err = mdfld_dsi_send_dcs(sender,
-					 DCS_WRITE_MEM_START,
-					 NULL,
-					 0,
-					 CMD_DATA_SRC_PIPE,
-					 MDFLD_DSI_QUEUE_PACKAGE);
-		if (err) {
-			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-						DCS_WRITE_MEM_START);
-			goto power_err;
-		}
-	} else {
-		/* Set tear effect off */
-		err = mdfld_dsi_send_dcs(sender,
-					 DCS_SET_TEAR_OFF,
-					 NULL,
-					 0,
-					 CMD_DATA_SRC_SYSTEM_MEM,
-					 MDFLD_DSI_QUEUE_PACKAGE);
-		if (err) {
-			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							DCS_SET_TEAR_OFF);
-			goto power_err;
-		}
-
-		/* Turn display off */
-		err = mdfld_dsi_send_dcs(sender,
-					 DCS_SET_DISPLAY_OFF,
-					 NULL,
-					 0,
-					 CMD_DATA_SRC_SYSTEM_MEM,
-					 MDFLD_DSI_QUEUE_PACKAGE);
-		if (err) {
-			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-						DCS_SET_DISPLAY_OFF);
-			goto power_err;
-		}
-
-		/* Now enter sleep mode */
-		err = mdfld_dsi_send_dcs(sender,
-					 DCS_ENTER_SLEEP_MODE,
-					 NULL,
-					 0,
-					 CMD_DATA_SRC_SYSTEM_MEM,
-					 MDFLD_DSI_QUEUE_PACKAGE);
-		if (err) {
-			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							DCS_ENTER_SLEEP_MODE);
-			goto power_err;
-		}
-	}
-	mdfld_dsi_cmds_kick_out(sender);
-power_err:
-	return err;
-}
-
-/*
- * send a generic DCS command with a parameter list
- */
-int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
-			u8 dcs,  u8 *param, u32 num, u8 data_src)
-{
-	struct mdfld_dsi_pkg_sender *sender =
-		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-	int ret;
-
-	if (!sender) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	ret = mdfld_dsi_send_dcs(sender,
-				 dcs,
-				 param,
-				 num,
-				 data_src,
-				 MDFLD_DSI_SEND_PACKAGE);
-
-	return ret;
-}
-
-/*
- * Enter DSR
- */
-void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
-{
-	u32 reg_val;
-	struct drm_device *dev = dbi_output->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_crtc *crtc = dbi_output->base.base.crtc;
-	struct psb_intel_crtc *psb_crtc = (crtc) ?
-					to_psb_intel_crtc(crtc) : NULL;
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 dspcntr_reg = DSPACNTR;
-
-	if (!dbi_output)
-		return;
-
-	/* FIXME check if can go */
-	dev_priv->is_in_idle = true;
-
-	gdbi_output = dbi_output;
-	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
-		return;
-
-	if (pipe == 2) {
-		dpll_reg = MRST_DPLL_A;
-		pipeconf_reg = PIPECCONF;
-		dspcntr_reg = DSPCCNTR;
-	}
-
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-	/* Disable te interrupts */
-	mdfld_disable_te(dev, pipe);
-
-	/* Disable plane */
-	reg_val = REG_READ(dspcntr_reg);
-	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
-		REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
-		REG_READ(dspcntr_reg);
-	}
-
-	/* Disable pipe */
-	reg_val = REG_READ(pipeconf_reg);
-	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
-		reg_val &= ~DISPLAY_PLANE_ENABLE;
-		reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF);
-		REG_WRITE(pipeconf_reg, reg_val);
-		REG_READ(pipeconf_reg);
-		mdfldWaitForPipeDisable(dev, pipe);
-	}
-
-	/* Disable DPLL */
-	reg_val = REG_READ(dpll_reg);
-	if (!(reg_val & DPLL_VCO_ENABLE)) {
-		reg_val &= ~DPLL_VCO_ENABLE;
-		REG_WRITE(dpll_reg, reg_val);
-		REG_READ(dpll_reg);
-		udelay(500);
-	}
-
-	gma_power_end(dev);
-	dbi_output->mode_flags |= MODE_SETTING_IN_DSR;
-	if (pipe == 2) {
-		enter_dsr = 1;
-		/* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
-	}
-}
-
-static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
-			int pipe)
-{
-	struct drm_device *dev = dbi_output->dev;
-	struct drm_crtc *crtc = dbi_output->base.base.crtc;
-	struct psb_intel_crtc *psb_crtc = (crtc) ?
-					to_psb_intel_crtc(crtc) : NULL;
-	u32 reg_val;
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 reg_offset = 0;
-
-	/*if mode setting on-going, back off*/
-	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
-		return;
-
-	if (pipe == 2) {
-		dpll_reg = MRST_DPLL_A;
-		pipeconf_reg = PIPECCONF;
-		dspcntr_reg = DSPCCNTR;
-		reg_offset = MIPIC_REG_OFFSET;
-	}
-
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-
-	/* Enable DPLL */
-	reg_val = REG_READ(dpll_reg);
-	if (!(reg_val & DPLL_VCO_ENABLE)) {
-		if (reg_val & MDFLD_PWR_GATE_EN) {
-			reg_val &= ~MDFLD_PWR_GATE_EN;
-			REG_WRITE(dpll_reg, reg_val);
-			REG_READ(dpll_reg);
-			udelay(500);
-		}
-
-		reg_val |= DPLL_VCO_ENABLE;
-		REG_WRITE(dpll_reg, reg_val);
-		REG_READ(dpll_reg);
-		udelay(500);
-
-		/* Add timeout */
-		while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
-			cpu_relax();
-	}
-
-	/* Enable pipe */
-	reg_val = REG_READ(pipeconf_reg);
-	if (!(reg_val & PIPEACONF_ENABLE)) {
-		reg_val |= PIPEACONF_ENABLE;
-		REG_WRITE(pipeconf_reg, reg_val);
-		REG_READ(pipeconf_reg);
-		udelay(500);
-		mdfldWaitForPipeEnable(dev, pipe);
-	}
-
-	/* Enable plane */
-	reg_val = REG_READ(dspcntr_reg);
-	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
-		reg_val |= DISPLAY_PLANE_ENABLE;
-		REG_WRITE(dspcntr_reg, reg_val);
-		REG_READ(dspcntr_reg);
-		udelay(500);
-	}
-
-	/* Enable TE interrupt on this pipe */
-	mdfld_enable_te(dev, pipe);
-	gma_power_end(dev);
-
-	/*clean IN_DSR flag*/
-	dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-}
-
-/*
- * Exit from DSR
- */
-void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-	struct mdfld_dsi_dbi_output **dbi_output;
-	int i;
-	int pipe;
-
-	/* FIXME can go ? */
-	dev_priv->is_in_idle = false;
-	dbi_output = dsr_info->dbi_outputs;
-
-#ifdef CONFIG_PM_RUNTIME
-	 if (!enable_gfx_rtpm) {
-/*                pm_runtime_allow(&gpDrmDevice->pdev->dev); */
-/*		schedule_delayed_work(&rtpm_work, 30 * 1000);*/ /* FIXME: HZ ? */
-	}
-#endif
-
-	/* For each output, exit dsr */
-	for (i = 0; i < dsr_info->dbi_output_num; i++) {
-		/* If panel has been turned off, skip */
-		if (!dbi_output[i] || !dbi_output[i]->dbi_panel_on)
-			continue;
-		pipe = dbi_output[i]->channel_num ? 2 : 0;
-		enter_dsr = 0;
-		mdfld_dbi_output_exit_dsr(dbi_output[i], pipe);
-	}
-	dev_priv->dsr_fb_update |= update_src;
-}
-
-static bool mdfld_dbi_is_in_dsr(struct drm_device *dev)
-{
-	if (REG_READ(MRST_DPLL_A) & DPLL_VCO_ENABLE)
-		return false;
-	if ((REG_READ(PIPEACONF) & PIPEACONF_ENABLE) ||
-	   (REG_READ(PIPECCONF) & PIPEACONF_ENABLE))
-		return false;
-	if ((REG_READ(DSPACNTR) & DISPLAY_PLANE_ENABLE) ||
-	   (REG_READ(DSPCCNTR) & DISPLAY_PLANE_ENABLE))
-		return false;
-
-	return true;
-}
-
-/* Periodically update dbi panel */
-void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-	struct mdfld_dsi_dbi_output **dbi_outputs;
-	struct mdfld_dsi_dbi_output *dbi_output;
-	int i;
-	int can_enter_dsr = 0;
-	u32 damage_mask;
-
-	dbi_outputs = dsr_info->dbi_outputs;
-	dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
-
-	if (!dbi_output)
-		return;
-
-	if (pipe == 0)
-		damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_0;
-	else if (pipe == 2)
-		damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_2;
-	else
-		return;
-
-	/* If FB is damaged and panel is on update on-panel FB */
-	if (damage_mask && dbi_output->dbi_panel_on) {
-		dbi_output->dsr_fb_update_done = false;
-
-		if (dbi_output->p_funcs->update_fb)
-			dbi_output->p_funcs->update_fb(dbi_output, pipe);
-
-		if (dev_priv->dsr_enable && dbi_output->dsr_fb_update_done)
-			dev_priv->dsr_fb_update &= ~damage_mask;
-
-		/*clean IN_DSR flag*/
-		dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-
-		dbi_output->dsr_idle_count = 0;
-	} else {
-		dbi_output->dsr_idle_count++;
-	}
-
-	switch (dsr_info->dbi_output_num) {
-	case 1:
-		if (dbi_output->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
-			can_enter_dsr = 1;
-		break;
-	case 2:
-		if (dbi_outputs[0]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT
-		   && dbi_outputs[1]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
-			can_enter_dsr = 1;
-		break;
-	default:
-		DRM_ERROR("Wrong DBI output number\n");
-	}
-
-	/* Try to enter DSR */
-	if (can_enter_dsr) {
-		for (i = 0; i < dsr_info->dbi_output_num; i++) {
-			if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] &&
-			   !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
-				mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
-					dbi_outputs[i]->channel_num ? 2 : 0);
-#if 0
-				enter_dsr = 1;
-				pr_err("%s: enter_dsr = 1\n", __func__);
-#endif
-			}
-		}
-	/*schedule rpm suspend after gfxrtdelay*/
-#ifdef CONFIG_GFX_RTPM
-		if (!dev_priv->rpm_enabled
-			|| !enter_dsr
-	/*		|| (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */
-			|| pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay))
-			dev_warn(dev->dev,
-				"Runtime PM schedule suspend failed, rpm %d\n",
-					dev_priv->rpm_enabled);
-#endif
-	}
-}
-
-int mdfld_dbi_dsr_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-
-	if (!dsr_info || IS_ERR(dsr_info)) {
-		dsr_info = kzalloc(sizeof(struct mdfld_dbi_dsr_info),
-								GFP_KERNEL);
-		if (!dsr_info) {
-			dev_err(dev->dev, "No memory\n");
-			return -ENOMEM;
-		}
-		dev_priv->dbi_dsr_info = dsr_info;
-	}
-	return 0;
-}
-
-void mdfld_dbi_dsr_exit(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-
-	if (dsr_info) {
-		kfree(dsr_info);
-		dev_priv->dbi_dsr_info = NULL;
-	}
-}
-
-void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
-								int pipe)
-{
-	struct drm_device *dev = dsi_config->dev;
-	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-	int lane_count = dsi_config->lane_count;
-	u32 val = 0;
-
-	dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
-
-	/* Un-ready device */
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
-	/* Init dsi adapter before kicking off */
-	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
-	/* TODO: figure out how to setup these registers */
-	REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-	REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
-							0x000a0014);
-	REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
-	REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
-	REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
-	/* Enable all interrupts */
-	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-	/* Max value: 20 clock cycles of txclkesc */
-	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
-	/* Min 21 txclkesc, max: ffffh */
-	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
-	/* Min: 7d0 max: 4e20 */
-	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
-	/* Set up func_prg */
-	val |= lane_count;
-	val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
-	val |= DSI_DBI_COLOR_FORMAT_OPTION2;
-	REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
-	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
-	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
-	/* De-assert dbi_stall when half of DBI FIFO is empty */
-	/* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
-
-	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-	REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-	REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-#if 0
-/*DBI encoder helper funcs*/
-static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
-	.dpms = mdfld_dsi_dbi_dpms,
-	.mode_fixup = mdfld_dsi_dbi_mode_fixup,
-	.prepare = mdfld_dsi_dbi_prepare,
-	.mode_set = mdfld_dsi_dbi_mode_set,
-	.commit = mdfld_dsi_dbi_commit,
-};
-
-/*DBI encoder funcs*/
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
-#endif
-
-/*
- * Init DSI DBI encoder.
- * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
- * return pointer of newly allocated DBI encoder, NULL on error
- */
-struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
-				struct mdfld_dsi_connector *dsi_connector,
-				struct panel_funcs *p_funcs)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dsi_dbi_output *dbi_output = NULL;
-	struct mdfld_dsi_config *dsi_config;
-	struct drm_connector *connector = NULL;
-	struct drm_encoder *encoder = NULL;
-	struct drm_display_mode *fixed_mode = NULL;
-	struct psb_gtt *pg = dev_priv ? (&dev_priv->gtt) : NULL;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL;
-	struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
-	u32 data = 0;
-	int pipe;
-	int ret;
-
-	if (!pg || !dsi_connector || !p_funcs) {
-		WARN_ON(1);
-		return NULL;
-	}
-
-	dsi_config = mdfld_dsi_get_config(dsi_connector);
-	pipe = dsi_connector->pipe;
-
-	/*panel hard-reset*/
-	if (p_funcs->reset) {
-		ret = p_funcs->reset(pipe);
-		if (ret) {
-			DRM_ERROR("Panel %d hard-reset failed\n", pipe);
-			return NULL;
-		}
-	}
-	/* Panel drvIC init */
-	if (p_funcs->drv_ic_init)
-		p_funcs->drv_ic_init(dsi_config, pipe);
-
-	/* Panel power mode detect */
-	ret = mdfld_dsi_get_power_mode(dsi_config,
-				       &data,
-				       MDFLD_DSI_HS_TRANSMISSION);
-	if (ret) {
-		DRM_ERROR("Panel %d get power mode failed\n", pipe);
-		dsi_connector->status = connector_status_disconnected;
-	} else {
-		DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
-		dsi_connector->status = connector_status_connected;
-	}
-
-	/*TODO: get panel info from DDB*/
-
-	dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL);
-	if (!dbi_output) {
-		dev_err(dev->dev, "No memory\n");
-		return NULL;
-	}
-
-	if (dsi_connector->pipe == 0) {
-		dbi_output->channel_num = 0;
-		dev_priv->dbi_output = dbi_output;
-	} else if (dsi_connector->pipe == 2) {
-		dbi_output->channel_num = 1;
-		dev_priv->dbi_output2 = dbi_output;
-	} else {
-		dev_err(dev->dev, "only support 2 DSI outputs\n");
-		goto out_err1;
-	}
-
-	dbi_output->dev = dev;
-	dbi_output->p_funcs = p_funcs;
-	fixed_mode = dsi_config->fixed_mode;
-	dbi_output->panel_fixed_mode = fixed_mode;
-
-	/* Create drm encoder object */
-	connector = &dsi_connector->base.base;
-	encoder = &dbi_output->base.base;
-	/* Review this if we ever get MIPI-HDMI bridges or similar */
-	drm_encoder_init(dev,
-			encoder,
-			p_funcs->encoder_funcs,
-			DRM_MODE_ENCODER_LVDS);
-	drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs);
-
-	/* Attach to given connector */
-	drm_mode_connector_attach_encoder(connector, encoder);
-
-	/* Set possible CRTCs and clones */
-	if (dsi_connector->pipe) {
-		encoder->possible_crtcs = (1 << 2);
-		encoder->possible_clones = (1 << 1);
-	} else {
-		encoder->possible_crtcs = (1 << 0);
-		encoder->possible_clones = (1 << 0);
-	}
-
-	dev_priv->dsr_fb_update = 0;
-	dev_priv->dsr_enable = false;
-	dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr;
-
-	dbi_output->first_boot = true;
-	dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
-
-	/* Add this output to dpu_info if in DPU mode */
-	if (dpu_info && dsi_connector->status == connector_status_connected) {
-		if (dsi_connector->pipe == 0)
-			dpu_info->dbi_outputs[0] = dbi_output;
-		else
-			dpu_info->dbi_outputs[1] = dbi_output;
-
-		dpu_info->dbi_output_num++;
-	} else if (dsi_connector->status == connector_status_connected) {
-		/* Add this output to dsr_info if not */
-		if (dsi_connector->pipe == 0)
-			dsr_info->dbi_outputs[0] = dbi_output;
-		else
-			dsr_info->dbi_outputs[1] = dbi_output;
-
-		dsr_info->dbi_output_num++;
-	}
-	return &dbi_output->base;
-out_err1:
-	kfree(dbi_output);
-	return NULL;
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.h b/drivers/staging/gma500/mdfld_dsi_dbi.h
deleted file mode 100644
index f0fa986..0000000
--- a/drivers/staging/gma500/mdfld_dsi_dbi.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#ifndef __MDFLD_DSI_DBI_H__
-#define __MDFLD_DSI_DBI_H__
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-/*
- * DBI encoder which inherits from mdfld_dsi_encoder
- */
-struct mdfld_dsi_dbi_output {
-	struct mdfld_dsi_encoder base;
-	struct drm_display_mode *panel_fixed_mode;
-	u8 last_cmd;
-	u8 lane_count;
-	u8 channel_num;
-	struct drm_device *dev;
-
-	/* Backlight operations */
-
-	/* DSR timer */
-	u32 dsr_idle_count;
-	bool dsr_fb_update_done;
-
-	/* Mode setting flags */
-	u32 mode_flags;
-
-	/* Panel status */
-	bool dbi_panel_on;
-	bool first_boot;
-	struct panel_funcs *p_funcs;
-
-	/* DPU */
-	u32 *dbi_cb_addr;
-	u32 dbi_cb_phy;
-	spinlock_t cb_lock;
-	u32 cb_write;
-};
-
-#define MDFLD_DSI_DBI_OUTPUT(dsi_encoder) \
-	container_of(dsi_encoder, struct mdfld_dsi_dbi_output, base)
-
-struct mdfld_dbi_dsr_info {
-	int dbi_output_num;
-	struct mdfld_dsi_dbi_output *dbi_outputs[2];
-
-	u32 dsr_idle_count;
-};
-
-#define DBI_CB_TIMEOUT_COUNT	0xffff
-
-/* Offsets */
-#define CMD_MEM_ADDR_OFFSET	0
-
-#define CMD_DATA_SRC_SYSTEM_MEM	0
-#define CMD_DATA_SRC_PIPE	1
-
-static inline int mdfld_dsi_dbi_fifo_ready(struct mdfld_dsi_dbi_output *dbi_output)
-{
-	struct drm_device *dev = dbi_output->dev;
-	u32 retry = DBI_CB_TIMEOUT_COUNT;
-	int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0;
-	int ret = 0;
-
-	/* Query the dbi fifo status*/
-	while (retry--) {
-		if (REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset) & (1 << 27))
-			break;
-	}
-
-	if (!retry) {
-		DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
-		ret = -EAGAIN;
-	}
-	return ret;
-}
-
-static inline int mdfld_dsi_dbi_cmd_sent(struct mdfld_dsi_dbi_output *dbi_output)
-{
-	struct drm_device *dev = dbi_output->dev;
-	u32 retry = DBI_CB_TIMEOUT_COUNT;
-	int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0;
-	int ret = 0;
-
-	/* Query the command execution status */
-	while (retry--)
-		if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 0)))
-			break;
-
-	if (!retry) {
-		DRM_ERROR("Timeout waiting for DBI command status\n");
-		ret = -EAGAIN;
-	}
-
-	return ret;
-}
-
-static inline int mdfld_dsi_dbi_cb_ready(struct mdfld_dsi_dbi_output *dbi_output)
-{
-	int ret = 0;
-
-	/* Query the command execution status*/
-	ret = mdfld_dsi_dbi_cmd_sent(dbi_output);
-	if (ret) {
-		DRM_ERROR("Peripheral is busy\n");
-		ret = -EAGAIN;
-	}
-	/* Query the dbi fifo status*/
-	ret = mdfld_dsi_dbi_fifo_ready(dbi_output);
-	if (ret) {
-		DRM_ERROR("DBI FIFO is not empty\n");
-		ret = -EAGAIN;
-	}
-	return ret;
-}
-
-extern void mdfld_dsi_dbi_output_init(struct drm_device *dev,
-			struct psb_intel_mode_device *mode_dev, int pipe);
-extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src);
-extern void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output,
-			int pipe);
-extern int mdfld_dbi_dsr_init(struct drm_device *dev);
-extern void mdfld_dbi_dsr_exit(struct drm_device *dev);
-extern struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
-			struct mdfld_dsi_connector *dsi_connector,
-			struct panel_funcs *p_funcs);
-extern int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
-			u8 dcs, u8 *param, u32 num, u8 data_src);
-extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
-			u16 x1, u16 y1, u16 x2, u16 y2);
-extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
-			int mode);
-extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
-			int pipe);
-
-#endif /*__MDFLD_DSI_DBI_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c
deleted file mode 100644
index a4e2ff4..0000000
--- a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * Copyright © 2010-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jim Liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_dbi.h"
-
-/*
- * NOTE: all mdlfd_x_damage funcs should be called by holding dpu_update_lock
- */
-
-static int mdfld_cursor_damage(struct mdfld_dbi_dpu_info *dpu_info,
-			   mdfld_plane_t plane,
-			   struct psb_drm_dpu_rect *damaged_rect)
-{
-	int x, y;
-	int new_x, new_y;
-	struct psb_drm_dpu_rect *rect;
-	struct psb_drm_dpu_rect *pipe_rect;
-	int cursor_size;
-	struct mdfld_cursor_info *cursor;
-	mdfld_plane_t fb_plane;
-
-	if (plane == MDFLD_CURSORA) {
-		cursor = &dpu_info->cursors[0];
-		x = dpu_info->cursors[0].x;
-		y = dpu_info->cursors[0].y;
-		cursor_size = dpu_info->cursors[0].size;
-		pipe_rect = &dpu_info->damage_pipea;
-		fb_plane = MDFLD_PLANEA;
-	} else {
-		cursor = &dpu_info->cursors[1];
-		x = dpu_info->cursors[1].x;
-		y = dpu_info->cursors[1].y;
-		cursor_size = dpu_info->cursors[1].size;
-		pipe_rect = &dpu_info->damage_pipec;
-		fb_plane = MDFLD_PLANEC;
-	}
-	new_x = damaged_rect->x;
-	new_y = damaged_rect->y;
-
-	if (x == new_x && y == new_y)
-		return 0;
-
-	rect = &dpu_info->damaged_rects[plane];
-	/* Move to right */
-	if (new_x >= x) {
-		if (new_y > y) {
-			rect->x = x;
-			rect->y = y;
-			rect->width = (new_x + cursor_size) - x;
-			rect->height = (new_y + cursor_size) - y;
-			goto cursor_out;
-		} else {
-			rect->x = x;
-			rect->y = new_y;
-			rect->width = (new_x + cursor_size) - x;
-			rect->height = (y - new_y);
-			goto cursor_out;
-		}
-	} else {
-		if (new_y > y) {
-			rect->x = new_x;
-			rect->y = y;
-			rect->width = (x + cursor_size) - new_x;
-			rect->height = new_y - y;
-			goto cursor_out;
-		} else {
-			rect->x = new_x;
-			rect->y = new_y;
-			rect->width = (x + cursor_size) - new_x;
-			rect->height = (y + cursor_size) - new_y;
-		}
-	}
-cursor_out:
-	if (new_x < 0)
-		cursor->x = 0;
-	else if (new_x > 864)
-		cursor->x = 864;
-	else
-		cursor->x = new_x;
-
-	if (new_y < 0)
-		cursor->y = 0;
-	else if (new_y > 480)
-		cursor->y = 480;
-	else
-		cursor->y = new_y;
-
-	/*
-	 * FIXME: this is a workaround for cursor plane update,
-	 * remove it later!
-	 */
-	rect->x = 0;
-	rect->y = 0;
-	rect->width = 864;
-	rect->height = 480;
-
-	mdfld_check_boundary(dpu_info, rect);
-	mdfld_dpu_region_extent(pipe_rect, rect);
-
-	/* Update pending status of dpu_info */
-	dpu_info->pending |= (1 << plane);
-	/* Update fb panel as well */
-	dpu_info->pending |= (1 << fb_plane);
-	return 0;
-}
-
-static int mdfld_fb_damage(struct mdfld_dbi_dpu_info *dpu_info,
-				   mdfld_plane_t plane,
-				   struct psb_drm_dpu_rect *damaged_rect)
-{
-	struct psb_drm_dpu_rect *rect;
-
-	if (plane == MDFLD_PLANEA)
-		rect = &dpu_info->damage_pipea;
-	else
-		rect = &dpu_info->damage_pipec;
-
-	mdfld_check_boundary(dpu_info, damaged_rect);
-
-	/* Add fb damage area to this pipe */
-	mdfld_dpu_region_extent(rect, damaged_rect);
-
-	/* Update pending status of dpu_info */
-	dpu_info->pending |= (1 << plane);
-	return 0;
-}
-
-/* Do nothing here, right now */
-static int mdfld_overlay_damage(struct mdfld_dbi_dpu_info *dpu_info,
-				mdfld_plane_t plane,
-				struct psb_drm_dpu_rect *damaged_rect)
-{
-	return 0;
-}
-
-int mdfld_dbi_dpu_report_damage(struct drm_device *dev,
-				mdfld_plane_t plane,
-				struct psb_drm_dpu_rect *rect)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-	int ret = 0;
-
-	/* DPU not in use, no damage reporting needed */
-	if (dpu_info == NULL)
-		return 0;
-
-	spin_lock(&dpu_info->dpu_update_lock);
-
-	switch (plane) {
-	case MDFLD_PLANEA:
-	case MDFLD_PLANEC:
-		mdfld_fb_damage(dpu_info, plane, rect);
-		break;
-	case MDFLD_CURSORA:
-	case MDFLD_CURSORC:
-		mdfld_cursor_damage(dpu_info, plane, rect);
-		break;
-	case MDFLD_OVERLAYA:
-	case MDFLD_OVERLAYC:
-		mdfld_overlay_damage(dpu_info, plane, rect);
-		break;
-	default:
-		DRM_ERROR("Invalid plane type %d\n", plane);
-		ret = -EINVAL;
-	}
-	spin_unlock(&dpu_info->dpu_update_lock);
-	return ret;
-}
-
-int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv;
-	struct mdfld_dbi_dpu_info *dpu_info;
-	struct mdfld_dsi_config  *dsi_config;
-	struct psb_drm_dpu_rect rect;
-	int i;
-
-	if (!dev) {
-		DRM_ERROR("Invalid parameter\n");
-		return -EINVAL;
-	}
-
-	dev_priv = dev->dev_private;
-	dpu_info = dev_priv->dbi_dpu_info;
-
-	/* This is fine - we may be in non DPU mode */
-	if (!dpu_info)
-		return -EINVAL;
-
-	for (i = 0; i < dpu_info->dbi_output_num; i++) {
-		dsi_config = dev_priv->dsi_configs[i];
-		if (dsi_config) {
-			rect.x = rect.y = 0;
-			rect.width = dsi_config->fixed_mode->hdisplay;
-			rect.height = dsi_config->fixed_mode->vdisplay;
-			mdfld_dbi_dpu_report_damage(dev,
-				    i ? (MDFLD_PLANEC) : (MDFLD_PLANEA),
-				    &rect);
-		}
-	}
-	/* Exit DSR state */
-	mdfld_dpu_exit_dsr(dev);
-	return 0;
-}
-
-int mdfld_dsi_dbi_dsr_off(struct drm_device *dev,
-					struct psb_drm_dpu_rect *rect)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
-	mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, rect);
-
-	/* If dual display mode */
-	if (dpu_info->dbi_output_num == 2)
-		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, rect);
-
-	/* Force dsi to exit DSR mode */
-	mdfld_dpu_exit_dsr(dev);
-	return 0;
-}
-
-static void mdfld_dpu_cursor_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
-						 mdfld_plane_t plane)
-{
-	struct drm_device *dev = dpu_info->dev;
-	u32 curpos_reg = CURAPOS;
-	u32 curbase_reg = CURABASE;
-	u32 curcntr_reg = CURACNTR;
-	struct mdfld_cursor_info *cursor = &dpu_info->cursors[0];
-
-	if (plane == MDFLD_CURSORC) {
-		curpos_reg = CURCPOS;
-		curbase_reg = CURCBASE;
-		curcntr_reg = CURCCNTR;
-		cursor = &dpu_info->cursors[1];
-	}
-
-	REG_WRITE(curcntr_reg, REG_READ(curcntr_reg));
-	REG_WRITE(curpos_reg,
-		(((cursor->x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) |
-		((cursor->y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT)));
-	REG_WRITE(curbase_reg, REG_READ(curbase_reg));
-}
-
-static void mdfld_dpu_fb_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
-						 mdfld_plane_t plane)
-{
-	u32 pipesrc_reg = PIPEASRC;
-	u32 dspsize_reg = DSPASIZE;
-	u32 dspoff_reg = DSPALINOFF;
-	u32 dspsurf_reg = DSPASURF;
-	u32 dspstride_reg = DSPASTRIDE;
-	u32 stride;
-	struct psb_drm_dpu_rect *rect = &dpu_info->damage_pipea;
-	struct drm_device *dev = dpu_info->dev;
-
-	if (plane == MDFLD_PLANEC) {
-		pipesrc_reg = PIPECSRC;
-		dspsize_reg = DSPCSIZE;
-		dspoff_reg = DSPCLINOFF;
-		dspsurf_reg = DSPCSURF;
-		dspstride_reg = DSPCSTRIDE;
-		rect = &dpu_info->damage_pipec;
-	}
-
-	stride = REG_READ(dspstride_reg);
-	/* FIXME: should I do the pipe src update here? */
-	REG_WRITE(pipesrc_reg, ((rect->width - 1) << 16) | (rect->height - 1));
-	/* Flush plane */
-	REG_WRITE(dspsize_reg, ((rect->height - 1) << 16) | (rect->width - 1));
-	REG_WRITE(dspoff_reg, ((rect->x * 4) + (rect->y * stride)));
-	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
-
-	/*
-	 * TODO: wait for flip finished and restore the pipesrc reg,
-	 * or cursor will be show at a wrong position
-	 */
-}
-
-static void mdfld_dpu_overlay_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
-						  mdfld_plane_t plane)
-{
-}
-
-/*
- * TODO: we are still in dbi normal mode now, we will try to use partial
- * mode later.
- */
-static int mdfld_dbi_prepare_cb(struct mdfld_dsi_dbi_output *dbi_output,
-				struct mdfld_dbi_dpu_info *dpu_info, int pipe)
-{
-	u8 *cb_addr = (u8 *)dbi_output->dbi_cb_addr;
-	u32 *index;
-	struct psb_drm_dpu_rect *rect = pipe ?
-		(&dpu_info->damage_pipec) : (&dpu_info->damage_pipea);
-
-	/* FIXME: lock command buffer, this may lead to a deadlock,
-	   as we already hold the dpu_update_lock */
-	if (!spin_trylock(&dbi_output->cb_lock)) {
-		DRM_ERROR("lock command buffer failed, try again\n");
-		return -EAGAIN;
-	}
-
-	index = &dbi_output->cb_write;
-
-	if (*index) {
-		DRM_ERROR("DBI command buffer unclean\n");
-		return -EAGAIN;
-	}
-
-	/* Column address */
-	*(cb_addr + ((*index)++)) = set_column_address;
-	*(cb_addr + ((*index)++)) = rect->x >> 8;
-	*(cb_addr + ((*index)++)) = rect->x;
-	*(cb_addr + ((*index)++)) = (rect->x + rect->width - 1) >> 8;
-	*(cb_addr + ((*index)++)) = (rect->x + rect->width - 1);
-
-	*index = 8;
-
-	/* Page address */
-	*(cb_addr + ((*index)++)) = set_page_addr;
-	*(cb_addr + ((*index)++)) = rect->y >> 8;
-	*(cb_addr + ((*index)++)) = rect->y;
-	*(cb_addr + ((*index)++)) = (rect->y + rect->height - 1) >> 8;
-	*(cb_addr + ((*index)++)) = (rect->y + rect->height - 1);
-
-	*index = 16;
-
-	/*write memory*/
-	*(cb_addr + ((*index)++)) = write_mem_start;
-
-	return 0;
-}
-
-static int mdfld_dbi_flush_cb(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
-{
-	u32 cmd_phy = dbi_output->dbi_cb_phy;
-	u32 *index = &dbi_output->cb_write;
-	int reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-	struct drm_device *dev = dbi_output->dev;
-
-	if (*index == 0 || !dbi_output)
-		return 0;
-
-	REG_WRITE((MIPIA_CMD_LEN_REG + reg_offset), 0x010505);
-	REG_WRITE((MIPIA_CMD_ADD_REG + reg_offset), cmd_phy | 3);
-
-	*index = 0;
-
-	/* FIXME: unlock command buffer */
-	spin_unlock(&dbi_output->cb_lock);
-	return 0;
-}
-
-static int mdfld_dpu_update_pipe(struct mdfld_dsi_dbi_output *dbi_output,
-				 struct mdfld_dbi_dpu_info *dpu_info, int pipe)
-{
-	struct drm_device *dev =  dbi_output->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	mdfld_plane_t cursor_plane = MDFLD_CURSORA;
-	mdfld_plane_t fb_plane = MDFLD_PLANEA;
-	mdfld_plane_t overlay_plane = MDFLD_OVERLAYA;
-	int ret = 0;
-	u32 plane_mask = MDFLD_PIPEA_PLANE_MASK;
-
-	/* Damaged rects on this pipe */
-	if (pipe) {
-		cursor_plane = MDFLD_CURSORC;
-		fb_plane = MDFLD_PLANEC;
-		overlay_plane = MDFLD_OVERLAYC;
-		plane_mask = MDFLD_PIPEC_PLANE_MASK;
-	}
-
-	/*update cursor which assigned to @pipe*/
-	if (dpu_info->pending & (1 << cursor_plane))
-		mdfld_dpu_cursor_plane_flush(dpu_info, cursor_plane);
-
-	/*update fb which assigned to @pipe*/
-	if (dpu_info->pending & (1 << fb_plane))
-		mdfld_dpu_fb_plane_flush(dpu_info, fb_plane);
-
-	/* TODO: update overlay */
-	if (dpu_info->pending & (1 << overlay_plane))
-		mdfld_dpu_overlay_plane_flush(dpu_info, overlay_plane);
-
-	/* Flush damage area to panel fb */
-	if (dpu_info->pending & plane_mask) {
-		ret = mdfld_dbi_prepare_cb(dbi_output, dpu_info, pipe);
-		/*
-		 * TODO: remove b_dsr_enable later,
-		 * added it so that text console could boot smoothly
-		 */
-		/* Clean pending flags on this pipe */
-		if (!ret && dev_priv->dsr_enable) {
-			dpu_info->pending &= ~plane_mask;
-			/* Reset overlay pipe damage rect */
-			mdfld_dpu_init_damage(dpu_info, pipe);
-		}
-	}
-	return ret;
-}
-
-static int mdfld_dpu_update_fb(struct drm_device *dev)
-{
-	struct drm_crtc *crtc;
-	struct psb_intel_crtc *psb_crtc;
-	struct mdfld_dsi_dbi_output **dbi_output;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-	bool pipe_updated[2];
-	unsigned long irq_flags;
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 dsplinoff_reg = DSPALINOFF;
-	u32 dspsurf_reg = DSPASURF;
-	u32 mipi_state_reg = MIPIA_INTR_STAT_REG;
-	u32 reg_offset = 0;
-	int pipe;
-	int i;
-	int ret;
-
-	dbi_output = dpu_info->dbi_outputs;
-	pipe_updated[0] = pipe_updated[1] = false;
-
-	if (!gma_power_begin(dev, true))
-		return -EAGAIN;
-
-	/* Try to prevent any new damage reports */
-	if (!spin_trylock_irqsave(&dpu_info->dpu_update_lock, irq_flags))
-		return -EAGAIN;
-
-	for (i = 0; i < dpu_info->dbi_output_num; i++) {
-		crtc = dbi_output[i]->base.base.crtc;
-		psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL;
-
-		pipe = dbi_output[i]->channel_num ? 2 : 0;
-
-		if (pipe == 2) {
-			dspcntr_reg = DSPCCNTR;
-			pipeconf_reg = PIPECCONF;
-			dsplinoff_reg = DSPCLINOFF;
-			dspsurf_reg = DSPCSURF;
-			reg_offset = MIPIC_REG_OFFSET;
-		}
-
-		if (!(REG_READ((MIPIA_GEN_FIFO_STAT_REG + reg_offset))
-							& (1 << 27)) ||
-			!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
-			!(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
-			!(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
-			dev_err(dev->dev,
-				"DBI FIFO is busy, DSI %d state %x\n",
-				pipe,
-				REG_READ(mipi_state_reg + reg_offset));
-			continue;
-		}
-
-		/*
-		 *	If DBI output is in a exclusive state then the pipe
-		 *	change won't be updated
-		 */
-		if (dbi_output[i]->dbi_panel_on &&
-		   !(dbi_output[i]->mode_flags & MODE_SETTING_ON_GOING) &&
-		   !(psb_crtc &&
-			psb_crtc->mode_flags & MODE_SETTING_ON_GOING) &&
-		   !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
-			ret = mdfld_dpu_update_pipe(dbi_output[i],
-				dpu_info, dbi_output[i]->channel_num ? 2 : 0);
-			if (!ret)
-				pipe_updated[i] = true;
-		}
-	}
-
-	for (i = 0; i < dpu_info->dbi_output_num; i++)
-		if (pipe_updated[i])
-			mdfld_dbi_flush_cb(dbi_output[i],
-				dbi_output[i]->channel_num ? 2 : 0);
-
-	spin_unlock_irqrestore(&dpu_info->dpu_update_lock, irq_flags);
-	gma_power_end(dev);
-	return 0;
-}
-
-static int __mdfld_dbi_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
-								int pipe)
-{
-	struct drm_device *dev = dbi_output->dev;
-	struct drm_crtc *crtc = dbi_output->base.base.crtc;
-	struct psb_intel_crtc *psb_crtc = (crtc) ? to_psb_intel_crtc(crtc)
-								: NULL;
-	u32 reg_val;
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 dspbase_reg = DSPABASE;
-	u32 dspsurf_reg = DSPASURF;
-	u32 reg_offset = 0;
-
-	if (!dbi_output)
-		return 0;
-
-	/* If mode setting on-going, back off */
-	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
-		return -EAGAIN;
-
-	if (pipe == 2) {
-		dpll_reg = MRST_DPLL_A;
-		pipeconf_reg = PIPECCONF;
-		dspcntr_reg = DSPCCNTR;
-		dspbase_reg = MDFLD_DSPCBASE;
-		dspsurf_reg = DSPCSURF;
-
-		reg_offset = MIPIC_REG_OFFSET;
-	}
-
-	if (!gma_power_begin(dev, true))
-		return -EAGAIN;
-
-	/* Enable DPLL */
-	reg_val = REG_READ(dpll_reg);
-	if (!(reg_val & DPLL_VCO_ENABLE)) {
-
-		if (reg_val & MDFLD_PWR_GATE_EN) {
-			reg_val &= ~MDFLD_PWR_GATE_EN;
-			REG_WRITE(dpll_reg, reg_val);
-			REG_READ(dpll_reg);
-			udelay(500);
-		}
-
-		reg_val |= DPLL_VCO_ENABLE;
-		REG_WRITE(dpll_reg, reg_val);
-		REG_READ(dpll_reg);
-		udelay(500);
-
-		/* FIXME: add timeout */
-		while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
-			cpu_relax();
-	}
-
-	/* Enable pipe */
-	reg_val = REG_READ(pipeconf_reg);
-	if (!(reg_val & PIPEACONF_ENABLE)) {
-		reg_val |= PIPEACONF_ENABLE;
-		REG_WRITE(pipeconf_reg, reg_val);
-		REG_READ(pipeconf_reg);
-		udelay(500);
-		mdfldWaitForPipeEnable(dev, pipe);
-	}
-
-	/* Enable plane */
-	reg_val = REG_READ(dspcntr_reg);
-	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
-		reg_val |= DISPLAY_PLANE_ENABLE;
-		REG_WRITE(dspcntr_reg, reg_val);
-		REG_READ(dspcntr_reg);
-		udelay(500);
-	}
-
-	gma_power_end(dev);
-
-	/* Clean IN_DSR flag */
-	dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
-
-	return 0;
-}
-
-int mdfld_dpu_exit_dsr(struct drm_device *dev)
-{
-	struct mdfld_dsi_dbi_output **dbi_output;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-	int i;
-	int pipe;
-
-	dbi_output = dpu_info->dbi_outputs;
-
-	for (i = 0; i < dpu_info->dbi_output_num; i++) {
-		/* If this output is not in DSR mode, don't call exit dsr */
-		if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)
-			__mdfld_dbi_exit_dsr(dbi_output[i],
-					dbi_output[i]->channel_num ? 2 : 0);
-	}
-
-	/* Enable TE interrupt */
-	for (i = 0; i < dpu_info->dbi_output_num; i++) {
-		/* If this output is not in DSR mode, don't call exit dsr */
-		pipe = dbi_output[i]->channel_num ? 2 : 0;
-		if (dbi_output[i]->dbi_panel_on && pipe) {
-			mdfld_disable_te(dev, 0);
-			mdfld_enable_te(dev, 2);
-		} else if (dbi_output[i]->dbi_panel_on && !pipe) {
-			mdfld_disable_te(dev, 2);
-			mdfld_enable_te(dev, 0);
-		}
-	}
-	return 0;
-}
-
-static int mdfld_dpu_enter_dsr(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-	struct mdfld_dsi_dbi_output **dbi_output;
-	int i;
-
-	dbi_output = dpu_info->dbi_outputs;
-
-	for (i = 0; i < dpu_info->dbi_output_num; i++) {
-		/* If output is off or already in DSR state, don't re-enter */
-		if (dbi_output[i]->dbi_panel_on &&
-		   !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
-			mdfld_dsi_dbi_enter_dsr(dbi_output[i],
-				dbi_output[i]->channel_num ? 2 : 0);
-		}
-	}
-
-	return 0;
-}
-
-static void mdfld_dbi_dpu_timer_func(unsigned long data)
-{
-	struct drm_device *dev = (struct drm_device *)data;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-	struct timer_list *dpu_timer = &dpu_info->dpu_timer;
-	unsigned long flags;
-
-	if (dpu_info->pending) {
-		dpu_info->idle_count = 0;
-		/* Update panel fb with damaged area */
-		mdfld_dpu_update_fb(dev);
-	} else {
-		dpu_info->idle_count++;
-	}
-
-	if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) {
-		mdfld_dpu_enter_dsr(dev);
-		/* Stop timer by return */
-		return;
-	}
-
-	spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
-	if (!timer_pending(dpu_timer)) {
-		dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
-		add_timer(dpu_timer);
-	}
-	spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-}
-
-void mdfld_dpu_update_panel(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
-	if (dpu_info->pending) {
-		dpu_info->idle_count = 0;
-
-		/*update panel fb with damaged area*/
-		mdfld_dpu_update_fb(dev);
-	} else {
-		dpu_info->idle_count++;
-	}
-
-	if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) {
-		/*enter dsr*/
-		mdfld_dpu_enter_dsr(dev);
-	}
-}
-
-static int mdfld_dbi_dpu_timer_init(struct drm_device *dev,
-				struct mdfld_dbi_dpu_info *dpu_info)
-{
-	struct timer_list *dpu_timer = &dpu_info->dpu_timer;
-	unsigned long flags;
-
-	spin_lock_init(&dpu_info->dpu_timer_lock);
-	spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
-
-	init_timer(dpu_timer);
-
-	dpu_timer->data = (unsigned long)dev;
-	dpu_timer->function = mdfld_dbi_dpu_timer_func;
-	dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
-
-	spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-
-	return 0;
-}
-
-void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info)
-{
-	struct timer_list *dpu_timer = &dpu_info->dpu_timer;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
-	if (!timer_pending(dpu_timer)) {
-		dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
-		add_timer(dpu_timer);
-	}
-	spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
-}
-
-int mdfld_dbi_dpu_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
-	if (!dpu_info || IS_ERR(dpu_info)) {
-		dpu_info = kzalloc(sizeof(struct mdfld_dbi_dpu_info),
-								GFP_KERNEL);
-		if (!dpu_info) {
-			DRM_ERROR("No memory\n");
-			return -ENOMEM;
-		}
-		dev_priv->dbi_dpu_info = dpu_info;
-	}
-
-	dpu_info->dev = dev;
-
-	dpu_info->cursors[0].size = MDFLD_CURSOR_SIZE;
-	dpu_info->cursors[1].size = MDFLD_CURSOR_SIZE;
-
-	/*init dpu_update_lock*/
-	spin_lock_init(&dpu_info->dpu_update_lock);
-
-	/*init dpu refresh timer*/
-	mdfld_dbi_dpu_timer_init(dev, dpu_info);
-
-	/*init pipe damage area*/
-	mdfld_dpu_init_damage(dpu_info, 0);
-	mdfld_dpu_init_damage(dpu_info, 2);
-
-	return 0;
-}
-
-void mdfld_dbi_dpu_exit(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-
-	if (!dpu_info)
-		return;
-
-	del_timer_sync(&dpu_info->dpu_timer);
-	kfree(dpu_info);
-	dev_priv->dbi_dpu_info = NULL;
-}
-
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
deleted file mode 100644
index 42367ed..0000000
--- a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#ifndef __MDFLD_DSI_DBI_DPU_H__
-#define __MDFLD_DSI_DBI_DPU_H__
-
-#include "mdfld_dsi_dbi.h"
-
-typedef enum {
-	MDFLD_PLANEA,
-	MDFLD_PLANEC,
-	MDFLD_CURSORA,
-	MDFLD_CURSORC,
-	MDFLD_OVERLAYA,
-	MDFLD_OVERLAYC,
-	MDFLD_PLANE_NUM,
-} mdfld_plane_t;
-
-#define MDFLD_PIPEA_PLANE_MASK	0x15
-#define MDFLD_PIPEC_PLANE_MASK	0x2A
-
-struct mdfld_cursor_info {
-	int x, y;
-	int size;
-};
-
-#define MDFLD_CURSOR_SIZE	64
-
-/*
- * enter DSR mode if screen has no update for 2 frames.
- */
-#define MDFLD_MAX_IDLE_COUNT	2
-
-struct mdfld_dbi_dpu_info {
-	struct drm_device *dev;
-	/* Lock */
-	spinlock_t dpu_update_lock;
-
-	/* Cursor postion */
-	struct mdfld_cursor_info cursors[2];
-
-	/* Damaged area for each plane */
-	struct psb_drm_dpu_rect damaged_rects[MDFLD_PLANE_NUM];
-
-	/* Final damaged area */
-	struct psb_drm_dpu_rect damage_pipea;
-	struct psb_drm_dpu_rect damage_pipec;
-
-	/* Pending */
-	u32 pending;
-
-	/* DPU timer */
-	struct timer_list dpu_timer;
-	spinlock_t dpu_timer_lock;
-
-	/* DPU idle count */
-	u32 idle_count;
-
-	/* DSI outputs */
-	struct mdfld_dsi_dbi_output *dbi_outputs[2];
-	int dbi_output_num;
-};
-
-static inline int mdfld_dpu_region_extent(struct psb_drm_dpu_rect *origin,
-			 struct psb_drm_dpu_rect *rect)
-{
-	int x1, y1, x2, y2;
-
-	x1 = origin->x + origin->width;
-	y1 = origin->y + origin->height;
-
-	x2 = rect->x + rect->width;
-	y2 = rect->y + rect->height;
-
-	origin->x = min(origin->x, rect->x);
-	origin->y = min(origin->y, rect->y);
-	origin->width = max(x1, x2) - origin->x;
-	origin->height = max(y1, y2) - origin->y;
-
-	return 0;
-}
-
-static inline void mdfld_check_boundary(struct mdfld_dbi_dpu_info *dpu_info,
-				struct psb_drm_dpu_rect *rect)
-{
-	if (rect->x < 0)
-		rect->x = 0;
-	if (rect->y < 0)
-		rect->y = 0;
-
-	if (rect->x + rect->width > 864)
-		rect->width = 864 - rect->x;
-	if (rect->y + rect->height > 480)
-		rect->height = 480 - rect->height;
-
-	if (!rect->width)
-		rect->width = 1;
-	if (!rect->height)
-		rect->height = 1;
-}
-
-static inline void mdfld_dpu_init_damage(struct mdfld_dbi_dpu_info *dpu_info,
-				int pipe)
-{
-	struct psb_drm_dpu_rect *rect;
-
-	if (pipe == 0)
-		rect = &dpu_info->damage_pipea;
-	else
-		rect = &dpu_info->damage_pipec;
-
-	rect->x = 864;
-	rect->y = 480;
-	rect->width = -864;
-	rect->height = -480;
-}
-
-extern int mdfld_dsi_dbi_dsr_off(struct drm_device *dev,
-				struct psb_drm_dpu_rect *rect);
-extern int mdfld_dbi_dpu_report_damage(struct drm_device *dev,
-				mdfld_plane_t plane,
-				struct psb_drm_dpu_rect *rect);
-extern int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev);
-extern int mdfld_dpu_exit_dsr(struct drm_device *dev);
-extern void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info);
-extern int mdfld_dbi_dpu_init(struct drm_device *dev);
-extern void mdfld_dbi_dpu_exit(struct drm_device *dev);
-extern void mdfld_dpu_update_panel(struct drm_device *dev);
-
-#endif /*__MDFLD_DSI_DBI_DPU_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.c b/drivers/staging/gma500/mdfld_dsi_dpi.c
deleted file mode 100644
index e685f12..0000000
--- a/drivers/staging/gma500/mdfld_dsi_dpi.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-
-static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
-{
-	u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
-	int timeout = 0;
-
-	if (pipe == 2)
-		gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
-	udelay(500);
-
-	/* This will time out after approximately 2+ seconds */
-	while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) {
-		udelay(100);
-		timeout++;
-	}
-
-	if (timeout == 20000)
-		dev_warn(dev->dev, "MIPI: HS Data FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
-{
-	u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
-	int timeout = 0;
-
-	if (pipe == 2)
-		gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
-	udelay(500);
-
-	/* This will time out after approximately 2+ seconds */
-	while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_CTRL_FULL)) {
-		udelay(100);
-		timeout++;
-	}
-	if (timeout == 20000)
-		dev_warn(dev->dev, "MIPI: HS CMD FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
-{
-	u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
-        int timeout = 0;
-
-	if (pipe == 2)
-		gen_fifo_stat_reg += MIPIC_REG_OFFSET;
-
-        udelay(500);
-
-        /* This will time out after approximately 2+ seconds */
-        while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & DPI_FIFO_EMPTY)
-                                                        != DPI_FIFO_EMPTY)) {
-                udelay(100);
-                timeout++;
-        }
-
-        if (timeout == 20000)
-                dev_warn(dev->dev, "MIPI: DPI FIFO was never cleared!\n");
-}
-
-static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
-{
-	u32 intr_stat_reg = MIPIA_INTR_STAT_REG;
-	int timeout = 0;
-
-	if (pipe == 2)
-		intr_stat_reg += MIPIC_REG_OFFSET;
-
-        udelay(500);
-
-        /* This will time out after approximately 2+ seconds */
-        while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) & DSI_INTR_STATE_SPL_PKG_SENT))) {
-                udelay(100);
-                timeout++;
-        }
-
-        if (timeout == 20000)
-                dev_warn(dev->dev, "MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
-}
-
-
-/* ************************************************************************* *\
- * FUNCTION: mdfld_dsi_tpo_ic_init
- *
- * DESCRIPTION:  This function is called only by mrst_dsi_mode_set and
- *               restore_display_registers.  since this function does not
- *               acquire the mutex, it is important that the calling function
- *               does!
-\* ************************************************************************* */
-void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe)
-{
-	struct drm_device *dev = dsi_config->dev;
-	u32 dcsChannelNumber = dsi_config->channel_num;
-	u32 gen_data_reg = MIPIA_HS_GEN_DATA_REG; 
-	u32 gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
-	u32 gen_ctrl_val = GEN_LONG_WRITE;
-
-	if (pipe == 2) {
-		gen_data_reg = HS_GEN_DATA_REG + MIPIC_REG_OFFSET; 
-		gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
-	}
-
-	gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS;
-
-	/* Flip page order */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x00008036);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
-
-	/* 0xF0 */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x005a5af0);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
-	/* Write protection key */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x005a5af1);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
-	/* 0xFC */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x005a5afc);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
-	/* 0xB7 */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x770000b7);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x00000044);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS));
-
-	/* 0xB6 */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x000a0ab6);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-
-	/* 0xF2 */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x081010f2);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x4a070708);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x000000c5);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
-	/* 0xF8 */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x024003f8);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x01030a04);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x0e020220);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x00000004);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS));
-
-	/* 0xE2 */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x398fc3e2);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x0000916f);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS));
-
-	/* 0xB0 */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x000000b0);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
-
-	/* 0xF4 */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x240242f4);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x78ee2002);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x2a071050);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x507fee10);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x10300710);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS));
-
-	/* 0xBA */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x19fe07ba);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x101c0a31);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x00000010);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
-	/* 0xBB */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x28ff07bb);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x24280a31);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x00000034);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
-
-	/* 0xFB */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x535d05fb);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x1b1a2130);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x221e180e);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x131d2120);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x535d0508);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x1c1a2131);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x231f160d);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x111b2220);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x535c2008);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x1f1d2433);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x2c251a10);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x2c34372d);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x00000023);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
-
-	/* 0xFA */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x525c0bfa);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x1c1c232f);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x2623190e);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x18212625);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x545d0d0e);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x1e1d2333);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x26231a10);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x1a222725);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x545d280f);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x21202635);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x31292013);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x31393d33);
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x00000029);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
-
-	/* Set DM */
-	mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
-	REG_WRITE(gen_data_reg, 0x000100f7);
-	mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
-	REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
-}
-
-static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count,
-						int num_lane, int bpp)
-{
-	return (u16)((pixel_clock_count * bpp) / (num_lane * 8)); 
-}
-
-/*
- * Calculate the dpi time basing on a given drm mode @mode
- * return 0 on success.
- * FIXME: I was using proposed mode value for calculation, may need to 
- * use crtc mode values later 
- */
-int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, 
-			struct mdfld_dsi_dpi_timing *dpi_timing,
-			int num_lane, int bpp)
-{
-	int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive;
-	int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive;
-	
-	if(!mode || !dpi_timing) {
-		DRM_ERROR("Invalid parameter\n");
-		return -EINVAL;
-	}
-	
-	pclk_hactive = mode->hdisplay;
-	pclk_hfp = mode->hsync_start - mode->hdisplay;
-	pclk_hsync = mode->hsync_end - mode->hsync_start;
-	pclk_hbp = mode->htotal - mode->hsync_end;
-	
-	pclk_vactive = mode->vdisplay;
-	pclk_vfp = mode->vsync_start - mode->vdisplay;
-	pclk_vsync = mode->vsync_end - mode->vsync_start;
-	pclk_vbp = mode->vtotal - mode->vsync_end;
-
-	/*
-	 * byte clock counts were calculated by following formula
-	 * bclock_count = pclk_count * bpp / num_lane / 8
-	 */
-	dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hsync, num_lane, bpp);
-	dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hbp, num_lane, bpp);
-	dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hfp, num_lane, bpp);
-	dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hactive, num_lane, bpp);
-	dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vsync, num_lane, bpp);
-	dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vbp, num_lane, bpp);
-	dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vfp, num_lane, bpp);
-
-	return 0; 
-}
-
-void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
-	struct drm_device *dev = dsi_config->dev;
-	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-	int lane_count = dsi_config->lane_count;
-	struct mdfld_dsi_dpi_timing dpi_timing;
-	struct drm_display_mode *mode = dsi_config->mode;
-	u32 val = 0;
-	
-	/*un-ready device*/
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-	
-	/*init dsi adapter before kicking off*/
-	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-	
-	/*enable all interrupts*/
-	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-	
-
-	/*set up func_prg*/
-	val |= lane_count;
-	val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
-		
-	switch(dsi_config->bpp) {
-	case 16:
-		val |= DSI_DPI_COLOR_FORMAT_RGB565;
-		break;
-	case 18:
-		val |= DSI_DPI_COLOR_FORMAT_RGB666;
-		break;
-	case 24:
-		val |= DSI_DPI_COLOR_FORMAT_RGB888;
-		break;
-	default:
-		DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
-	}
-	REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-	
-	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 
-			(mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
-	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
-	
-	/*max value: 20 clock cycles of txclkesc*/
-	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
-	
-	/*min 21 txclkesc, max: ffffh*/
-	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
-
-	REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
-	
-	/*set DPI timing registers*/
-	mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
-	
-	REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
-	
-	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-	
-	/*min: 7d0 max: 4e20*/
-	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
-	
-	/*set up video mode*/
-	val = 0;
-	val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
-	REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
-	
-	REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-	
-	REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-	
-	/*TODO: figure out how to setup these registers*/
-	REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-	
-	REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
-	/*set device ready*/
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe)
-{
-	struct drm_device *dev = output->dev;
-	u32 reg_offset = 0;
-	
-	if(output->panel_on) 
-		return;
-		
-	if(pipe) 
-		reg_offset = MIPIC_REG_OFFSET;
-
-	/* clear special packet sent bit */
-	if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-		REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
-	}
-		
-	/*send turn on package*/
-	REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
-	
-	/*wait for SPL_PKG_SENT interrupt*/
-	mdfld_wait_for_SPL_PKG_SENT(dev, pipe);
-	
-	if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-		REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
-	}
-
-	output->panel_on = 1;
-
-	/* FIXME the following is disabled to WA the X slow start issue for TMD panel */
-	/* if(pipe == 2) */
-	/* 	dev_priv->dpi_panel_on2 = true; */
-	/* else if (pipe == 0) */
-	/* 	dev_priv->dpi_panel_on = true; */
-}
-
-static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe)
-{
-	struct drm_device *dev = output->dev;
-	u32 reg_offset = 0;
-	
-	/*if output is on, or mode setting didn't happen, ignore this*/
-	if((!output->panel_on) || output->first_boot) {
-		output->first_boot = 0; 
-		return;
-	}
-	
-	if(pipe)
-		reg_offset = MIPIC_REG_OFFSET;
-
-	/* Wait for dpi fifo to empty */
-	mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe);
-
-	/* Clear the special packet interrupt bit if set */
-	if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-		REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
-	}
-	
-	if(REG_READ(MIPIA_DPI_CONTROL_REG + reg_offset) == DSI_DPI_CTRL_HS_SHUTDOWN) {
-		dev_warn(dev->dev, "try to send the same package again, abort!");
-		goto shutdown_out;
-	}
-	
-	REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
-
-shutdown_out:
-	output->panel_on = 0;
-	output->first_boot = 0;
-
-	/* FIXME the following is disabled to WA the X slow start issue for TMD panel */
-	/* if(pipe == 2) */
-	/* 	dev_priv->dpi_panel_on2 = false; */
-	/* else if (pipe == 0) */
-	/* 	dev_priv->dpi_panel_on = false;	 */
-	/* #ifdef CONFIG_PM_RUNTIME*/ 
-	/*	if (drm_psb_ospm && !enable_gfx_rtpm) { */
-	/*		pm_runtime_allow(&gpDrmDevice->pdev->dev); */
-	/*	schedule_delayed_work(&dev_priv->rtpm_work, 30 * 1000); */
-	/* } */
-	/*if (enable_gfx_rtpm) */
-	/*		pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
-	/* #endif */
-}
-
-void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
-	struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
-	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
-	struct drm_device *dev = dsi_config->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 mipi_reg = MIPI;
-	u32 pipeconf_reg = PIPEACONF;
-	
-	if(pipe) {
-		mipi_reg = MIPI_C;
-		pipeconf_reg = PIPECCONF;
-	}
-	
-	/* Start up display island if it was shutdown */
-	if (!gma_power_begin(dev, true))
-		return;
-
-	if(on) {
-		if (mdfld_get_panel_type(dev, pipe) == TMD_VID){
- 			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
- 		} else {
-			/* Enable mipi port */
-			REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31)));
-			REG_READ(mipi_reg);
-
-			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
-			mdfld_dsi_tpo_ic_init(dsi_config, pipe);
-		}
-
-		if(pipe == 2) {
-			dev_priv->dpi_panel_on2 = true;
-		}
-		else {
-			dev_priv->dpi_panel_on  = true;
-		}
-
-	} else {
- 		if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
- 			mdfld_dsi_dpi_shut_down(dpi_output, pipe);
- 		} else {
-			mdfld_dsi_dpi_shut_down(dpi_output, pipe);
-			/* Disable mipi port */
-			REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31)));
-			REG_READ(mipi_reg);
-		}
-
-		if(pipe == 2)
-			dev_priv->dpi_panel_on2 = false;
-		else
-			dev_priv->dpi_panel_on  = false;
-	}
-	gma_power_end(dev);
-}
-
-void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
-{
-	dev_dbg(encoder->dev->dev, "DPMS %s\n",
-			(mode == DRM_MODE_DPMS_ON ? "on":"off"));
-
-	if (mode == DRM_MODE_DPMS_ON)
-		mdfld_dsi_dpi_set_power(encoder, true);
-	else {
-		mdfld_dsi_dpi_set_power(encoder, false);
-#if 0 /* FIXME */
-#ifdef CONFIG_PM_RUNTIME
-		if (enable_gfx_rtpm)
-			pm_schedule_suspend(&gpDrmDevice->pdev->dev, gfxrtdelay);
-#endif
-#endif
-	}
-}
-
-bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
-				     struct drm_display_mode *mode,
-				     struct drm_display_mode *adjusted_mode)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
-	struct drm_display_mode *fixed_mode = dsi_config->fixed_mode;
-
-	if(fixed_mode) {
-		adjusted_mode->hdisplay = fixed_mode->hdisplay;
-		adjusted_mode->hsync_start = fixed_mode->hsync_start;
-		adjusted_mode->hsync_end = fixed_mode->hsync_end;
-		adjusted_mode->htotal = fixed_mode->htotal;
-		adjusted_mode->vdisplay = fixed_mode->vdisplay;
-		adjusted_mode->vsync_start = fixed_mode->vsync_start;
-		adjusted_mode->vsync_end = fixed_mode->vsync_end;
-		adjusted_mode->vtotal = fixed_mode->vtotal;
-		adjusted_mode->clock = fixed_mode->clock;
-		drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-	}
-	
-	return true;
-}
-
-void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder) 
-{
-	mdfld_dsi_dpi_set_power(encoder, false);
-}
-
-void mdfld_dsi_dpi_commit(struct drm_encoder *encoder) 
-{
-	mdfld_dsi_dpi_set_power(encoder, true);
-}
-
-void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
-				   struct drm_display_mode *mode,
-				   struct drm_display_mode *adjusted_mode)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
-	struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
-	struct drm_device *dev = dsi_config->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
-	
-	u32 pipeconf_reg = PIPEACONF;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 mipi_reg = MIPI;
-	u32 reg_offset = 0;
-	
-	u32 pipeconf = dev_priv->pipeconf;
-	u32 dspcntr = dev_priv->dspcntr;
-	u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
-	
-	dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n",
-				mode->hdisplay, mode->vdisplay, pipe);
-
-	if(pipe) {
-		pipeconf_reg = PIPECCONF;
-		dspcntr_reg = DSPCCNTR;
-		mipi_reg = MIPI_C;
-		reg_offset = MIPIC_REG_OFFSET;
-	} else {
-		mipi |= 2;
-	}
-	
-	if (!gma_power_begin(dev, true))
-		return;
-
-	/* Set up mipi port FIXME: do at init time */
-	REG_WRITE(mipi_reg, mipi);
-	REG_READ(mipi_reg);
-
-	/* Set up DSI controller DPI interface */
-	mdfld_dsi_dpi_controller_init(dsi_config, pipe);
-
-	if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
-		/* Turn on DPI interface */
-		mdfld_dsi_dpi_turn_on(dpi_output, pipe);
-	}
-	
-	/* Set up pipe */
-	REG_WRITE(pipeconf_reg, pipeconf);
-	REG_READ(pipeconf_reg);
-	
-	/* Set up display plane */
-	REG_WRITE(dspcntr_reg, dspcntr);
-	REG_READ(dspcntr_reg);
-	
-	msleep(20); /* FIXME: this should wait for vblank */
-	
-	dev_dbg(dev->dev, "State %x, power %d\n",
-		REG_READ(MIPIA_INTR_STAT_REG + reg_offset),
-		dpi_output->panel_on);
-
-	if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
-		/* Init driver ic */
-		mdfld_dsi_tpo_ic_init(dsi_config, pipe);
-		/* Init backlight */
-		mdfld_dsi_brightness_init(dsi_config, pipe);
-	}
-	gma_power_end(dev);
-}
-
-
-/*
- * Init DSI DPI encoder. 
- * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
- * return pointer of newly allocated DPI encoder, NULL on error
- */ 
-struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, 
-				struct mdfld_dsi_connector *dsi_connector,
-				struct panel_funcs *p_funcs)
-{
-	struct mdfld_dsi_dpi_output *dpi_output = NULL;
-	struct mdfld_dsi_config *dsi_config;
-	struct drm_connector *connector = NULL;
-	struct drm_encoder *encoder = NULL;
-	struct drm_display_mode *fixed_mode = NULL;
-	int pipe;
-	u32 data;
-	int ret;
-
-	if (!dsi_connector || !p_funcs) {
-		WARN_ON(1);
-		return NULL;
-	}
-
-	dsi_config = mdfld_dsi_get_config(dsi_connector);
-	pipe = dsi_connector->pipe;
-
-	/* Panel hard-reset */
-	if (p_funcs->reset) {
-		ret = p_funcs->reset(pipe);
-		if (ret) {
-			DRM_ERROR("Panel %d hard-reset failed\n", pipe);
-			return NULL;
-		}
-	}
-
-	/* Panel drvIC init */
-	if (p_funcs->drv_ic_init)
-		p_funcs->drv_ic_init(dsi_config, pipe);
-
-	/* Panel power mode detect */
-	ret = mdfld_dsi_get_power_mode(dsi_config,
-					&data,
-					MDFLD_DSI_LP_TRANSMISSION);
-	if (ret) {
-		DRM_ERROR("Panel %d get power mode failed\n", pipe);
-		dsi_connector->status = connector_status_disconnected;
-	} else {
-		DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
-		dsi_connector->status = connector_status_connected;
-	}
-
-	dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL);
-	if(!dpi_output) {
-		dev_err(dev->dev, "No memory for dsi_dpi_output\n");
-		return NULL;
-	}
-
-	if(dsi_connector->pipe) 
-		dpi_output->panel_on = 0;
-	else
-		dpi_output->panel_on = 0;
-	
-	dpi_output->dev = dev;
-	dpi_output->p_funcs = p_funcs;
-	dpi_output->first_boot = 1;
-	
-	/* Get fixed mode */
-	dsi_config = mdfld_dsi_get_config(dsi_connector);
-	fixed_mode = dsi_config->fixed_mode;
-	
-	/* Create drm encoder object */
-	connector = &dsi_connector->base.base;
-	encoder = &dpi_output->base.base;
-	/*
-	 * On existing hardware this will be a panel of some form,
-	 * if future devices also have HDMI bridges this will need
-	 * revisiting
-	 */
-	drm_encoder_init(dev,
-			encoder,
-			p_funcs->encoder_funcs,
-			DRM_MODE_ENCODER_LVDS);
-	drm_encoder_helper_add(encoder,
-				p_funcs->encoder_helper_funcs);
-	
-	/* Attach to given connector */
-	drm_mode_connector_attach_encoder(connector, encoder);
-	
-	/* Set possible crtcs and clones */
-	if(dsi_connector->pipe) {
-		encoder->possible_crtcs = (1 << 2);
-		encoder->possible_clones = (1 << 1);
-	} else {
-		encoder->possible_crtcs = (1 << 0);
-		encoder->possible_clones = (1 << 0);
-	}
-	return &dpi_output->base;
-}
-
diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.h b/drivers/staging/gma500/mdfld_dsi_dpi.h
deleted file mode 100644
index ed92d45..0000000
--- a/drivers/staging/gma500/mdfld_dsi_dpi.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#ifndef __MDFLD_DSI_DPI_H__
-#define __MDFLD_DSI_DPI_H__
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-struct mdfld_dsi_dpi_timing {
-	u16 hsync_count;
-	u16 hbp_count;
-	u16 hfp_count;
-	u16 hactive_count;
-	u16 vsync_count;
-	u16 vbp_count;
-	u16 vfp_count;
-};
-
-struct mdfld_dsi_dpi_output {
-	struct mdfld_dsi_encoder base;
-	struct drm_device *dev;
-
-	int panel_on;
-	int first_boot;
-
-	struct panel_funcs *p_funcs;
-};
-
-#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) \
-	container_of(dsi_encoder, struct mdfld_dsi_dpi_output, base)
-
-extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode,
-			struct mdfld_dsi_dpi_timing *dpi_timing,
-			int num_lane, int bpp);
-extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
-			struct mdfld_dsi_connector *dsi_connector,
-			struct panel_funcs *p_funcs);
-
-/* Medfield DPI helper functions */
-extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode);
-extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
-			struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode);
-extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder);
-extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder);
-extern void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
-			struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode);
-extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output,
-			int pipe);
-extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *si_config,
-			int pipe);
-#endif /*__MDFLD_DSI_DPI_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c
deleted file mode 100644
index 3f979db..0000000
--- a/drivers/staging/gma500/mdfld_dsi_output.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_output.h"
-#include <asm/intel_scu_ipc.h>
-#include "mdfld_dsi_pkg_sender.h"
-#include <linux/pm_runtime.h>
-#include <linux/moduleparam.h>
-
-#define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100
-
-static int CABC_control = 1;
-static int LABC_control = 1;
-
-module_param (CABC_control, int, 0644);
-module_param (LABC_control, int, 0644);
-
-/**
- * make these MCS command global 
- * we don't need 'movl' everytime we send them.
- * FIXME: these datas were provided by OEM, we should get them from GCT.
- **/
-static u32 mdfld_dbi_mcs_hysteresis[] = {
-	0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff,
-	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-	0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff,
-	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-	0x000000ff,
-};
-
-static u32 mdfld_dbi_mcs_display_profile[] = {
-	0x50281450, 0x0000c882, 0x00000000, 0x00000000,
-	0x00000000,
-};
-
-static u32 mdfld_dbi_mcs_kbbc_profile[] = {
-	0x00ffcc60, 0x00000000, 0x00000000, 0x00000000,
-}; 
-	
-static u32 mdfld_dbi_mcs_gamma_profile[] = {
-	0x81111158, 0x88888888, 0x88888888,
-}; 
-
-/*
- * write hysteresis values.
- */
-static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config *dsi_config,
-                                                                int pipe)
-{
-	struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-	if(!sender) {
-	        WARN_ON(1);
-		return;
-	}
-	mdfld_dsi_send_mcs_long_hs(sender,
-				   mdfld_dbi_mcs_hysteresis,
-				   17,
-				   MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write display profile values.
- */
-static void mdfld_dsi_write_display_profile(struct mdfld_dsi_config *dsi_config, int pipe)
-{
-	struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-	if(!sender) {
-	        WARN_ON(1);
-		return;
-        }
-	mdfld_dsi_send_mcs_long_hs(sender,
-				   mdfld_dbi_mcs_display_profile,
-				   5,
-				   MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write KBBC profile values.
- */
-static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config * dsi_config, int pipe)
-{
-	struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-	if(!sender) {
-	        WARN_ON(1);
-		return;
-        }
-	mdfld_dsi_send_mcs_long_hs(sender,
-				   mdfld_dbi_mcs_kbbc_profile,
-				   4,
-				   MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * write gamma setting.
- */
-static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config *dsi_config, int pipe)
-{
-	struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-	if(!sender) {
-	        WARN_ON(1);
-		return;
-	}
-	mdfld_dsi_send_mcs_long_hs(sender,
-				   mdfld_dbi_mcs_gamma_profile,
-				   3,
-				   MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * Check and see if the generic control or data buffer is empty and ready.
- */
-void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat)
-{
-	u32 GEN_BF_time_out_count = 0;
-	
-	/* Check MIPI Adatper command registers */
-	for (GEN_BF_time_out_count = 0; GEN_BF_time_out_count < GEN_FB_TIME_OUT; GEN_BF_time_out_count++)
-	{
-		if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat)
-			break;
-		udelay (100);
-	}
-
-	if (GEN_BF_time_out_count == GEN_FB_TIME_OUT)
-		dev_err(dev->dev,
-        "mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x. \n",
-                                                gen_fifo_stat_reg);
-}
-
-/*
- * Manage the DSI MIPI keyboard and display brightness.
- * FIXME: this is exported to OSPM code. should work out an specific 
- * display interface to OSPM. 
- */
-void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
-	struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
-	struct drm_device *dev = sender->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 gen_ctrl_val;
-	
-	if(!sender) {
-	        WARN_ON(1);
-	        return;
-	}
-	/* Set default display backlight value to 85% (0xd8)*/
-	mdfld_dsi_send_mcs_short_hs(sender,
-				    write_display_brightness,
-				    0xd8,
-				    1,
-				    MDFLD_DSI_SEND_PACKAGE);
-
-	/* Set minimum brightness setting of CABC function to 20% (0x33)*/
-	mdfld_dsi_send_mcs_short_hs(sender,
-				    write_cabc_min_bright,
-				    0x33,
-				    1,
-				    MDFLD_DSI_SEND_PACKAGE);
-
-	mdfld_dsi_write_hysteresis(dsi_config, pipe);
-	mdfld_dsi_write_display_profile (dsi_config, pipe);
-	mdfld_dsi_write_kbbc_profile (dsi_config, pipe);
-	mdfld_dsi_write_gamma_setting (dsi_config, pipe);
-
-	/* Enable backlight or/and LABC */
-	gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON| BACKLIGHT_ON;
-	if (LABC_control == 1 || CABC_control == 1)
-		gen_ctrl_val |= DISPLAY_DIMMING_ON| DISPLAY_BRIGHTNESS_AUTO | GAMMA_AUTO;
-
-	if (LABC_control == 1)
-		gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON;
-
-	dev_priv->mipi_ctrl_display = gen_ctrl_val;
-
-	mdfld_dsi_send_mcs_short_hs(sender,
-				    write_ctrl_display,
-				    (u8)gen_ctrl_val,
-				    1,
-				    MDFLD_DSI_SEND_PACKAGE);
-
-	if (CABC_control == 0)
-		return;
-	mdfld_dsi_send_mcs_short_hs(sender,
-				    write_ctrl_cabc,
-				    UI_IMAGE,
-				    1,
-				    MDFLD_DSI_SEND_PACKAGE);
-}
-
-/*
- * Manage the mipi display brightness.
- * TODO: refine this interface later
- */
-void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level)
-{
-	struct mdfld_dsi_pkg_sender *sender;
-	struct drm_psb_private *dev_priv;
-	struct mdfld_dsi_config *dsi_config;
-	u32 gen_ctrl_val;
-	int p_type;	
-	
-	if (!dev || (pipe != 0 && pipe != 2)) {
-		dev_err(dev->dev, "Invalid parameter\n");
-		return;
-	}
-
-	p_type = mdfld_get_panel_type(dev, 0);
-
-	dev_priv = dev->dev_private;
-
-	if(pipe)
-		dsi_config = dev_priv->dsi_configs[1];
-	else
-		dsi_config = dev_priv->dsi_configs[0];
-
-	sender = mdfld_dsi_get_pkg_sender(dsi_config);
-
-	if(!sender) {
-	        WARN_ON(1);
-		return;
-	}
-
-	gen_ctrl_val = ((level * 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff;
-
-	dev_dbg(dev->dev,
-                "pipe = %d, gen_ctrl_val = %d.  \n", pipe, gen_ctrl_val);
-	
-	if(p_type == TMD_VID || p_type == TMD_CMD){
-		/* Set display backlight value */
-		mdfld_dsi_send_mcs_short_hs(sender, 
-					tmd_write_display_brightness, 
-					(u8)gen_ctrl_val, 
-	                                 1, 
-	                        	MDFLD_DSI_SEND_PACKAGE);		
-	} else {			
-		/* Set display backlight value */
-		mdfld_dsi_send_mcs_short_hs(sender,
-				    write_display_brightness,
-				    (u8)gen_ctrl_val,
-                                    1,
-                                    MDFLD_DSI_SEND_PACKAGE);
-
-
-		/* Enable backlight control */
-		if (level == 0)
-			gen_ctrl_val = 0;
-		else 
-			gen_ctrl_val = dev_priv->mipi_ctrl_display;
-
-		mdfld_dsi_send_mcs_short_hs(sender,
-                                    write_ctrl_display,
-                                   (u8)gen_ctrl_val,
-                                   1,
-                                   MDFLD_DSI_SEND_PACKAGE);
-	}
-}
-
-/*
- * shut down DSI controller
- */ 
-void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-	struct drm_device * dev;
-	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-	int retry = 100;
-	
-	if (!dsi_config) {
-	        WARN_ON(1);
-		return;
-	}
-	
-	dev = dsi_config->dev;
-	
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-		
-	if(!(REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) &  DSI_DEVICE_READY)) 
-		goto shutdown_out;
-	
-	/* Send shut down package, clean packet send bit first */
-	if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-		REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), 
-				(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) | DSI_INTR_STATE_SPL_PKG_SENT));
-	}
-	
-	/*send shut down package in HS*/
-	REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
-	
-	
-	/*
-	 * make sure shut down is sent.
-	 * FIXME: add max retry counter
-	 */
-	while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
-		retry--;
-		
-		if(!retry) {
-			dev_err(dev->dev, "timeout\n");
-			break;
-		}
-	}
-	
-	/*sleep 1 ms to ensure shutdown finished*/
-	msleep(100);
-	
-	/*un-ready device*/
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
-			   (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & ~DSI_DEVICE_READY));
-
-shutdown_out:			   
-	gma_power_end(dev);
-}
-
-void mdfld_dsi_controller_startup(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-	struct drm_device * dev;
-	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-	int retry = 100;
-	
-	
-	if (!dsi_config) {
-		WARN_ON(1);
-		return;
-	}
-	
-	dev = dsi_config->dev;
-	dev_dbg(dev->dev, "starting up DSI controller on pipe %d...\n", pipe);
-	
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-	
-	if((REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY)) 
-		goto startup_out;
-	
-	/*if config DPI, turn on DPI interface*/
-	if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
-		if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
-			REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
-		}
-		
-		REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
-		
-		/*
-		 * make sure shut down is sent.
-		 * FIXME: add max retry counter
-		 */
-		while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
-			retry--;
-			if(!retry) {
-				dev_err(dev->dev, "timeout\n");
-				break;
-			}
-		}
-		
-		msleep(100);
-	}
-	
-	/*set device ready*/
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
-			   (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) | DSI_DEVICE_READY));
-
-startup_out:	
-	gma_power_end(dev);
-}
-
-
-static int mdfld_dsi_get_panel_status(struct mdfld_dsi_config *dsi_config,
-					u8 dcs,
-					u32 *data,
-					u8 transmission)
-{
-	struct mdfld_dsi_pkg_sender *sender
-		= mdfld_dsi_get_pkg_sender(dsi_config);
-
-	if (!sender || !data) {
-		DRM_ERROR("Invalid parameter\n");
-		return -EINVAL;
-	}
-
-	if (transmission == MDFLD_DSI_HS_TRANSMISSION)
-		return mdfld_dsi_read_mcs_hs(sender, dcs, data, 1);
-	else if (transmission == MDFLD_DSI_LP_TRANSMISSION)
-		return mdfld_dsi_read_mcs_lp(sender, dcs, data, 1);
-	else
-		return -EINVAL;
-}
-
-int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config,
-				u32 *mode,
-				u8 transmission)
-{
-	if (!dsi_config || !mode) {
-		DRM_ERROR("Invalid parameter\n");
-		return -EINVAL;
-	}
-
-	return mdfld_dsi_get_panel_status(dsi_config, 0x0a, mode, transmission);
-}
-
-int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config,
-					u32 *result,
-					u8 transmission)
-{
-	if (!dsi_config || !result) {
-		DRM_ERROR("Invalid parameter\n");
-		return -EINVAL;
-	}
-
-	return mdfld_dsi_get_panel_status(dsi_config, 0x0f, result,
-					  transmission);
-}
-
-/*
- * NOTE: this function was used by OSPM.
- * TODO: will be removed later, should work out display interfaces for OSPM
- */
-void mdfld_dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-	if(!dsi_config || ((pipe != 0) && (pipe != 2))) {
-	        WARN_ON(1);
-		return;
-	}
-
-	if(dsi_config->type)
-		mdfld_dsi_dpi_controller_init(dsi_config, pipe);
-	else
-		mdfld_dsi_controller_dbi_init(dsi_config, pipe);
-}
-
-static void mdfld_dsi_connector_save(struct drm_connector * connector)
-{
-}
-
-static void mdfld_dsi_connector_restore(struct drm_connector * connector)
-{
-}
-
-static enum drm_connector_status mdfld_dsi_connector_detect(struct drm_connector * connector, bool force)
-{
-	struct psb_intel_output *psb_output
-					= to_psb_intel_output(connector);
-	struct mdfld_dsi_connector *dsi_connector
-	                                = MDFLD_DSI_CONNECTOR(psb_output);
-	return dsi_connector->status;
-}
-
-static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
-					struct drm_property *property,
-					uint64_t value)
-{
-	struct drm_encoder *encoder = connector->encoder;
-
-	if (!strcmp(property->name, "scaling mode") && encoder) {
-		struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc);
-		bool bTransitionFromToCentered;
-		uint64_t curValue;
-
-		if (!psb_crtc)
-			goto set_prop_error;
-
-		switch (value) {
-		case DRM_MODE_SCALE_FULLSCREEN:
-			break;
-		case DRM_MODE_SCALE_NO_SCALE:
-			break;
-		case DRM_MODE_SCALE_ASPECT:
-			break;
-		default:
-			goto set_prop_error;
-		}
-
-		if (drm_connector_property_get_value(connector, property, &curValue))
-			goto set_prop_error;
-
-		if (curValue == value)
-			goto set_prop_done;
-
-		if (drm_connector_property_set_value(connector, property, value))
-			goto set_prop_error;
-
-		bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
-			(value == DRM_MODE_SCALE_NO_SCALE);
-
-		if (psb_crtc->saved_mode.hdisplay != 0 &&
-		    psb_crtc->saved_mode.vdisplay != 0) {
-			if (bTransitionFromToCentered) {
-				if (!drm_crtc_helper_set_mode(encoder->crtc, &psb_crtc->saved_mode,
-					    encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
-					goto set_prop_error;
-			} else {
-				struct drm_encoder_helper_funcs *pEncHFuncs  = encoder->helper_private;
-				pEncHFuncs->mode_set(encoder, &psb_crtc->saved_mode,
-						     &psb_crtc->saved_adjusted_mode);
-			}
-		}
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	} else if (!strcmp(property->name, "backlight") && encoder) {
-		struct drm_psb_private *dev_priv = encoder->dev->dev_private;
-		struct backlight_device *psb_bd = dev_priv->backlight_device;
-		dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value);
-		if (drm_connector_property_set_value(connector, property, value))
-			goto set_prop_error;
-		else {
-			dev_dbg(encoder->dev->dev,
-			                "set brightness to %d", (int)value);
-			if (psb_bd) {
-				psb_bd->props.brightness = value;
-				backlight_update_status(psb_bd);
-			}
-		}
-#endif
-	}
-set_prop_done:
-    return 0;
-set_prop_error:
-    return -1;
-}
-
-static void mdfld_dsi_connector_destroy(struct drm_connector *connector)
-{
-	struct psb_intel_output * psb_output = to_psb_intel_output(connector);
-	struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
-	struct mdfld_dsi_pkg_sender * sender;
-	
-	if(!dsi_connector)
-	        return;
-	
-	drm_sysfs_connector_remove(connector);
-	drm_connector_cleanup(connector);
-	
-	sender = dsi_connector->pkg_sender;
-
-	mdfld_dsi_pkg_sender_destroy(sender);
-
-	kfree(dsi_connector);
-}
-
-static int mdfld_dsi_connector_get_modes(struct drm_connector * connector)
-{
-	struct psb_intel_output * psb_output = to_psb_intel_output(connector);
-	struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
-	struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
-	struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
-	struct drm_display_mode * dup_mode = NULL;
-	struct drm_device * dev = connector->dev;
-	
-	connector->display_info.min_vfreq = 0;
-	connector->display_info.max_vfreq = 200;
-	connector->display_info.min_hfreq = 0;
-	connector->display_info.max_hfreq = 200;
-
-	if(fixed_mode) {
-		dev_dbg(dev->dev, "fixed_mode %dx%d\n",
-		        fixed_mode->hdisplay, fixed_mode->vdisplay);
-		
-		dup_mode = drm_mode_duplicate(dev, fixed_mode);
-		drm_mode_probed_add(connector, dup_mode);
-		return 1;
-	}
-	dev_err(dev->dev, "Didn't get any modes!\n");
-	return 0;
-}
-
-static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, struct drm_display_mode * mode)
-{
-	struct psb_intel_output * psb_output = to_psb_intel_output(connector);
-	struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
-	struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
-	struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
-
-	dev_dbg(connector->dev->dev, "mode %p, fixed mode %p\n",
-	                                                mode, fixed_mode);
-
-	if(mode->flags & DRM_MODE_FLAG_DBLSCAN) 
-		return MODE_NO_DBLESCAN;
-
-	if(mode->flags & DRM_MODE_FLAG_INTERLACE)
-		return MODE_NO_INTERLACE;
-
-	/**
-	 * FIXME: current DC has no fitting unit, reject any mode setting request
-	 * will figure out a way to do up-scaling(pannel fitting) later.  
-	 **/
-	if(fixed_mode) {
-		if(mode->hdisplay != fixed_mode->hdisplay)
-			return MODE_PANEL;
-
-		if(mode->vdisplay != fixed_mode->vdisplay)
-			return MODE_PANEL;
-	}
-	dev_dbg(connector->dev->dev, "mode ok\n");
-
-	return MODE_OK;
-}
-
-static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode)
-{
-#ifdef CONFIG_PM_RUNTIME
-	struct drm_device * dev = connector->dev;
-	struct drm_psb_private * dev_priv = dev->dev_private;
-	bool panel_on, panel_on2;
-#endif
-	/* First, execute DPMS */
-	drm_helper_connector_dpms(connector, mode);
-
-#ifdef CONFIG_PM_RUNTIME
-	if(mdfld_panel_dpi(dev)) {
-		/* DPI panel */
-		panel_on = dev_priv->dpi_panel_on;
-		panel_on2 = dev_priv->dpi_panel_on2;
-	} else {
-		/* DBI panel */
-		panel_on = dev_priv->dbi_panel_on;
-		panel_on2 = dev_priv->dbi_panel_on2;
-	}
-
-	/* Then check all display panels + monitors status */
-	/* Make sure that the Display (B) sub-system status isn't i3 when
-	 * R/W the DC register, otherwise "Fabric error" issue would occur
-	 * during S0i3 state. */
-	if(!panel_on && !panel_on2 && !(REG_READ(HDMIB_CONTROL)
-	                                        & HDMIB_PORT_EN)) {
-		/* Request rpm idle */
-		if(dev_priv->rpm_enabled)
-			pm_request_idle(&dev->pdev->dev);
-	}
-	/*
-	 * if rpm wasn't enabled yet, try to allow it
-	 * FIXME: won't enable rpm for DPI since DPI
-	 * CRTC setting is a little messy now.
-	 * Enable it later!
-	 */
-#if 0
-	if(!dev_priv->rpm_enabled && !mdfld_panel_dpi(dev))
-		ospm_runtime_pm_allow(dev);
-#endif
-#endif
-}
-
-static struct drm_encoder *mdfld_dsi_connector_best_encoder(
-                                        struct drm_connector *connector) 
-{
-	struct psb_intel_output * psb_output = to_psb_intel_output(connector);
-	struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
-	struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
-	struct mdfld_dsi_encoder * encoder = NULL;
-	
-	if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) 
-		encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DBI];
-	else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) 
-		encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DPI];
-	
-	dev_dbg(connector->dev->dev, "get encoder %p\n", encoder);
-	
-	if(!encoder) {
-		dev_err(connector->dev->dev,
-                        "Invalid encoder for type %d\n", dsi_config->type);
-		return NULL;
-	}
-	dsi_config->encoder = encoder;	
-	return &encoder->base;	
-}
-
-/* DSI connector funcs */
-static const struct drm_connector_funcs mdfld_dsi_connector_funcs = {
-	.dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms,
-	.save = mdfld_dsi_connector_save,
-	.restore = mdfld_dsi_connector_restore,
-	.detect = mdfld_dsi_connector_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.set_property = mdfld_dsi_connector_set_property,
-	.destroy = mdfld_dsi_connector_destroy,
-};
-
-/* DSI connector helper funcs */
-static const struct drm_connector_helper_funcs mdfld_dsi_connector_helper_funcs = {
-	.get_modes = mdfld_dsi_connector_get_modes,
-	.mode_valid = mdfld_dsi_connector_mode_valid,
-	.best_encoder = mdfld_dsi_connector_best_encoder,
-};
-
-static int mdfld_dsi_get_default_config(struct drm_device * dev, 
-										struct mdfld_dsi_config * config, int pipe)
-{
-	if(!dev || !config) {
-	        WARN_ON(1);
-		return -EINVAL;
-	}
-	
-	config->bpp = 24;
-	config->type = mdfld_panel_dpi(dev);
-	config->lane_count = 2;
-	config->channel_num = 0;
-	/*NOTE: video mode is ignored when type is MDFLD_DSI_ENCODER_DBI*/
-	if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
-		config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE;
-	} else {
-		config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE;
-	}
-	
-	return 0;
-}
-
-/*
- * Returns the panel fixed mode from configuration. 
- */
-struct drm_display_mode *
-mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-	struct drm_device *dev = dsi_config->dev;
-	struct drm_display_mode *mode;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-	bool use_gct = false;
-
-	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-	if (!mode) {
-	        dev_err(dev->dev, "Out of memory for mode\n");
-		return NULL;
-        }
-	if (use_gct) {
-		dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
-		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-		mode->hsync_start = mode->hdisplay + \
-				((ti->hsync_offset_hi << 8) | \
-				ti->hsync_offset_lo);
-		mode->hsync_end = mode->hsync_start + \
-				((ti->hsync_pulse_width_hi << 8) | \
-				ti->hsync_pulse_width_lo);
-		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
-								ti->hblank_lo);
-		mode->vsync_start = \
-			mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
-						ti->vsync_offset_lo);
-		mode->vsync_end = \
-			mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
-						ti->vsync_pulse_width_lo);
-		mode->vtotal = mode->vdisplay + \
-				((ti->vblank_hi << 8) | ti->vblank_lo);
-		mode->clock = ti->pixel_clock * 10;
-	} else {
-		if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { 
-			if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
-				mode->hdisplay = 480;
-				mode->vdisplay = 854;
-				mode->hsync_start = 487;
-				mode->hsync_end = 490;
-				mode->htotal = 499;
-				mode->vsync_start = 861;
-				mode->vsync_end = 865;
-				mode->vtotal = 873;
-				mode->clock = 33264;
-			} else {
-				mode->hdisplay = 864;
-				mode->vdisplay = 480;
-				mode->hsync_start = 873;
-				mode->hsync_end = 876;
-				mode->htotal = 887;
-				mode->vsync_start = 487;
-				mode->vsync_end = 490;
-				mode->vtotal = 499;
-				mode->clock = 33264;
-			}
-		} else if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
-			mode->hdisplay = 864;
-			mode->vdisplay = 480;
-			mode->hsync_start = 872;
-			mode->hsync_end = 876;
-			mode->htotal = 884;
-			mode->vsync_start = 482;
-			mode->vsync_end = 494;
-			mode->vtotal = 486;
-			mode->clock = 25777;
-			
-		}
-	}
-
-	drm_mode_set_name(mode);
-	drm_mode_set_crtcinfo(mode, 0);
-	
-	mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-	return mode;
-}
-
-int mdfld_dsi_panel_reset(int pipe)
-{
-	unsigned gpio;
-	int ret = 0;
-
-	switch (pipe) {
-	case 0:
-		gpio = 128;
-		break;
-	case 2:
-		gpio = 34;
-		break;
-	default:
-		DRM_ERROR("Invalid output\n");
-		return -EINVAL;
-	}
-
-	ret = gpio_request(gpio, "gfx");
-	if (ret) {
-		DRM_ERROR("gpio_rqueset failed\n");
-		return ret;
-	}
-
-	ret = gpio_direction_output(gpio, 1);
-	if (ret) {
-		DRM_ERROR("gpio_direction_output failed\n");
-		goto gpio_error;
-	}
-
-	gpio_get_value(128);
-
-gpio_error:
-	if (gpio_is_valid(gpio))
-		gpio_free(gpio);
-
-	return ret;
-}
-
-/*
- * MIPI output init
- * @dev drm device
- * @pipe pipe number. 0 or 2
- * @config 
- * 
- * Do the initialization of a MIPI output, including create DRM mode objects
- * initialization of DSI output on @pipe 
- */
-void mdfld_dsi_output_init(struct drm_device *dev,
-			   int pipe, 
-			   struct mdfld_dsi_config *config,
-			   struct panel_funcs* p_cmd_funcs,
-			   struct panel_funcs* p_vid_funcs)
-{
-	struct mdfld_dsi_config * dsi_config;
-	struct mdfld_dsi_connector * dsi_connector;
-	struct psb_intel_output * psb_output;
-	struct drm_connector * connector;
-	struct mdfld_dsi_encoder * encoder;
-	struct drm_psb_private * dev_priv = dev->dev_private;
-	struct panel_info dsi_panel_info;
-	u32 width_mm, height_mm;
-
-	dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe);
-	
-	if(!dev || ((pipe != 0) && (pipe != 2))) {
-	        WARN_ON(1);
-		return;
-	}
-	
-	/*create a new connetor*/
-	dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL);
-	if(!dsi_connector) {
-		DRM_ERROR("No memory");
-		return;
-	}
-	
-	dsi_connector->pipe =  pipe;
-	
-	/*set DSI config*/
-	if(config) { 
-		dsi_config = config;
-	} else {
-		dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), GFP_KERNEL);
-		if(!dsi_config) {
-			dev_err(dev->dev,
-			        "cannot allocate memory for DSI config\n");
-			goto dsi_init_err0;
-		}
-		
-		mdfld_dsi_get_default_config(dev, dsi_config, pipe);
-	}
-	
-	dsi_connector->private = dsi_config;
-	
-	dsi_config->changed = 1;
-	dsi_config->dev = dev;
-	
-	/* Init fixed mode basing on DSI config type */
-	if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
-		dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev);
-		if(p_cmd_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
-			goto dsi_init_err0;
-	} else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
-		dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev);
-		if(p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
-			goto dsi_init_err0;
-	}
-
-	width_mm = dsi_panel_info.width_mm;
-	height_mm = dsi_panel_info.height_mm;
-
-	dsi_config->mode = dsi_config->fixed_mode;
-	dsi_config->connector = dsi_connector;
-	
-	if(!dsi_config->fixed_mode) {
-		dev_err(dev->dev, "No pannel fixed mode was found\n");
-		goto dsi_init_err0;
-	}
-	
-	if(pipe && dev_priv->dsi_configs[0]) {
-		dsi_config->dvr_ic_inited = 0;
-		dev_priv->dsi_configs[1] = dsi_config;
-	} else if(pipe == 0) {
-		dsi_config->dvr_ic_inited = 1;
-		dev_priv->dsi_configs[0] = dsi_config;
-	} else {
-		dev_err(dev->dev, "Trying to init MIPI1 before MIPI0\n");
-		goto dsi_init_err0;
-	}
-
-	/*init drm connector object*/
-	psb_output = &dsi_connector->base;
-	
-	psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2;
-
-	connector = &psb_output->base;
-	/* Revisit type if MIPI/HDMI bridges ever appear on Medfield */
-	drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs,
-						DRM_MODE_CONNECTOR_LVDS);
-	drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs);
-	
-	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-	connector->display_info.width_mm = width_mm;
-	connector->display_info.height_mm = height_mm;
-	connector->interlace_allowed = false;
-	connector->doublescan_allowed = false;
-	
-	/* Attach properties */
-	drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
-	drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
-
-	/* Init DSI package sender on this output */
-	if (mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) {
-		DRM_ERROR("Package Sender initialization failed on pipe %d\n", pipe);
-		goto dsi_init_err0;
-	}
-
-	/* Init DBI & DPI encoders */
-	if (p_cmd_funcs) {
-		encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs);
-		if(!encoder) {
-			dev_err(dev->dev, "Create DBI encoder failed\n");
-			goto dsi_init_err1;
-		}
-		encoder->private = dsi_config;
-		dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder;
-	}
-	
-	if(p_vid_funcs) {
-		encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs);
-		if(!encoder) {
-			dev_err(dev->dev, "Create DPI encoder failed\n");
-			goto dsi_init_err1;
-		}
-		encoder->private = dsi_config;
-		dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder;
-	}
-	
-	drm_sysfs_connector_add(connector);
-	return;
-	
-	/*TODO: add code to destroy outputs on error*/
-dsi_init_err1:
-	/*destroy sender*/
-	mdfld_dsi_pkg_sender_destroy(dsi_connector->pkg_sender);
-
-	drm_connector_cleanup(connector);
-	kfree(dsi_config->fixed_mode);
-	kfree(dsi_config);
-dsi_init_err0:
-	kfree(dsi_connector);
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_output.h b/drivers/staging/gma500/mdfld_dsi_output.h
deleted file mode 100644
index 4699267..0000000
--- a/drivers/staging/gma500/mdfld_dsi_output.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#ifndef __MDFLD_DSI_OUTPUT_H__
-#define __MDFLD_DSI_OUTPUT_H__
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_edid.h>
-
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include "mdfld_output.h"
-
-#include <asm/mrst.h>
-
-
-static inline struct mdfld_dsi_config *
-	mdfld_dsi_get_config(struct mdfld_dsi_connector *connector)
-{
-	if (!connector)
-		return NULL;
-	return (struct mdfld_dsi_config *)connector->private;
-}
-
-static inline void *mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config *config)
-{
-	struct mdfld_dsi_connector *dsi_connector;
-
-	if (!config)
-		return NULL;
-
-	dsi_connector = config->connector;
-
-	if (!dsi_connector)
-		return NULL;
-
-	return dsi_connector->pkg_sender;
-}
-
-static inline struct mdfld_dsi_config *
-	mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder *encoder)
-{
-	if (!encoder)
-		return NULL;
-	return (struct mdfld_dsi_config *)encoder->private;
-}
-
-static inline struct mdfld_dsi_connector *
-	mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder *encoder)
-{
-	struct mdfld_dsi_config *config;
-
-	if (!encoder)
-		return NULL;
-
-	config = mdfld_dsi_encoder_get_config(encoder);
-	if (!config)
-		return NULL;
-
-	return config->connector;
-}
-
-static inline void *mdfld_dsi_encoder_get_pkg_sender(
-	struct mdfld_dsi_encoder *encoder)
-{
-	struct mdfld_dsi_config *dsi_config;
-
-	dsi_config = mdfld_dsi_encoder_get_config(encoder);
-	if (!dsi_config)
-		return NULL;
-
-	return mdfld_dsi_get_pkg_sender(dsi_config);
-}
-
-static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder *encoder)
-{
-	struct mdfld_dsi_connector *connector;
-
-	if (!encoder)
-		return -1;
-
-	connector = mdfld_dsi_encoder_get_connector(encoder);
-	if (!connector)
-		return -1;
-
-	return connector->pipe;
-}
-
-extern void mdfld_dsi_gen_fifo_ready(struct drm_device *dev,
-				u32 gen_fifo_stat_reg, u32 fifo_stat);
-extern void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config,
-				int pipe);
-extern void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe,
-				int level);
-extern void mdfld_dsi_output_init(struct drm_device *dev, int pipe,
-				struct mdfld_dsi_config *config,
-				struct panel_funcs *p_cmd_funcs,
-				struct panel_funcs *p_vid_funcs);
-extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config,
-				int pipe);
-extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config,
-				u32 *mode,
-				u8 transmission);
-extern int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config,
-				u32 *result,
-				u8 transmission);
-extern int mdfld_dsi_panel_reset(int pipe);
-
-#endif /*__MDFLD_DSI_OUTPUT_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.c b/drivers/staging/gma500/mdfld_dsi_pkg_sender.c
deleted file mode 100644
index 9b96a5c..0000000
--- a/drivers/staging/gma500/mdfld_dsi_pkg_sender.c
+++ /dev/null
@@ -1,1484 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include <linux/freezer.h>
-
-#include "mdfld_dsi_output.h"
-#include "mdfld_dsi_pkg_sender.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-
-#define MDFLD_DSI_DBI_FIFO_TIMEOUT		100
-#define MDFLD_DSI_MAX_RETURN_PACKET_SIZE	512
-#define MDFLD_DSI_READ_MAX_COUNT		5000
-
-static const char * const dsi_errors[] = {
-	"RX SOT Error",
-	"RX SOT Sync Error",
-	"RX EOT Sync Error",
-	"RX Escape Mode Entry Error",
-	"RX LP TX Sync Error",
-	"RX HS Receive Timeout Error",
-	"RX False Control Error",
-	"RX ECC Single Bit Error",
-	"RX ECC Multibit Error",
-	"RX Checksum Error",
-	"RX DSI Data Type Not Recognised",
-	"RX DSI VC ID Invalid",
-	"TX False Control Error",
-	"TX ECC Single Bit Error",
-	"TX ECC Multibit Error",
-	"TX Checksum Error",
-	"TX DSI Data Type Not Recognised",
-	"TX DSI VC ID invalid",
-	"High Contention",
-	"Low contention",
-	"DPI FIFO Under run",
-	"HS TX Timeout",
-	"LP RX Timeout",
-	"Turn Around ACK Timeout",
-	"ACK With No Error",
-	"RX Invalid TX Length",
-	"RX Prot Violation",
-	"HS Generic Write FIFO Full",
-	"LP Generic Write FIFO Full",
-	"Generic Read Data Avail",
-	"Special Packet Sent",
-	"Tearing Effect",
-};
-
-static int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender,
-								u32 mask)
-{
-	struct drm_device *dev = sender->dev;
-	u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg;
-	int retry = 0xffff;
-
-	while (retry--) {
-		if ((mask & REG_READ(gen_fifo_stat_reg)) == mask)
-			return 0;
-		udelay(100);
-	}
-	dev_err(dev->dev, "fifo is NOT empty 0x%08x\n",
-					REG_READ(gen_fifo_stat_reg));
-	return -EIO;
-}
-
-static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
-	return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 10) | (1 << 18)
-		| (1 << 26) | (1 << 27) | (1 << 28));
-}
-
-static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
-	return wait_for_gen_fifo_empty(sender, (1 << 10) | (1 << 26));
-}
-
-static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
-{
-	return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 18));
-}
-
-static int wait_for_dbi_fifo_empty(struct mdfld_dsi_pkg_sender *sender)
-{
-	return wait_for_gen_fifo_empty(sender, (1 << 27));
-}
-
-static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
-{
-	u32 intr_stat_reg = sender->mipi_intr_stat_reg;
-	struct drm_device *dev = sender->dev;
-
-	switch (mask) {
-	case (1 << 0):
-	case (1 << 1):
-	case (1 << 2):
-	case (1 << 3):
-	case (1 << 4):
-	case (1 << 5):
-	case (1 << 6):
-	case (1 << 7):
-	case (1 << 8):
-	case (1 << 9):
-	case (1 << 10):
-	case (1 << 11):
-	case (1 << 12):
-	case (1 << 13):
-		break;
-	case (1 << 14):
-		/*wait for all fifo empty*/
-		/*wait_for_all_fifos_empty(sender)*/;
-		break;
-	case (1 << 15):
-		break;
-	case (1 << 16):
-		break;
-	case (1 << 17):
-		break;
-	case (1 << 18):
-	case (1 << 19):
-		/*wait for contention recovery time*/
-		/*mdelay(10);*/
-		/*wait for all fifo empty*/
-		if (0)
-			wait_for_all_fifos_empty(sender);
-		break;
-	case (1 << 20):
-		break;
-	case (1 << 21):
-		/*wait for all fifo empty*/
-		/*wait_for_all_fifos_empty(sender);*/
-		break;
-	case (1 << 22):
-		break;
-	case (1 << 23):
-	case (1 << 24):
-	case (1 << 25):
-	case (1 << 26):
-	case (1 << 27):
-		/* HS Gen fifo full */
-		REG_WRITE(intr_stat_reg, mask);
-		wait_for_hs_fifos_empty(sender);
-		break;
-	case (1 << 28):
-		/* LP Gen fifo full\n */
-		REG_WRITE(intr_stat_reg, mask);
-		wait_for_lp_fifos_empty(sender);
-		break;
-	case (1 << 29):
-	case (1 << 30):
-	case (1 << 31):
-		break;
-	}
-
-	if (mask & REG_READ(intr_stat_reg))
-		dev_warn(dev->dev, "Cannot clean interrupt 0x%08x\n", mask);
-
-	return 0;
-}
-
-static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender)
-{
-	struct drm_device *dev = sender->dev;
-	u32 intr_stat_reg = sender->mipi_intr_stat_reg;
-	u32 mask;
-	u32 intr_stat;
-	int i;
-	int err = 0;
-
-	intr_stat = REG_READ(intr_stat_reg);
-
-	for (i = 0; i < 32; i++) {
-		mask = (0x00000001UL) << i;
-		if (intr_stat & mask) {
-			dev_dbg(dev->dev, "[DSI]: %s\n", dsi_errors[i]);
-			err = handle_dsi_error(sender, mask);
-			if (err)
-				dev_err(dev->dev, "Cannot handle error\n");
-		}
-	}
-	return err;
-}
-
-static inline int dbi_cmd_sent(struct mdfld_dsi_pkg_sender *sender)
-{
-	struct drm_device *dev = sender->dev;
-	u32 retry = 0xffff;
-	u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg;
-
-	/* Query the command execution status */
-	while (retry--) {
-		if (!(REG_READ(dbi_cmd_addr_reg) & (1 << 0)))
-			break;
-	}
-
-	if (!retry) {
-		dev_err(dev->dev, "Timeout waiting for DBI Command status\n");
-		return -EAGAIN;
-	}
-	return 0;
-}
-
-/*
- * NOTE: this interface is abandoned expect for write_mem_start DCS
- * other DCS are sent via generic pkg interfaces
- */
-static int send_dcs_pkg(struct mdfld_dsi_pkg_sender *sender,
-			struct mdfld_dsi_pkg *pkg)
-{
-	struct drm_device *dev = sender->dev;
-	struct mdfld_dsi_dcs_pkg *dcs_pkg = &pkg->pkg.dcs_pkg;
-	u32 dbi_cmd_len_reg = sender->mipi_cmd_len_reg;
-	u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg;
-	u32 cb_phy = sender->dbi_cb_phy;
-	u32 index = 0;
-	u8 *cb = (u8 *)sender->dbi_cb_addr;
-	int i;
-	int ret;
-
-	if (!sender->dbi_pkg_support) {
-		dev_err(dev->dev, "Trying to send DCS on a non DBI output, abort!\n");
-		return -ENOTSUPP;
-	}
-
-	/*wait for DBI fifo empty*/
-	wait_for_dbi_fifo_empty(sender);
-
-	*(cb + (index++)) = dcs_pkg->cmd;
-	if (dcs_pkg->param_num) {
-		for (i = 0; i < dcs_pkg->param_num; i++)
-			*(cb + (index++)) = *(dcs_pkg->param + i);
-	}
-
-	REG_WRITE(dbi_cmd_len_reg, (1 + dcs_pkg->param_num));
-	REG_WRITE(dbi_cmd_addr_reg,
-		(cb_phy << CMD_MEM_ADDR_OFFSET)
-		| (1 << 0)
-		| ((dcs_pkg->data_src == CMD_DATA_SRC_PIPE) ? (1 << 1) : 0));
-
-	ret = dbi_cmd_sent(sender);
-	if (ret) {
-		dev_err(dev->dev, "command 0x%x not complete\n", dcs_pkg->cmd);
-		return -EAGAIN;
-	}
-	return 0;
-}
-
-static int __send_short_pkg(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg)
-{
-	struct drm_device *dev = sender->dev;
-	u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
-	u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
-	u32 gen_ctrl_val = 0;
-	struct mdfld_dsi_gen_short_pkg *short_pkg = &pkg->pkg.short_pkg;
-
-	gen_ctrl_val |= short_pkg->cmd << MCS_COMMANDS_POS;
-	gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS;
-	gen_ctrl_val |= pkg->pkg_type;
-	gen_ctrl_val |= short_pkg->param << MCS_PARAMETER_POS;
-
-	if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) {
-		/* wait for hs fifo empty */
-		/* wait_for_hs_fifos_empty(sender); */
-		/* Send pkg */
-		REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val);
-	} else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) {
-		/* wait_for_lp_fifos_empty(sender); */
-		/* Send pkg*/
-		REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val);
-	} else {
-		dev_err(dev->dev, "Unknown transmission type %d\n",
-							pkg->transmission_type);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int __send_long_pkg(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg)
-{
-	struct drm_device *dev = sender->dev;
-	u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
-	u32 hs_gen_data_reg = sender->mipi_hs_gen_data_reg;
-	u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
-	u32 lp_gen_data_reg = sender->mipi_lp_gen_data_reg;
-	u32 gen_ctrl_val = 0;
-	u32 *dp;
-	int i;
-	struct mdfld_dsi_gen_long_pkg *long_pkg = &pkg->pkg.long_pkg;
-
-	dp = long_pkg->data;
-
-	/*
-	 * Set up word count for long pkg
-	 * FIXME: double check word count field.
-	 * currently, using the byte counts of the payload as the word count.
-	 * ------------------------------------------------------------
-	 * | DI |   WC   | ECC|         PAYLOAD              |CHECKSUM|
-	 * ------------------------------------------------------------
-	 */
-	gen_ctrl_val |= (long_pkg->len << 2) << WORD_COUNTS_POS;
-	gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS;
-	gen_ctrl_val |= pkg->pkg_type;
-
-	if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) {
-		/* Wait for hs ctrl and data fifos to be empty */
-		/* wait_for_hs_fifos_empty(sender); */
-		for (i = 0; i < long_pkg->len; i++)
-			REG_WRITE(hs_gen_data_reg, *(dp + i));
-		REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val);
-	} else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) {
-		/* wait_for_lp_fifos_empty(sender); */
-		for (i = 0; i < long_pkg->len; i++)
-			REG_WRITE(lp_gen_data_reg, *(dp + i));
-		REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val);
-	} else {
-		dev_err(dev->dev, "Unknown transmission type %d\n",
-						pkg->transmission_type);
-		return -EINVAL;
-	}
-
-	return 0;
-
-}
-
-static int send_mcs_short_pkg(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg)
-{
-	return __send_short_pkg(sender, pkg);
-}
-
-static int send_mcs_long_pkg(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg)
-{
-	return __send_long_pkg(sender, pkg);
-}
-
-static int send_gen_short_pkg(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg)
-{
-	return __send_short_pkg(sender, pkg);
-}
-
-static int send_gen_long_pkg(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg)
-{
-	return __send_long_pkg(sender, pkg);
-}
-
-static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg)
-{
-	u8 cmd;
-	u8 *data;
-
-	switch (pkg->pkg_type) {
-	case MDFLD_DSI_PKG_DCS:
-		cmd = pkg->pkg.dcs_pkg.cmd;
-		break;
-	case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
-	case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
-		cmd = pkg->pkg.short_pkg.cmd;
-		break;
-	case MDFLD_DSI_PKG_MCS_LONG_WRITE:
-		data = (u8 *)pkg->pkg.long_pkg.data;
-		cmd = *data;
-		break;
-	default:
-		return 0;
-	}
-
-	/* This prevents other package sending while doing msleep */
-	sender->status = MDFLD_DSI_PKG_SENDER_BUSY;
-
-	/* Check panel mode v.s. sending command */
-	if ((sender->panel_mode & MDFLD_DSI_PANEL_MODE_SLEEP) &&
-		cmd != exit_sleep_mode) {
-		dev_err(sender->dev->dev,
-				"sending 0x%x when panel sleep in\n", cmd);
-		sender->status = MDFLD_DSI_PKG_SENDER_FREE;
-		return -EINVAL;
-	}
-
-	/* Wait for 120 milliseconds in case exit_sleep_mode just be sent */
-	if (cmd == DCS_ENTER_SLEEP_MODE) {
- 		/*TODO: replace it with msleep later*/
-		mdelay(120);
-	}
-	return 0;
-}
-
-static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg)
-{
-	u8 cmd;
-	u8 *data;
-
-	switch (pkg->pkg_type) {
-	case MDFLD_DSI_PKG_DCS:
-		cmd = pkg->pkg.dcs_pkg.cmd;
-		break;
-	case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
-	case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
-		cmd = pkg->pkg.short_pkg.cmd;
-		break;
-	case MDFLD_DSI_PKG_MCS_LONG_WRITE:
-		data = (u8 *)pkg->pkg.long_pkg.data;
-		cmd = *data;
-		break;
-	default:
-		return 0;
-	}
-
-	/* Update panel status */
-	if (cmd == DCS_ENTER_SLEEP_MODE) {
-		sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP;
-		/*TODO: replace it with msleep later*/
-		mdelay(120);
-	} else if (cmd == DCS_EXIT_SLEEP_MODE) {
-		sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
-		/*TODO: replace it with msleep later*/
-		mdelay(120);
-	} else if (unlikely(cmd == DCS_SOFT_RESET)) {
-		/*TODO: replace it with msleep later*/
-		mdelay(5);
- 	}
-	sender->status = MDFLD_DSI_PKG_SENDER_FREE;
-	return 0;
-
-}
-
-static int do_send_pkg(struct mdfld_dsi_pkg_sender *sender,
-			struct mdfld_dsi_pkg *pkg)
-{
-	int ret;
-
-	if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) {
-		dev_err(sender->dev->dev, "sender is busy\n");
-		return -EAGAIN;
-	}
-
-	ret = send_pkg_prepare(sender, pkg);
-	if (ret) {
-		dev_err(sender->dev->dev, "send_pkg_prepare error\n");
-		return ret;
-	}
-
-	switch (pkg->pkg_type) {
-	case MDFLD_DSI_PKG_DCS:
-		ret = send_dcs_pkg(sender, pkg);
-		break;
-	case MDFLD_DSI_PKG_GEN_SHORT_WRITE_0:
-	case MDFLD_DSI_PKG_GEN_SHORT_WRITE_1:
-	case MDFLD_DSI_PKG_GEN_SHORT_WRITE_2:
-	case MDFLD_DSI_PKG_GEN_READ_0:
-	case MDFLD_DSI_PKG_GEN_READ_1:
-	case MDFLD_DSI_PKG_GEN_READ_2:
-		ret = send_gen_short_pkg(sender, pkg);
-		break;
-	case MDFLD_DSI_PKG_GEN_LONG_WRITE:
-		ret = send_gen_long_pkg(sender, pkg);
-		break;
-	case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
-	case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
-	case MDFLD_DSI_PKG_MCS_READ:
-		ret = send_mcs_short_pkg(sender, pkg);
-		break;
-	case MDFLD_DSI_PKG_MCS_LONG_WRITE:
-		ret = send_mcs_long_pkg(sender, pkg);
-		break;
-	default:
-		dev_err(sender->dev->dev, "Invalid pkg type 0x%x\n",
-							pkg->pkg_type);
-		ret = -EINVAL;
-	}
-	send_pkg_done(sender, pkg);
-	return ret;
-}
-
-static int send_pkg(struct mdfld_dsi_pkg_sender *sender,
-			struct mdfld_dsi_pkg *pkg)
-{
-	int err ;
-
-	/* Handle DSI error */
-	err = dsi_error_handler(sender);
-	if (err) {
-		dev_err(sender->dev->dev, "Error handling failed\n");
-		err = -EAGAIN;
-		goto send_pkg_err;
-	}
-
-	/* Send pkg */
-	err = do_send_pkg(sender, pkg);
-	if (err) {
-		dev_err(sender->dev->dev, "sent pkg failed\n");
-		err = -EAGAIN;
-		goto send_pkg_err;
-	}
-
-	/* FIXME: should I query complete and fifo empty here? */
-send_pkg_err:
-	return err;
-}
-
-static struct mdfld_dsi_pkg *pkg_sender_get_pkg_locked(
-					struct mdfld_dsi_pkg_sender *sender)
-{
-	struct mdfld_dsi_pkg *pkg;
-
-	if (list_empty(&sender->free_list)) {
-		dev_err(sender->dev->dev, "No free pkg left\n");
-		return NULL;
-	}
-	pkg = list_first_entry(&sender->free_list, struct mdfld_dsi_pkg, entry);
-	/* Detach from free list */
-	list_del_init(&pkg->entry);
-	return pkg;
-}
-
-static void pkg_sender_put_pkg_locked(struct mdfld_dsi_pkg_sender *sender,
-					struct mdfld_dsi_pkg *pkg)
-{
-	memset(pkg, 0, sizeof(struct mdfld_dsi_pkg));
-	INIT_LIST_HEAD(&pkg->entry);
-	list_add_tail(&pkg->entry, &sender->free_list);
-}
-
-static int mdfld_dbi_cb_init(struct mdfld_dsi_pkg_sender *sender,
-					struct psb_gtt *pg, int pipe)
-{
-	unsigned long phys;
-	void *virt_addr = NULL;
-
-	switch (pipe) {
-	case 0:
-		/* FIXME: Doesn't this collide with stolen space ? */
-		phys = pg->gtt_phys_start - 0x1000;
-		break;
-	case 2:
-		phys = pg->gtt_phys_start - 0x800;
-		break;
-	default:
-		dev_err(sender->dev->dev, "Unsupported channel %d\n", pipe);
-		return -EINVAL;
-	}
-
-	virt_addr = ioremap_nocache(phys, 0x800);
-	if (!virt_addr) {
-		dev_err(sender->dev->dev, "Map DBI command buffer error\n");
-		return -ENOMEM;
-	}
-	sender->dbi_cb_phy = phys;
-	sender->dbi_cb_addr = virt_addr;
-	return 0;
-}
-
-static void mdfld_dbi_cb_destroy(struct mdfld_dsi_pkg_sender *sender)
-{
-	if (sender && sender->dbi_cb_addr)
-		iounmap(sender->dbi_cb_addr);
-}
-
-static void pkg_sender_queue_pkg(struct mdfld_dsi_pkg_sender *sender,
-					struct mdfld_dsi_pkg *pkg,
-					int delay)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sender->lock, flags);
-
-	if (!delay) {
-		send_pkg(sender, pkg);
-		pkg_sender_put_pkg_locked(sender, pkg);
-	} else {
-		/* Queue it */
-		list_add_tail(&pkg->entry, &sender->pkg_list);
-	}
-	spin_unlock_irqrestore(&sender->lock, flags);
-}
-
-static void process_pkg_list(struct mdfld_dsi_pkg_sender *sender)
-{
-	struct mdfld_dsi_pkg *pkg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sender->lock, flags);
-
-	while (!list_empty(&sender->pkg_list)) {
-		pkg = list_first_entry(&sender->pkg_list,
-					struct mdfld_dsi_pkg, entry);
-		send_pkg(sender, pkg);
-		list_del_init(&pkg->entry);
-		pkg_sender_put_pkg_locked(sender, pkg);
-	}
-
-	spin_unlock_irqrestore(&sender->lock, flags);
-}
-
-static int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender,
-	u32 *data, u32 len, u8 transmission, int delay)
-{
-	struct mdfld_dsi_pkg *pkg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sender->lock, flags);
-	pkg = pkg_sender_get_pkg_locked(sender);
-	spin_unlock_irqrestore(&sender->lock, flags);
-
-	if (!pkg) {
-		dev_err(sender->dev->dev, "No memory\n");
-		return -ENOMEM;
-	}
-	pkg->pkg_type = MDFLD_DSI_PKG_MCS_LONG_WRITE;
-	pkg->transmission_type = transmission;
-	pkg->pkg.long_pkg.data = data;
-	pkg->pkg.long_pkg.len = len;
-	INIT_LIST_HEAD(&pkg->entry);
-
-	pkg_sender_queue_pkg(sender, pkg, delay);
-	return 0;
-}
-
-static int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender,
-					u8 cmd, u8 param, u8 param_num,
-					u8 transmission,
-					int delay)
-{
-	struct mdfld_dsi_pkg *pkg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sender->lock, flags);
-	pkg = pkg_sender_get_pkg_locked(sender);
-	spin_unlock_irqrestore(&sender->lock, flags);
-
-	if (!pkg) {
-		dev_err(sender->dev->dev, "No memory\n");
-		return -ENOMEM;
-	}
-
-	if (param_num) {
-		pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_1;
-		pkg->pkg.short_pkg.param = param;
-	} else {
-		pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_0;
-		pkg->pkg.short_pkg.param = 0;
-	}
-	pkg->transmission_type = transmission;
-	pkg->pkg.short_pkg.cmd = cmd;
-	INIT_LIST_HEAD(&pkg->entry);
-
-	pkg_sender_queue_pkg(sender, pkg, delay);
-	return 0;
-}
-
-static int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender,
-					u8 param0, u8 param1, u8 param_num,
-					u8 transmission,
-					int delay)
-{
-	struct mdfld_dsi_pkg *pkg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sender->lock, flags);
-	pkg = pkg_sender_get_pkg_locked(sender);
-	spin_unlock_irqrestore(&sender->lock, flags);
-
-	if (!pkg) {
-		dev_err(sender->dev->dev, "No pkg memory\n");
-		return -ENOMEM;
-	}
-
-	switch (param_num) {
-	case 0:
-		pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_0;
-		pkg->pkg.short_pkg.cmd = 0;
-		pkg->pkg.short_pkg.param = 0;
-		break;
-	case 1:
-		pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_1;
-		pkg->pkg.short_pkg.cmd = param0;
-		pkg->pkg.short_pkg.param = 0;
-		break;
-	case 2:
-		pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_2;
-		pkg->pkg.short_pkg.cmd = param0;
-		pkg->pkg.short_pkg.param = param1;
-		break;
-	}
-
-	pkg->transmission_type = transmission;
-	INIT_LIST_HEAD(&pkg->entry);
-
-	pkg_sender_queue_pkg(sender, pkg, delay);
-	return 0;
-}
-
-static int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender,
-				u32 *data, u32 len, u8 transmission, int delay)
-{
-	struct mdfld_dsi_pkg *pkg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sender->lock, flags);
-	pkg = pkg_sender_get_pkg_locked(sender);
-	spin_unlock_irqrestore(&sender->lock, flags);
-
-	if (!pkg) {
-		dev_err(sender->dev->dev, "No pkg memory\n");
-		return -ENOMEM;
-	}
-
-	pkg->pkg_type = MDFLD_DSI_PKG_GEN_LONG_WRITE;
-	pkg->transmission_type = transmission;
-	pkg->pkg.long_pkg.data = data;
-	pkg->pkg.long_pkg.len = len;
-
-	INIT_LIST_HEAD(&pkg->entry);
-
-	pkg_sender_queue_pkg(sender, pkg, delay);
-
-	return 0;
-}
-
-static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender,
-				struct mdfld_dsi_pkg *pkg,
-				u32 *data,
-				u16 len)
-{
-	unsigned long flags;
-	struct drm_device *dev = sender->dev;
-	int i;
-	u32 gen_data_reg;
-	int retry = MDFLD_DSI_READ_MAX_COUNT;
-	u8 transmission = pkg->transmission_type;
-
-	/*
-	 * do reading.
-	 * 0) send out generic read request
-	 * 1) polling read data avail interrupt
-	 * 2) read data
-	 */
-	spin_lock_irqsave(&sender->lock, flags);
-
-	REG_WRITE(sender->mipi_intr_stat_reg, 1 << 29);
-
-	if ((REG_READ(sender->mipi_intr_stat_reg) & (1 << 29)))
-		DRM_ERROR("Can NOT clean read data valid interrupt\n");
-
-	/*send out read request*/
-	send_pkg(sender, pkg);
-
-	pkg_sender_put_pkg_locked(sender, pkg);
-
-	/*polling read data avail interrupt*/
-	while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & (1 << 29))) {
-		udelay(100);
-		retry--;
-	}
-
-	if (!retry) {
-		spin_unlock_irqrestore(&sender->lock, flags);
-		return -ETIMEDOUT;
-	}
-
-	REG_WRITE(sender->mipi_intr_stat_reg, (1 << 29));
-
-	/*read data*/
-	if (transmission == MDFLD_DSI_HS_TRANSMISSION)
-		gen_data_reg = sender->mipi_hs_gen_data_reg;
-	else if (transmission == MDFLD_DSI_LP_TRANSMISSION)
-		gen_data_reg = sender->mipi_lp_gen_data_reg;
-	else {
-		DRM_ERROR("Unknown transmission");
-		spin_unlock_irqrestore(&sender->lock, flags);
-		return -EINVAL;
-	}
-
-	for (i=0; i<len; i++)
-		*(data + i) = REG_READ(gen_data_reg);
-
- 	spin_unlock_irqrestore(&sender->lock, flags);
- 
-	return 0;
-}
-
-static int mdfld_dsi_read_gen(struct mdfld_dsi_pkg_sender *sender,
-				u8 param0,
-				u8 param1,
-				u8 param_num,
-				u32 *data,
-				u16 len,
-				u8 transmission)
-{
-	struct mdfld_dsi_pkg *pkg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sender->lock, flags);
-
-	pkg = pkg_sender_get_pkg_locked(sender);
-
-	spin_unlock_irqrestore(&sender->lock,flags);
-
-	if (!pkg) {
-		dev_err(sender->dev->dev, "No pkg memory\n");
-		return -ENOMEM;
-	}
-
-	switch (param_num) {
-	case 0:
-		pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_0;
-		pkg->pkg.short_pkg.cmd = 0;
-		pkg->pkg.short_pkg.param = 0;
-		break;
-	case 1:
-		pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_1;
-		pkg->pkg.short_pkg.cmd = param0;
-		pkg->pkg.short_pkg.param = 0;
-		break;
- 	case 2:
-		pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_2;
-		pkg->pkg.short_pkg.cmd = param0;
-		pkg->pkg.short_pkg.param = param1;
-		break;
-	}
-
-	pkg->transmission_type = transmission;
-
-	INIT_LIST_HEAD(&pkg->entry);
-
-	return __read_panel_data(sender, pkg, data, len);
-}
- 
-static int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender,
-				u8 cmd,
-				u32 *data,
-				u16 len,
-				u8 transmission)
-{
-	struct mdfld_dsi_pkg *pkg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sender->lock, flags);
-
-	pkg = pkg_sender_get_pkg_locked(sender);
-
- 	spin_unlock_irqrestore(&sender->lock, flags);
- 
- 	if (!pkg) {
-		dev_err(sender->dev->dev, "No pkg memory\n");
- 		return -ENOMEM;
-	}
-
-	pkg->pkg_type = MDFLD_DSI_PKG_MCS_READ;
-	pkg->pkg.short_pkg.cmd = cmd;
-	pkg->pkg.short_pkg.param = 0;
-
-	pkg->transmission_type = transmission;
- 
-	INIT_LIST_HEAD(&pkg->entry);
-
-	return __read_panel_data(sender, pkg, data, len);
-}
-
-void dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-	struct drm_device * dev = dsi_config->dev;
-	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-	int lane_count = dsi_config->lane_count;
-	u32 val = 0;
-
-	/*un-ready device*/
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
-	/*init dsi adapter before kicking off*/
-	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
-	/*TODO: figure out how to setup these registers*/
-	REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-	REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), 0x000a0014);
-	REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
-	REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
-	REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
-	/*enable all interrupts*/
-	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-	/*max value: 20 clock cycles of txclkesc*/
-	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
-	/*min 21 txclkesc, max: ffffh*/
-	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
-	/*min: 7d0 max: 4e20*/
-	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
-	/*set up max return packet size*/
-	REG_WRITE((MIPIA_MAX_RETURN_PACK_SIZE_REG + reg_offset),
-			MDFLD_DSI_MAX_RETURN_PACKET_SIZE);
-
-	/*set up func_prg*/
-	val |= lane_count;
-	val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
-	val |= DSI_DBI_COLOR_FORMAT_OPTION2;
-	REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
-	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
-	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
-	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-	REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-	REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-void dsi_controller_dpi_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-	struct drm_device * dev = dsi_config->dev;
-	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-	int lane_count = dsi_config->lane_count;
-	struct mdfld_dsi_dpi_timing dpi_timing;
-	struct drm_display_mode * mode = dsi_config->mode;
-	u32 val = 0;
-
-	/*un-ready device*/
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
-	/*init dsi adapter before kicking off*/
-	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
-	/*enable all interrupts*/
-	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-
-	/*set up func_prg*/
-	val |= lane_count;
-	val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
-
-	switch(dsi_config->bpp) {
-	case 16:
-		val |= DSI_DPI_COLOR_FORMAT_RGB565;
-		break;
-	case 18:
-		val |= DSI_DPI_COLOR_FORMAT_RGB666;
-		break;
-	case 24:
-		val |= DSI_DPI_COLOR_FORMAT_RGB888;
-		break;
-	default:
-		DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
-	}
-
-	REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
-	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset),
-			(mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
-	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
-
-	/*max value: 20 clock cycles of txclkesc*/
-	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
-
-	/*min 21 txclkesc, max: ffffh*/
-	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
-
-	REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
-
-	/*set DPI timing registers*/
-	mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
-
-	REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
-	REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
-
-	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-
-	/*min: 7d0 max: 4e20*/
-	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
-
-	/*set up video mode*/
-	val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
-	REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
-
-	REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
-
-	REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-
-	/*TODO: figure out how to setup these registers*/
-	REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
-
-	REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
-
-	/*set device ready*/
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-static void dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe)
-{
-	if (!dsi_config || ((pipe != 0) && (pipe != 2))) {
-		DRM_ERROR("Invalid parameters\n");
-		return;
-	}
-
-	if (dsi_config->type == MDFLD_DSI_ENCODER_DPI)
-		dsi_controller_dpi_init(dsi_config, pipe);
-	else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI)
-		dsi_controller_dbi_init(dsi_config, pipe);
-	else
-		DRM_ERROR("Bad DSI encoder type\n");
-}
-
-void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender)
-{
-	process_pkg_list(sender);
-}
-
-int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender,
-			u8 dcs, u8 *param, u32 param_num, u8 data_src,
-			int delay)
-{
-	struct mdfld_dsi_pkg *pkg;
-	u32 cb_phy = sender->dbi_cb_phy;
-	struct drm_device *dev = sender->dev;
-	u32 index = 0;
-	u8 *cb = (u8 *)sender->dbi_cb_addr;
-	unsigned long flags;
-	int retry;
-	u8 *dst = NULL;
-	u32 len;
-
-	if (!sender) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	if (!sender->dbi_pkg_support) {
-		dev_err(dev->dev, "No DBI pkg sending on this sender\n");
-		return -ENOTSUPP;
-	}
-
-	if (param_num > MDFLD_MAX_DCS_PARAM) {
-		dev_err(dev->dev, "Sender only supports up to %d DCS params\n",
-							MDFLD_MAX_DCS_PARAM);
-		return -EINVAL;
-	}
-
-	/*
-	 * If dcs is write_mem_start, send it directly using DSI adapter
-	 * interface
-	 */
-	if (dcs == DCS_WRITE_MEM_START) {
-		if (!spin_trylock(&sender->lock))
-			return -EAGAIN;
-
-		/*
-		 * query whether DBI FIFO is empty,
-		 * if not wait it becoming empty
-		 */
-		retry = MDFLD_DSI_DBI_FIFO_TIMEOUT;
-		while (retry &&
-		    !(REG_READ(sender->mipi_gen_fifo_stat_reg) & (1 << 27))) {
-			udelay(500);
-			retry--;
-		}
-
-		/* If DBI FIFO timeout, drop this frame */
-		if (!retry) {
-			spin_unlock(&sender->lock);
-			return 0;
-		}
-
-		*(cb + (index++)) = write_mem_start;
-
-		REG_WRITE(sender->mipi_cmd_len_reg, 1);
-		REG_WRITE(sender->mipi_cmd_addr_reg,
-					cb_phy | (1 << 0) | (1 << 1));
-
-		retry = MDFLD_DSI_DBI_FIFO_TIMEOUT;
-		while (retry &&
-			(REG_READ(sender->mipi_cmd_addr_reg) & (1 << 0))) {
-			udelay(1);
-			retry--;
-		}
-
-		spin_unlock(&sender->lock);
-		return 0;
-	}
-
-	/* Get a free pkg */
-	spin_lock_irqsave(&sender->lock, flags);
-	pkg = pkg_sender_get_pkg_locked(sender);
-	spin_unlock_irqrestore(&sender->lock, flags);
-
-	if (!pkg) {
-		dev_err(dev->dev, "No packages memory\n");
-		return -ENOMEM;
-	}
-
-	dst = pkg->pkg.dcs_pkg.param;
-	memcpy(dst, param, param_num);
-
-	pkg->pkg_type = MDFLD_DSI_PKG_DCS;
-	pkg->transmission_type = MDFLD_DSI_DCS;
-	pkg->pkg.dcs_pkg.cmd = dcs;
-	pkg->pkg.dcs_pkg.param_num = param_num;
-	pkg->pkg.dcs_pkg.data_src = data_src;
-
-	INIT_LIST_HEAD(&pkg->entry);
-
-	if (param_num == 0)
-		return mdfld_dsi_send_mcs_short_hs(sender, dcs, 0, 0, delay);
-	else if (param_num == 1)
-		return mdfld_dsi_send_mcs_short_hs(sender, dcs,
-							param[0], 1, delay);
-	else if (param_num > 1) {
-		len = (param_num + 1) / 4;
-		if ((param_num + 1) % 4)
-			len++;
-		return mdfld_dsi_send_mcs_long_hs(sender,
-				(u32 *)&pkg->pkg.dcs_pkg, len, delay);
-	}
-	return 0;
-}
-
-int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender,
-				u8 cmd, u8 param, u8 param_num, int delay)
-{
-	if (!sender) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-	return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num,
-					MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender,
-				u8 cmd, u8 param, u8 param_num, int delay)
-{
-	if (!sender) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-	return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num,
-					MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender,
-				u32 *data,
-				u32 len,
-				int delay)
-{
-	if (!sender || !data || !len) {
-		DRM_ERROR("Invalid parameters\n");
-		return -EINVAL;
-	}
-	return mdfld_dsi_send_mcs_long(sender, data, len,
-					MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender,
-				u32 *data,
-				u32 len,
-				int delay)
-{
-	if (!sender || !data || !len) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-	return mdfld_dsi_send_mcs_long(sender, data, len,
-				MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender,
-				u8 param0, u8 param1, u8 param_num, int delay)
-{
-	if (!sender) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-	return mdfld_dsi_send_gen_short(sender, param0, param1, param_num,
-					MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender,
-				u8 param0, u8 param1, u8 param_num, int delay)
-{
-	if (!sender || param_num < 0 || param_num > 2) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-	return mdfld_dsi_send_gen_short(sender, param0, param1, param_num,
-					MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
-				u32 *data,
-				u32 len,
-				int delay)
-{
-	if (!sender || !data || !len) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-	return mdfld_dsi_send_gen_long(sender, data, len,
-					MDFLD_DSI_HS_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
-				u32 *data,
-				u32 len,
-				int delay)
-{
-	if (!sender || !data || !len) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-	return mdfld_dsi_send_gen_long(sender, data, len,
-					MDFLD_DSI_LP_TRANSMISSION, delay);
-}
-
-int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender,
-			u8 param0,
-			u8 param1,
-			u8 param_num,
-			u32 *data,
-			u16 len)
-{
-	if (!sender || !data || param_num < 0 || param_num > 2
-		|| !data || !len) {
-		DRM_ERROR("Invalid parameters\n");
-		return -EINVAL;
-	}
-
-	return mdfld_dsi_read_gen(sender, param0, param1, param_num,
-				data, len, MDFLD_DSI_HS_TRANSMISSION);
-
-}
-
-int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender,
-			u8 param0,
-			u8 param1,
-			u8 param_num,
-			u32 *data,
-			u16 len)
-{
-	if (!sender || !data || param_num < 0 || param_num > 2
-		|| !data || !len) {
-		DRM_ERROR("Invalid parameters\n");
-		return -EINVAL;
-	}
-
-	return mdfld_dsi_read_gen(sender, param0, param1, param_num,
-				data, len, MDFLD_DSI_LP_TRANSMISSION);
-}
-
-int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender,
-			u8 cmd,
-			u32 *data,
-			u16 len)
-{
-	if (!sender || !data || !len) {
-		DRM_ERROR("Invalid parameters\n");
-		return -EINVAL;
-	}
-
-	return mdfld_dsi_read_mcs(sender, cmd, data, len,
-				MDFLD_DSI_HS_TRANSMISSION);
-}
-
-int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender,
-			u8 cmd,
-			u32 *data,
-			u16 len)
-{
-	if (!sender || !data || !len) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	return mdfld_dsi_read_mcs(sender, cmd, data, len,
-				MDFLD_DSI_LP_TRANSMISSION);
-}
- 
-int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
-								int pipe)
-{
-	int ret;
-	struct mdfld_dsi_pkg_sender *pkg_sender;
-	struct mdfld_dsi_config *dsi_config =
-					mdfld_dsi_get_config(dsi_connector);
-	struct drm_device *dev = dsi_config->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_gtt *pg = &dev_priv->gtt;
-	int i;
-	struct mdfld_dsi_pkg *pkg, *tmp;
-	u32 mipi_val = 0;
-
-	if (!dsi_connector) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	pkg_sender = dsi_connector->pkg_sender;
-
-	if (!pkg_sender || IS_ERR(pkg_sender)) {
-		pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
-								GFP_KERNEL);
-		if (!pkg_sender) {
-			dev_err(dev->dev, "Create DSI pkg sender failed\n");
-			return -ENOMEM;
-		}
-
-		dsi_connector->pkg_sender = (void *)pkg_sender;
-	}
-
-	pkg_sender->dev = dev;
-	pkg_sender->dsi_connector = dsi_connector;
-	pkg_sender->pipe = pipe;
-	pkg_sender->pkg_num = 0;
-	pkg_sender->panel_mode = 0;
-	pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;
-
-	/* Init dbi command buffer*/
-
-	if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
-		pkg_sender->dbi_pkg_support = 1;
-		ret = mdfld_dbi_cb_init(pkg_sender, pg, pipe);
-		if (ret) {
-			dev_err(dev->dev, "DBI command buffer map failed\n");
-			goto mapping_err;
-		}
-	}
-
-	/* Init regs */
-	if (pipe == 0) {
-		pkg_sender->dpll_reg = MRST_DPLL_A;
-		pkg_sender->dspcntr_reg = DSPACNTR;
-		pkg_sender->pipeconf_reg = PIPEACONF;
-		pkg_sender->dsplinoff_reg = DSPALINOFF;
-		pkg_sender->dspsurf_reg = DSPASURF;
-		pkg_sender->pipestat_reg = PIPEASTAT;
-
-		pkg_sender->mipi_intr_stat_reg = MIPIA_INTR_STAT_REG;
-		pkg_sender->mipi_lp_gen_data_reg = MIPIA_LP_GEN_DATA_REG;
-		pkg_sender->mipi_hs_gen_data_reg = MIPIA_HS_GEN_DATA_REG;
-		pkg_sender->mipi_lp_gen_ctrl_reg = MIPIA_LP_GEN_CTRL_REG;
-		pkg_sender->mipi_hs_gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
-		pkg_sender->mipi_gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
-		pkg_sender->mipi_data_addr_reg = MIPIA_DATA_ADD_REG;
-		pkg_sender->mipi_data_len_reg = MIPIA_DATA_LEN_REG;
-		pkg_sender->mipi_cmd_addr_reg = MIPIA_CMD_ADD_REG;
-		pkg_sender->mipi_cmd_len_reg = MIPIA_CMD_LEN_REG;
-	} else if (pipe == 2) {
-		pkg_sender->dpll_reg = MRST_DPLL_A;
-		pkg_sender->dspcntr_reg = DSPCCNTR;
-		pkg_sender->pipeconf_reg = PIPECCONF;
-		pkg_sender->dsplinoff_reg = DSPCLINOFF;
-		pkg_sender->dspsurf_reg = DSPCSURF;
-		pkg_sender->pipestat_reg = PIPECSTAT;
-
-		pkg_sender->mipi_intr_stat_reg =
-				MIPIA_INTR_STAT_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_lp_gen_data_reg =
-				MIPIA_LP_GEN_DATA_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_hs_gen_data_reg =
-				MIPIA_HS_GEN_DATA_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_lp_gen_ctrl_reg =
-				MIPIA_LP_GEN_CTRL_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_hs_gen_ctrl_reg =
-				MIPIA_HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_gen_fifo_stat_reg =
-				MIPIA_GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_data_addr_reg =
-				MIPIA_DATA_ADD_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_data_len_reg =
-				MIPIA_DATA_LEN_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_cmd_addr_reg =
-				MIPIA_CMD_ADD_REG + MIPIC_REG_OFFSET;
-		pkg_sender->mipi_cmd_len_reg =
-				MIPIA_CMD_LEN_REG + MIPIC_REG_OFFSET;
-	}
-
-	/* Init pkg list */
-	INIT_LIST_HEAD(&pkg_sender->pkg_list);
-	INIT_LIST_HEAD(&pkg_sender->free_list);
-
-	spin_lock_init(&pkg_sender->lock);
-
-	/* Allocate free pkg pool */
-	for (i = 0; i < MDFLD_MAX_PKG_NUM; i++) {
-		pkg = kzalloc(sizeof(struct mdfld_dsi_pkg), GFP_KERNEL);
-		if (!pkg) {
-			dev_err(dev->dev, "Out of memory allocating pkg pool");
-			ret = -ENOMEM;
-			goto pkg_alloc_err;
-		}
-		INIT_LIST_HEAD(&pkg->entry);
-		list_add_tail(&pkg->entry, &pkg_sender->free_list);
-	}
-
-	/*
-	 * For video mode, don't enable DPI timing output here,
-	 * will init the DPI timing output during mode setting.
-	 */
-	if (dsi_config->type == MDFLD_DSI_ENCODER_DPI)
-		mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
-	else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI)
-		mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX
-			| TE_TRIGGER_GPIO_PIN;
-	else
-		DRM_ERROR("Bad DSI encoder type\n");
-
-	if (pipe == 0) {
-		mipi_val |= 0x2;
-		REG_WRITE(MIPI, mipi_val);
-		REG_READ(MIPI);
-	} else if (pipe == 2) {
-		REG_WRITE(MIPI_C, mipi_val);
-		REG_READ(MIPI_C);
-	}
-
-	/*do dsi controller init*/
-	dsi_controller_init(dsi_config, pipe);
-	
-	return 0;
-
-pkg_alloc_err:
-	list_for_each_entry_safe(pkg, tmp, &pkg_sender->free_list, entry) {
-		list_del(&pkg->entry);
-		kfree(pkg);
-	}
-
-	/* Free mapped command buffer */
-	mdfld_dbi_cb_destroy(pkg_sender);
-mapping_err:
-	kfree(pkg_sender);
-	dsi_connector->pkg_sender = NULL;
-	return ret;
-}
-
-void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender)
-{
-	struct mdfld_dsi_pkg *pkg, *tmp;
-
-	if (!sender || IS_ERR(sender))
-		return;
-
-	/* Free pkg pool */
-	list_for_each_entry_safe(pkg, tmp, &sender->free_list, entry) {
-		list_del(&pkg->entry);
-		kfree(pkg);
-	}
-	/* Free pkg list */
-	list_for_each_entry_safe(pkg, tmp, &sender->pkg_list, entry) {
-		list_del(&pkg->entry);
-		kfree(pkg);
-	}
-	mdfld_dbi_cb_destroy(sender);	/* free mapped command buffer */
-	kfree(sender);
-}
diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.h b/drivers/staging/gma500/mdfld_dsi_pkg_sender.h
deleted file mode 100644
index f24abc7..0000000
--- a/drivers/staging/gma500/mdfld_dsi_pkg_sender.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jackie Li<yaodong.li@intel.com>
- */
-#ifndef __MDFLD_DSI_PKG_SENDER_H__
-#define __MDFLD_DSI_PKG_SENDER_H__
-
-#include <linux/kthread.h>
-
-#define MDFLD_MAX_DCS_PARAM	8
-#define MDFLD_MAX_PKG_NUM	2048
-
-enum {
-	MDFLD_DSI_PKG_DCS,
-	MDFLD_DSI_PKG_GEN_SHORT_WRITE_0 = 0x03,
-	MDFLD_DSI_PKG_GEN_SHORT_WRITE_1 = 0x13,
-	MDFLD_DSI_PKG_GEN_SHORT_WRITE_2 = 0x23,
-	MDFLD_DSI_PKG_GEN_READ_0 = 0x04,
-	MDFLD_DSI_PKG_GEN_READ_1 = 0x14,
-	MDFLD_DSI_PKG_GEN_READ_2 = 0x24,
-	MDFLD_DSI_PKG_GEN_LONG_WRITE = 0x29,
-	MDFLD_DSI_PKG_MCS_SHORT_WRITE_0 = 0x05,
-	MDFLD_DSI_PKG_MCS_SHORT_WRITE_1 = 0x15,
-	MDFLD_DSI_PKG_MCS_READ = 0x06,
-	MDFLD_DSI_PKG_MCS_LONG_WRITE = 0x39,
-};
-
-enum {
-	MDFLD_DSI_LP_TRANSMISSION,
-	MDFLD_DSI_HS_TRANSMISSION,
-	MDFLD_DSI_DCS,
-};
-
-enum {
-	MDFLD_DSI_PANEL_MODE_SLEEP = 0x1,
-};
-
-enum {
-	MDFLD_DSI_PKG_SENDER_FREE = 0x0,
-	MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
-};
-
-enum {
-	MDFLD_DSI_SEND_PACKAGE,
-	MDFLD_DSI_QUEUE_PACKAGE,
-};
-
-struct mdfld_dsi_gen_short_pkg {
-	u8 cmd;
-	u8 param;
-};
-
-struct mdfld_dsi_gen_long_pkg {
-	u32 *data;
-	u32 len;
-};
-
-struct mdfld_dsi_dcs_pkg {
-	u8 cmd;
-	u8 param[MDFLD_MAX_DCS_PARAM];
-	u32 param_num;
-	u8 data_src;
-};
-
-struct mdfld_dsi_pkg {
-	u8 pkg_type;
-	u8 transmission_type;
-
-	union {
-		struct mdfld_dsi_gen_short_pkg short_pkg;
-		struct mdfld_dsi_gen_long_pkg long_pkg;
-		struct mdfld_dsi_dcs_pkg dcs_pkg;
-	} pkg;
-
-	struct list_head entry;
-};
-
-struct mdfld_dsi_pkg_sender {
-	struct drm_device *dev;
-	struct mdfld_dsi_connector *dsi_connector;
-	u32 status;
-
-	u32 panel_mode;
-
-	int pipe;
-
-	spinlock_t lock;
-	struct list_head pkg_list;
-	struct list_head free_list;
-
-	u32 pkg_num;
-
-	int dbi_pkg_support;
-
-	u32 dbi_cb_phy;
-	void *dbi_cb_addr;
-
-	/* Registers */
-	u32 dpll_reg;
-	u32 dspcntr_reg;
-	u32 pipeconf_reg;
-	u32 pipestat_reg;
-	u32 dsplinoff_reg;
-	u32 dspsurf_reg;
-
-	u32 mipi_intr_stat_reg;
-	u32 mipi_lp_gen_data_reg;
-	u32 mipi_hs_gen_data_reg;
-	u32 mipi_lp_gen_ctrl_reg;
-	u32 mipi_hs_gen_ctrl_reg;
-	u32 mipi_gen_fifo_stat_reg;
-	u32 mipi_data_addr_reg;
-	u32 mipi_data_len_reg;
-	u32 mipi_cmd_addr_reg;
-	u32 mipi_cmd_len_reg;
-};
-
-/* DCS definitions */
-#define DCS_SOFT_RESET			0x01
-#define DCS_ENTER_SLEEP_MODE		0x10
-#define DCS_EXIT_SLEEP_MODE		0x11
-#define DCS_SET_DISPLAY_OFF		0x28
-#define DCS_SET_DISPLAY_ON		0x29
-#define DCS_SET_COLUMN_ADDRESS		0x2a
-#define DCS_SET_PAGE_ADDRESS		0x2b
-#define DCS_WRITE_MEM_START		0x2c
-#define DCS_SET_TEAR_OFF		0x34
-#define DCS_SET_TEAR_ON 		0x35
-
-extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
-			int pipe);
-extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender);
-extern int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender, u8 dcs,
-			u8 *param, u32 param_num, u8 data_src, int delay);
-extern int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender,
-			u8 cmd, u8 param, u8 param_num, int delay);
-extern int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender,
-			u8 cmd, u8 param, u8 param_num, int delay);
-extern int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender,
-			u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender,
-			u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender,
-			u8 param0, u8 param1, u8 param_num, int delay);
-extern int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender,
-			u8 param0, u8 param1, u8 param_num, int delay);
-extern int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
-			u32 *data, u32 len, int delay);
-extern int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
-			u32 *data, u32 len, int delay);
-
-extern int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender,
-			u8 param0, u8 param1, u8 param_num, u32 *data, u16 len);
-extern int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender,
-			u8 param0, u8 param1, u8 param_num, u32 *data, u16 len);
-extern int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender,
-			u8 cmd, u32 *data, u16 len);
-extern int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender,
-			u8 cmd, u32 *data, u16 len);
-
-extern void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender);
-
-#endif /* __MDFLD_DSI_PKG_SENDER_H__ */
diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c
deleted file mode 100644
index 0b37b7b..0000000
--- a/drivers/staging/gma500/mdfld_intel_display.c
+++ /dev/null
@@ -1,1404 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- */
-
-#include "framebuffer.h"
-#include "psb_intel_display.h"
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_dbi_dpu.h"
-
-#include <linux/pm_runtime.h>
-
-#ifdef MIN
-#undef MIN
-#endif
-
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-
-/* Hardcoded currently */
-static int ksel = KSEL_CRYSTAL_19;
-
-extern void mdfld_save_display(struct drm_device *dev);
-extern bool gbgfxsuspended;
-
-struct psb_intel_range_t {
-	int min, max;
-};
-
-struct mdfld_limit_t {
-	struct psb_intel_range_t dot, m, p1;
-};
-
-struct mdfld_intel_clock_t {
-	/* given values */
-	int n;
-	int m1, m2;
-	int p1, p2;
-	/* derived values */
-	int dot;
-	int vco;
-	int m;
-	int p;
-};
-
-
-
-#define COUNT_MAX 0x10000000
-
-void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
-{
-	int count, temp;
-	u32 pipeconf_reg = PIPEACONF;
-	
-	switch (pipe) {
-	case 0:
-		break;
-	case 1:
-		pipeconf_reg = PIPEBCONF;
-		break;
-	case 2:
-		pipeconf_reg = PIPECCONF;
-		break;
-	default:
-		DRM_ERROR("Illegal Pipe Number. \n");
-		return;
-	}
-
-	/* FIXME JLIU7_PO */
-	psb_intel_wait_for_vblank(dev);
-	return;
-
-	/* Wait for for the pipe disable to take effect. */
-	for (count = 0; count < COUNT_MAX; count++) {
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_PIPE_STATE) == 0)
-			break;
-	}
-}
-
-void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
-{
-	int count, temp;
-	u32 pipeconf_reg = PIPEACONF;
-	
-	switch (pipe) {
-	case 0:
-		break;
-	case 1:
-		pipeconf_reg = PIPEBCONF;
-		break;
-	case 2:
-		pipeconf_reg = PIPECCONF;
-		break;
-	default:
-		dev_err(dev->dev, "Illegal Pipe Number.\n");
-		return;
-	}
-
-	/* FIXME JLIU7_PO */
-	psb_intel_wait_for_vblank(dev);
-	return;
-
-	/* Wait for for the pipe enable to take effect. */
-	for (count = 0; count < COUNT_MAX; count++) {
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_PIPE_STATE) == 1)
-			break;
-	}
-}
-
-
-static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
-				 struct drm_file *file_priv,
-				 uint32_t handle,
-				 uint32_t width, uint32_t height)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	uint32_t control = CURACNTR;
-	uint32_t base = CURABASE;
-	uint32_t temp;
-	size_t addr = 0;
-	struct gtt_range *gt;
-	struct drm_gem_object *obj;
-	int ret;
-
-	switch (pipe) {
-	case 0:
-		break;
-	case 1:
-		control = CURBCNTR;
-		base = CURBBASE;
-		break;
-	case 2:
-		control = CURCCNTR;
-		base = CURCBASE;
-		break;
-	default:
-		dev_err(dev->dev, "Illegal Pipe Number. \n");
-		return -EINVAL;
-	}
-	
-#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
-	if (pipe != 0)
-		return 0;
-#endif 
-	/* if we want to turn of the cursor ignore width and height */
-	if (!handle) {
-		dev_dbg(dev->dev, "cursor off\n");
-		/* turn off the cursor */
-		temp = 0;
-		temp |= CURSOR_MODE_DISABLE;
-
-		if (gma_power_begin(dev, true)) {
-			REG_WRITE(control, temp);
-			REG_WRITE(base, 0);
-			gma_power_end(dev);
-		}
-		/* Unpin the old GEM object */
-		if (psb_intel_crtc->cursor_obj) {
-			gt = container_of(psb_intel_crtc->cursor_obj,
-							struct gtt_range, gem);
-			psb_gtt_unpin(gt);
-			drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-			psb_intel_crtc->cursor_obj = NULL;
-		}
-		return 0;
-	}
-
-	/* Currently we only support 64x64 cursors */
-	if (width != 64 || height != 64) {
-		DRM_ERROR("we currently only support 64x64 cursors\n");
-		return -EINVAL;
-	}
-
-	obj = drm_gem_object_lookup(dev, file_priv, handle);
-	if (!obj)
-		return -ENOENT;
-
-	if (obj->size < width * height * 4) {
-		dev_dbg(dev->dev, "buffer is to small\n");
-		return -ENOMEM;
-	}
-
-	gt = container_of(obj, struct gtt_range, gem);
-
-	/* Pin the memory into the GTT */
-	ret = psb_gtt_pin(gt);
-	if (ret) {
-		dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-		return ret;
-	}
-
-
-	addr = gt->offset;	/* Or resource.start ??? */
-
-	psb_intel_crtc->cursor_addr = addr;
-
-	temp = 0;
-	/* set the pipe for the cursor */
-	temp |= (pipe << 28);
-	temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-
-	if (gma_power_begin(dev, true)) {
-		REG_WRITE(control, temp);
-		REG_WRITE(base, addr);
-		gma_power_end(dev);
-	}
-	/* unpin the old GEM object */
-	if (psb_intel_crtc->cursor_obj) {
-		gt = container_of(psb_intel_crtc->cursor_obj,
-							struct gtt_range, gem);
-		psb_gtt_unpin(gt);
-		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-		psb_intel_crtc->cursor_obj = obj;
-	}
-	return 0;
-}
-
-static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
-	struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
-	struct psb_drm_dpu_rect rect;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	uint32_t pos = CURAPOS;
-	uint32_t base = CURABASE;
-	uint32_t temp = 0;
-	uint32_t addr;
-
-	switch (pipe) {
-	case 0:
-		if (dpu_info) {
-			rect.x = x;
-			rect.y = y;
-		
-			mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect);
-			mdfld_dpu_exit_dsr(dev);
-		} else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0))
-			mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_0);
-		break;
-	case 1:
-		pos = CURBPOS;
-		base = CURBBASE;
-		break;
-	case 2:
-		if (dpu_info) {
-			mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect);
-			mdfld_dpu_exit_dsr(dev);
-		} else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2))
-			mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_2);
-		pos = CURCPOS;
-		base = CURCBASE;
-		break;
-	default:
-		DRM_ERROR("Illegal Pipe Number. \n");
-		return -EINVAL;
-	}
-		
-#if 1 /* FIXME_JLIU7 can't enable cursorB/C HW issue. need to remove after HW fix */
-	if (pipe != 0)
-		return 0;
-#endif 
-	if (x < 0) {
-		temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
-		x = -x;
-	}
-	if (y < 0) {
-		temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
-		y = -y;
-	}
-
-	temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
-	temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
-	addr = psb_intel_crtc->cursor_addr;
-
-	if (gma_power_begin(dev, true)) {
-		REG_WRITE(pos, temp);
-		REG_WRITE(base, addr);
-		gma_power_end(dev);
-	}
-
-	return 0;
-}
-
-const struct drm_crtc_funcs mdfld_intel_crtc_funcs = {
-	.cursor_set = mdfld_intel_crtc_cursor_set,
-	.cursor_move = mdfld_intel_crtc_cursor_move,
-	.gamma_set = psb_intel_crtc_gamma_set,
-	.set_config = drm_crtc_helper_set_config,
-	.destroy = psb_intel_crtc_destroy,
-};
-
-static struct drm_device globle_dev;
-
-void mdfld__intel_plane_set_alpha(int enable)
-{
-	struct drm_device *dev = &globle_dev;
-	int dspcntr_reg = DSPACNTR;
-	u32 dspcntr;
-
-	dspcntr = REG_READ(dspcntr_reg);
-
-	if (enable) {
-		dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
-		dspcntr |= DISPPLANE_32BPP;
-	} else {
-		dspcntr &= ~DISPPLANE_32BPP;
-		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-	}
-
-	REG_WRITE(dspcntr_reg, dspcntr);
-}
-
-int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	/* struct drm_i915_master_private *master_priv; */
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-	int pipe = psb_intel_crtc->pipe;
-	unsigned long start, offset;
-	int dsplinoff = DSPALINOFF;
-	int dspsurf = DSPASURF;
-	int dspstride = DSPASTRIDE;
-	int dspcntr_reg = DSPACNTR;
-	u32 dspcntr;
-	int ret = 0;
-
-	memcpy(&globle_dev, dev, sizeof(struct drm_device));
-
-	if (!gma_power_begin(dev, true))
-		return 0;
-
-	/* no fb bound */
-	if (!crtc->fb) {
-		dev_err(dev->dev, "No FB bound\n");
-		goto psb_intel_pipe_cleaner;
-	}
-
-	switch (pipe) {
-	case 0:
-		dsplinoff = DSPALINOFF;
-		break;
-	case 1:
-		dsplinoff = DSPBLINOFF;
-		dspsurf = DSPBSURF;
-		dspstride = DSPBSTRIDE;
-		dspcntr_reg = DSPBCNTR;
-		break;
-	case 2:
-		dsplinoff = DSPCLINOFF;
-		dspsurf = DSPCSURF;
-		dspstride = DSPCSTRIDE;
-		dspcntr_reg = DSPCCNTR;
-		break;
-	default:
-		dev_err(dev->dev, "Illegal Pipe Number.\n");
-		return -EINVAL;
-	}
-
-	ret = psb_gtt_pin(psbfb->gtt);
-	if (ret < 0)
-	        goto psb_intel_pipe_set_base_exit;
-
-	start = psbfb->gtt->offset;
-	offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
-	REG_WRITE(dspstride, crtc->fb->pitches[0]);
-	dspcntr = REG_READ(dspcntr_reg);
-	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
-	switch (crtc->fb->bits_per_pixel) {
-	case 8:
-		dspcntr |= DISPPLANE_8BPP;
-		break;
-	case 16:
-		if (crtc->fb->depth == 15)
-			dspcntr |= DISPPLANE_15_16BPP;
-		else
-			dspcntr |= DISPPLANE_16BPP;
-		break;
-	case 24:
-	case 32:
-		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-		break;
-	default:
-		dev_err(dev->dev, "Unknown color depth\n");
-		ret = -EINVAL;
-		goto psb_intel_pipe_set_base_exit;
-	}
-	REG_WRITE(dspcntr_reg, dspcntr);
-
-	dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
-	                                        start, offset, x, y);
-
-	REG_WRITE(dsplinoff, offset);
-	REG_READ(dsplinoff);
-	REG_WRITE(dspsurf, start);
-	REG_READ(dspsurf);
-
-psb_intel_pipe_cleaner:
-	/* If there was a previous display we can now unpin it */
-	if (old_fb)
-		psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
-
-psb_intel_pipe_set_base_exit:
-	gma_power_end(dev);
-	return ret;
-}
-
-/**
- * Disable the pipe, plane and pll.
- *
- */
-void mdfld_disable_crtc (struct drm_device *dev, int pipe)
-{
-	int dpll_reg = MRST_DPLL_A;
-	int dspcntr_reg = DSPACNTR;
-	int dspbase_reg = MRST_DSPABASE;
-	int pipeconf_reg = PIPEACONF;
-	u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
-	u32 temp;
-
-	switch (pipe) {
-	case 0:
-		break;
-	case 1:
-		dpll_reg = MDFLD_DPLL_B;
-		dspcntr_reg = DSPBCNTR;
-		dspbase_reg = DSPBSURF;
-		pipeconf_reg = PIPEBCONF;
-		break;
-	case 2:
-		dpll_reg = MRST_DPLL_A;
-		dspcntr_reg = DSPCCNTR;
-		dspbase_reg = MDFLD_DSPCBASE;
-		pipeconf_reg = PIPECCONF;
-		gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
-		break;
-	default:
-		dev_err(dev->dev, "Illegal Pipe Number. \n");
-		return;
-	}
-
-	if (pipe != 1)
-		mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
-	/* Disable display plane */
-	temp = REG_READ(dspcntr_reg);
-	if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-		REG_WRITE(dspcntr_reg,
-			  temp & ~DISPLAY_PLANE_ENABLE);
-		/* Flush the plane changes */
-		REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-		REG_READ(dspbase_reg);
-	}
-
-	/* FIXME_JLIU7 MDFLD_PO revisit */
-	/* Wait for vblank for the disable to take effect */
-/* MDFLD_PO_JLIU7		psb_intel_wait_for_vblank(dev); */
-
-	/* Next, disable display pipes */
-	temp = REG_READ(pipeconf_reg);
-	if ((temp & PIPEACONF_ENABLE) != 0) {
-		temp &= ~PIPEACONF_ENABLE;
-		temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
-		REG_WRITE(pipeconf_reg, temp);
-		REG_READ(pipeconf_reg);
-
-		/* Wait for for the pipe disable to take effect. */
-		mdfldWaitForPipeDisable(dev, pipe);
-	}
-
-	temp = REG_READ(dpll_reg);
-	if (temp & DPLL_VCO_ENABLE) {
-		if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
-				|| (pipe == 1)){
-			temp &= ~(DPLL_VCO_ENABLE);
-			REG_WRITE(dpll_reg, temp);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to turn off. */
-			/* FIXME_MDFLD PO may need more delay */
-			udelay(500);
-
-			if (!(temp & MDFLD_PWR_GATE_EN)) {
-				/* gating power of DPLL */
-				REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
-				/* FIXME_MDFLD PO - change 500 to 1 after PO */
-				udelay(5000);
-			}
-		}
-	}
-
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	int dpll_reg = MRST_DPLL_A;
-	int dspcntr_reg = DSPACNTR;
-	int dspbase_reg = MRST_DSPABASE;
-	int pipeconf_reg = PIPEACONF;
-	u32 pipestat_reg = PIPEASTAT;
-	u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
-	u32 pipeconf = dev_priv->pipeconf;
-	u32 dspcntr = dev_priv->dspcntr;
-	u32 mipi_enable_reg = MIPIA_DEVICE_READY_REG;
-	u32 temp;
-	bool enabled;
-	int timeout = 0;
-
-	if (!gma_power_begin(dev, true))
-		return;
-
-	 /* Ignore if system is already in DSR and in suspended state. */
-	if(/*gbgfxsuspended */0 && dev_priv->dispstatus == false && mode == 3){
-	    if(dev_priv->rpm_enabled && pipe == 1){
-	//          dev_priv->is_mipi_on = false;
-	          pm_request_idle(&dev->pdev->dev);
-	    }
-	    return;
-	}else if(mode == 0) {
-		//do not need to set gbdispstatus=true in crtc.
-		//this will be set in encoder such as mdfld_dsi_dbi_dpms
-	    //gbdispstatus = true;
-	}
-
-/* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
-/* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
-
-	switch (pipe) {
-	case 0:
-		break;
-	case 1:
-		dpll_reg = DPLL_B;
-		dspcntr_reg = DSPBCNTR;
-		dspbase_reg = MRST_DSPBBASE;
-		pipeconf_reg = PIPEBCONF;
-		pipeconf = dev_priv->pipeconf1;
-		dspcntr = dev_priv->dspcntr1;
-		dpll_reg = MDFLD_DPLL_B;
-		break;
-	case 2:
-		dpll_reg = MRST_DPLL_A;
-		dspcntr_reg = DSPCCNTR;
-		dspbase_reg = MDFLD_DSPCBASE;
-		pipeconf_reg = PIPECCONF;
-		pipestat_reg = PIPECSTAT;
-		pipeconf = dev_priv->pipeconf2;
-		dspcntr = dev_priv->dspcntr2;
-		gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
-		mipi_enable_reg = MIPIA_DEVICE_READY_REG + MIPIC_REG_OFFSET;
-		break;
-	default:
-		dev_err(dev->dev, "Illegal Pipe Number.\n");
-		return;
-	}
-
-	/* XXX: When our outputs are all unaware of DPMS modes other than off
-	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-	 */
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-		/* Enable the DPLL */
-		temp = REG_READ(dpll_reg);
-
-		if ((temp & DPLL_VCO_ENABLE) == 0) {
-			/* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
-			if (temp & MDFLD_PWR_GATE_EN) {
-				temp &= ~MDFLD_PWR_GATE_EN;
-				REG_WRITE(dpll_reg, temp);
-				/* FIXME_MDFLD PO - change 500 to 1 after PO */
-				udelay(500);
-			}
-
-			REG_WRITE(dpll_reg, temp);
-			REG_READ(dpll_reg);
-			/* FIXME_MDFLD PO - change 500 to 1 after PO */
-			udelay(500);
-			
-			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-
-			/**
-			 * wait for DSI PLL to lock
-			 * NOTE: only need to poll status of pipe 0 and pipe 1,
-			 * since both MIPI pipes share the same PLL.
-			 */
-			while ((pipe != 2) && (timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
-				udelay(150);
-				timeout ++;
-			}
-		}
-
-		/* Enable the plane */
-		temp = REG_READ(dspcntr_reg);
-		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-			REG_WRITE(dspcntr_reg,
-				temp | DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-		}
-
-		/* Enable the pipe */
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_ENABLE) == 0) {
-			REG_WRITE(pipeconf_reg, pipeconf);
-
-			/* Wait for for the pipe enable to take effect. */
-			mdfldWaitForPipeEnable(dev, pipe);
-		}
-
-		/*workaround for sighting 3741701 Random X blank display*/
-		/*perform w/a in video mode only on pipe A or C*/
-		if ((pipe == 0 || pipe == 2) &&
-			(mdfld_panel_dpi(dev) == true)) {
-			REG_WRITE(pipestat_reg, REG_READ(pipestat_reg));
-			msleep(100);
-			if(PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) {
-				printk(KERN_ALERT "OK");
-			} else {
-				printk(KERN_ALERT "STUCK!!!!");
-				/*shutdown controller*/
-				temp = REG_READ(dspcntr_reg);
-				REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
-				REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-				/*mdfld_dsi_dpi_shut_down(dev, pipe);*/
-				REG_WRITE(0xb048, 1);
-				msleep(100);
-				temp = REG_READ(pipeconf_reg);
-				temp &= ~PIPEACONF_ENABLE;
-				REG_WRITE(pipeconf_reg, temp);
-				msleep(100); /*wait for pipe disable*/
-			/*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
-			printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));*/
-				REG_WRITE(mipi_enable_reg, 0);
-				msleep(100);
-			printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
-			printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));
-				REG_WRITE(0xb004, REG_READ(0xb004));
-				/* try to bring the controller back up again*/
-				REG_WRITE(mipi_enable_reg, 1);
-				temp = REG_READ(dspcntr_reg);
-				REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
-				REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-				/*mdfld_dsi_dpi_turn_on(dev, pipe);*/
-				REG_WRITE(0xb048, 2);
-				msleep(100);
-				temp = REG_READ(pipeconf_reg);
-				temp |= PIPEACONF_ENABLE;
-				REG_WRITE(pipeconf_reg, temp);
-			}
-		}
-
-		psb_intel_crtc_load_lut(crtc);
-
-		/* Give the overlay scaler a chance to enable
-		   if it's on this pipe */
-		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
-
-		break;
-	case DRM_MODE_DPMS_OFF:
-		/* Give the overlay scaler a chance to disable
-		 * if it's on this pipe */
-		/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-		if (pipe != 1)
-			mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
-		/* Disable the VGA plane that we never use */
-		REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-		/* Disable display plane */
-		temp = REG_READ(dspcntr_reg);
-		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-			REG_WRITE(dspcntr_reg,
-				  temp & ~DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-			REG_READ(dspbase_reg);
-		}
-
-		/* FIXME_JLIU7 MDFLD_PO revisit */
-		/* Wait for vblank for the disable to take effect */
-// MDFLD_PO_JLIU7		psb_intel_wait_for_vblank(dev);
-
-		/* Next, disable display pipes */
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_ENABLE) != 0) {
-			temp &= ~PIPEACONF_ENABLE;
-			temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
-			REG_WRITE(pipeconf_reg, temp);
-//			REG_WRITE(pipeconf_reg, 0);
-			REG_READ(pipeconf_reg);
-
-			/* Wait for for the pipe disable to take effect. */
-			mdfldWaitForPipeDisable(dev, pipe);
-		}
-
-		temp = REG_READ(dpll_reg);
-		if (temp & DPLL_VCO_ENABLE) {
-			if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
-					|| (pipe == 1)){
-				temp &= ~(DPLL_VCO_ENABLE);
-				REG_WRITE(dpll_reg, temp);
-				REG_READ(dpll_reg);
-				/* Wait for the clocks to turn off. */
-				/* FIXME_MDFLD PO may need more delay */
-				udelay(500);
-#if 0 /* MDFLD_PO_JLIU7 */	
-		if (!(temp & MDFLD_PWR_GATE_EN)) {
-			/* gating power of DPLL */
-			REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
-			/* FIXME_MDFLD PO - change 500 to 1 after PO */
-			udelay(5000);
-		}
-#endif  /* MDFLD_PO_JLIU7 */	
-			}
-		}
-		break;
-	}
-
-	enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-
-#if 0				/* JB: Add vblank support later */
-	if (enabled)
-		dev_priv->vblank_pipe |= (1 << pipe);
-	else
-		dev_priv->vblank_pipe &= ~(1 << pipe);
-#endif
-
-	gma_power_end(dev);
-}
-
-
-#define MDFLD_LIMT_DPLL_19	    0
-#define MDFLD_LIMT_DPLL_25	    1
-#define MDFLD_LIMT_DPLL_83	    2
-#define MDFLD_LIMT_DPLL_100	    3
-#define MDFLD_LIMT_DSIPLL_19	    4
-#define MDFLD_LIMT_DSIPLL_25	    5
-#define MDFLD_LIMT_DSIPLL_83	    6
-#define MDFLD_LIMT_DSIPLL_100	    7
-
-#define MDFLD_DOT_MIN		  19750  /* FIXME_MDFLD JLIU7 need to find out  min & max for MDFLD */
-#define MDFLD_DOT_MAX		  120000
-#define MDFLD_DPLL_M_MIN_19	    113
-#define MDFLD_DPLL_M_MAX_19	    155
-#define MDFLD_DPLL_P1_MIN_19	    2
-#define MDFLD_DPLL_P1_MAX_19	    10
-#define MDFLD_DPLL_M_MIN_25	    101
-#define MDFLD_DPLL_M_MAX_25	    130
-#define MDFLD_DPLL_P1_MIN_25	    2
-#define MDFLD_DPLL_P1_MAX_25	    10
-#define MDFLD_DPLL_M_MIN_83	    64
-#define MDFLD_DPLL_M_MAX_83	    64
-#define MDFLD_DPLL_P1_MIN_83	    2
-#define MDFLD_DPLL_P1_MAX_83	    2
-#define MDFLD_DPLL_M_MIN_100	    64
-#define MDFLD_DPLL_M_MAX_100	    64
-#define MDFLD_DPLL_P1_MIN_100	    2
-#define MDFLD_DPLL_P1_MAX_100	    2
-#define MDFLD_DSIPLL_M_MIN_19	    131
-#define MDFLD_DSIPLL_M_MAX_19	    175
-#define MDFLD_DSIPLL_P1_MIN_19	    3
-#define MDFLD_DSIPLL_P1_MAX_19	    8
-#define MDFLD_DSIPLL_M_MIN_25	    97
-#define MDFLD_DSIPLL_M_MAX_25	    140
-#define MDFLD_DSIPLL_P1_MIN_25	    3
-#define MDFLD_DSIPLL_P1_MAX_25	    9
-#define MDFLD_DSIPLL_M_MIN_83	    33
-#define MDFLD_DSIPLL_M_MAX_83	    92
-#define MDFLD_DSIPLL_P1_MIN_83	    2
-#define MDFLD_DSIPLL_P1_MAX_83	    3
-#define MDFLD_DSIPLL_M_MIN_100	    97
-#define MDFLD_DSIPLL_M_MAX_100	    140
-#define MDFLD_DSIPLL_P1_MIN_100	    3
-#define MDFLD_DSIPLL_P1_MAX_100	    9
-
-static const struct mdfld_limit_t mdfld_limits[] = {
-	{			/* MDFLD_LIMT_DPLL_19 */
-	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-	 .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19},
-	 .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19},
-	 },
-	{			/* MDFLD_LIMT_DPLL_25 */
-	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-	 .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25},
-	 .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25},
-	 },
-	{			/* MDFLD_LIMT_DPLL_83 */
-	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-	 .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83},
-	 .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83},
-	 },
-	{			/* MDFLD_LIMT_DPLL_100 */
-	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-	 .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100},
-	 .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100},
-	 },
-	{			/* MDFLD_LIMT_DSIPLL_19 */
-	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-	 .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19},
-	 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19},
-	 },
-	{			/* MDFLD_LIMT_DSIPLL_25 */
-	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-	 .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25},
-	 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25},
-	 },
-	{			/* MDFLD_LIMT_DSIPLL_83 */
-	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-	 .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83},
-	 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83},
-	 },
-	{			/* MDFLD_LIMT_DSIPLL_100 */
-	 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
-	 .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100},
-	 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100},
-	 },
-};
-
-#define MDFLD_M_MIN	    21
-#define MDFLD_M_MAX	    180
-static const u32 mdfld_m_converts[] = {
-/* M configuration table from 9-bit LFSR table */
-	224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
-	173, 342, 171, 85, 298, 149, 74, 37, 18, 265,   /* 31 - 40 */
-	388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
-	83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
-	341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
-	461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
-	106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
-	71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
-	253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
-	478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
-	477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
-	210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
-	145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
-	380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
-	103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
-	396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
-};
-
-static const struct mdfld_limit_t *mdfld_limit(struct drm_crtc *crtc)
-{
-	const struct mdfld_limit_t *limit = NULL;
-	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)
-	    || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) {
-		if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
-			limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19];
-		else if (ksel == KSEL_BYPASS_25) 
-			limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25];
-		else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
-			limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83];
-		else if ((ksel == KSEL_BYPASS_83_100) &&
-			 (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
-			limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100];
-	} else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
-		if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
-			limit = &mdfld_limits[MDFLD_LIMT_DPLL_19];
-		else if (ksel == KSEL_BYPASS_25) 
-			limit = &mdfld_limits[MDFLD_LIMT_DPLL_25];
-		else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
-			limit = &mdfld_limits[MDFLD_LIMT_DPLL_83];
-		else if ((ksel == KSEL_BYPASS_83_100) &&
-			 (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
-			limit = &mdfld_limits[MDFLD_LIMT_DPLL_100];
-	} else {
-		limit = NULL;
-		dev_err(dev->dev, "mdfld_limit Wrong display type.\n");
-	}
-
-	return limit;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-static void mdfld_clock(int refclk, struct mdfld_intel_clock_t *clock)
-{
-	clock->dot = (refclk * clock->m) / clock->p1;
-}
-
-/**
- * Returns a set of divisors for the desired target clock with the given refclk,
- * or FALSE.  Divisor values are the actual divisors for
- */
-static bool
-mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
-		struct mdfld_intel_clock_t *best_clock)
-{
-	struct mdfld_intel_clock_t clock;
-	const struct mdfld_limit_t *limit = mdfld_limit(crtc);
-	int err = target;
-
-	memset(best_clock, 0, sizeof(*best_clock));
-
-	for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
-		for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
-		     clock.p1++) {
-			int this_err;
-
-			mdfld_clock(refclk, &clock);
-
-			this_err = abs(clock.dot - target);
-			if (this_err < err) {
-				*best_clock = clock;
-				err = this_err;
-			}
-		}
-	}
-	return err != target;
-}
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int mdfld_panel_fitter_pipe(struct drm_device *dev)
-{
-	u32 pfit_control;
-
-	pfit_control = REG_READ(PFIT_CONTROL);
-
-	/* See if the panel fitter is in use */
-	if ((pfit_control & PFIT_ENABLE) == 0)
-		return -1;
-	return (pfit_control >> 29) & 3;
-}
-
-static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
-			      struct drm_display_mode *mode,
-			      struct drm_display_mode *adjusted_mode,
-			      int x, int y,
-			      struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int pipe = psb_intel_crtc->pipe;
-	int fp_reg = MRST_FPA0;
-	int dpll_reg = MRST_DPLL_A;
-	int dspcntr_reg = DSPACNTR;
-	int pipeconf_reg = PIPEACONF;
-	int htot_reg = HTOTAL_A;
-	int hblank_reg = HBLANK_A;
-	int hsync_reg = HSYNC_A;
-	int vtot_reg = VTOTAL_A;
-	int vblank_reg = VBLANK_A;
-	int vsync_reg = VSYNC_A;
-	int dspsize_reg = DSPASIZE; 
-	int dsppos_reg = DSPAPOS; 
-	int pipesrc_reg = PIPEASRC;
-	u32 *pipeconf = &dev_priv->pipeconf;
-	u32 *dspcntr = &dev_priv->dspcntr;
-	int refclk = 0;
-	int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, clk_tmp = 0;
-	struct mdfld_intel_clock_t clock;
-	bool ok;
-	u32 dpll = 0, fp = 0;
-	bool is_crt = false, is_lvds = false, is_tv = false;
-	bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
-	struct drm_mode_config *mode_config = &dev->mode_config;
-	struct psb_intel_output *psb_intel_output = NULL;
-	uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
-	struct drm_encoder *encoder;
-	struct drm_connector *connector;
-	int timeout = 0;
-
-	dev_dbg(dev->dev, "pipe = 0x%x \n", pipe);
-
-	switch (pipe) {
-	case 0:
-		break;
-	case 1:
-		fp_reg = FPB0;
-		dpll_reg = DPLL_B;
-		dspcntr_reg = DSPBCNTR;
-		pipeconf_reg = PIPEBCONF;
-		htot_reg = HTOTAL_B;
-		hblank_reg = HBLANK_B;
-		hsync_reg = HSYNC_B;
-		vtot_reg = VTOTAL_B;
-		vblank_reg = VBLANK_B;
-		vsync_reg = VSYNC_B;
-		dspsize_reg = DSPBSIZE; 
-		dsppos_reg = DSPBPOS; 
-		pipesrc_reg = PIPEBSRC;
-		pipeconf = &dev_priv->pipeconf1;
-		dspcntr = &dev_priv->dspcntr1;
-		fp_reg = MDFLD_DPLL_DIV0;
-		dpll_reg = MDFLD_DPLL_B;
-		break;
-	case 2:
-		dpll_reg = MRST_DPLL_A;
-		dspcntr_reg = DSPCCNTR;
-		pipeconf_reg = PIPECCONF;
-		htot_reg = HTOTAL_C;
-		hblank_reg = HBLANK_C;
-		hsync_reg = HSYNC_C;
-		vtot_reg = VTOTAL_C;
-		vblank_reg = VBLANK_C;
-		vsync_reg = VSYNC_C;
-		dspsize_reg = DSPCSIZE; 
-		dsppos_reg = DSPCPOS; 
-		pipesrc_reg = PIPECSRC;
-		pipeconf = &dev_priv->pipeconf2;
-		dspcntr = &dev_priv->dspcntr2;
-		break;
-	default:
-		DRM_ERROR("Illegal Pipe Number. \n");
-		return 0;
-	}
-
-	dev_dbg(dev->dev, "adjusted_hdisplay = %d\n",
-		 adjusted_mode->hdisplay);
-	dev_dbg(dev->dev, "adjusted_vdisplay = %d\n",
-		 adjusted_mode->vdisplay);
-	dev_dbg(dev->dev, "adjusted_hsync_start = %d\n",
-		 adjusted_mode->hsync_start);
-	dev_dbg(dev->dev, "adjusted_hsync_end = %d\n",
-		 adjusted_mode->hsync_end);
-	dev_dbg(dev->dev, "adjusted_htotal = %d\n",
-		 adjusted_mode->htotal);
-	dev_dbg(dev->dev, "adjusted_vsync_start = %d\n",
-		 adjusted_mode->vsync_start);
-	dev_dbg(dev->dev, "adjusted_vsync_end = %d\n",
-		 adjusted_mode->vsync_end);
-	dev_dbg(dev->dev, "adjusted_vtotal = %d\n",
-		 adjusted_mode->vtotal);
-	dev_dbg(dev->dev, "adjusted_clock = %d\n",
-		 adjusted_mode->clock);
-	dev_dbg(dev->dev, "hdisplay = %d\n",
-		 mode->hdisplay);
-	dev_dbg(dev->dev, "vdisplay = %d\n",
-		 mode->vdisplay);
-
-	if (!gma_power_begin(dev, true))
-		return 0;
-
-	memcpy(&psb_intel_crtc->saved_mode, mode, sizeof(struct drm_display_mode));
-	memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode, sizeof(struct drm_display_mode));
-
-	list_for_each_entry(connector, &mode_config->connector_list, head) {
-			
-		encoder = connector->encoder;
-		
-		if(!encoder)
-			continue;
-
-		if (encoder->crtc != crtc)
-			continue;
-
-		psb_intel_output = to_psb_intel_output(connector);
-		
-		dev_dbg(dev->dev, "output->type = 0x%x \n", psb_intel_output->type);
-
-		switch (psb_intel_output->type) {
-		case INTEL_OUTPUT_LVDS:
-			is_lvds = true;
-			break;
-		case INTEL_OUTPUT_TVOUT:
-			is_tv = true;
-			break;
-		case INTEL_OUTPUT_ANALOG:
-			is_crt = true;
-			break;
-		case INTEL_OUTPUT_MIPI:
-			is_mipi = true;
-			break;
-		case INTEL_OUTPUT_MIPI2:
-			is_mipi2 = true;
-			break;
-		case INTEL_OUTPUT_HDMI:
-			is_hdmi = true;
-			break;
-		}
-	}
-
-	/* Disable the VGA plane that we never use */
-	REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-	/* Disable the panel fitter if it was on our pipe */
-	if (mdfld_panel_fitter_pipe(dev) == pipe)
-		REG_WRITE(PFIT_CONTROL, 0);
-
-	/* pipesrc and dspsize control the size that is scaled from,
-	 * which should always be the user's requested size.
-	 */
-	if (pipe == 1) {
-		/* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite
-		 * width/height and souce image size registers with the adjusted mode for pipe B. */
-
-		/* The defined sprite rectangle must always be completely contained within the displayable
-		 * area of the screen image (frame buffer). */
-		REG_WRITE(dspsize_reg, ((MIN(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16)
-				| (MIN(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1));
-		/* Set the CRTC with encoder mode. */
-		REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16)
-				 | (mode->crtc_vdisplay - 1));
-	} else {
-		REG_WRITE(dspsize_reg, ((mode->crtc_vdisplay - 1) << 16) | (mode->crtc_hdisplay - 1));
-		REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
-	}
-
-	REG_WRITE(dsppos_reg, 0);
-
-	if (psb_intel_output)
-		drm_connector_property_get_value(&psb_intel_output->base,
-			dev->mode_config.scaling_mode_property, &scalingType);
-
-	if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
-		/*
-		 *	Medfield doesn't have register support for centering so
-		 *	we need to mess with the h/vblank and h/vsync start and
-		 *	ends to get central
-		 */
-		int offsetX = 0, offsetY = 0;
-
-		offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
-		offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
-
-		REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
-			((adjusted_mode->crtc_htotal - 1) << 16));
-		REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
-			((adjusted_mode->crtc_vtotal - 1) << 16));
-		REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) |
-			((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
-		REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) |
-			((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
-		REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) |
-			((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
-		REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) |
-			((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
-	} else {
-		REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
-			((adjusted_mode->crtc_htotal - 1) << 16));
-		REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
-			((adjusted_mode->crtc_vtotal - 1) << 16));
-		REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
-			((adjusted_mode->crtc_hblank_end - 1) << 16));
-		REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
-			((adjusted_mode->crtc_hsync_end - 1) << 16));
-		REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
-			((adjusted_mode->crtc_vblank_end - 1) << 16));
-		REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
-			((adjusted_mode->crtc_vsync_end - 1) << 16));
-	}
-
-	/* Flush the plane changes */
-	{
-		struct drm_crtc_helper_funcs *crtc_funcs =
-		    crtc->helper_private;
-		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-	}
-
-	/* setup pipeconf */
-	*pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
-
-	/* Set up the display plane register */
- 	*dspcntr = REG_READ(dspcntr_reg);
-	*dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS;
-	*dspcntr |= DISPLAY_PLANE_ENABLE;
-/* MDFLD_PO_JLIU7	dspcntr |= DISPPLANE_BOTTOM; */
-/* MDFLD_PO_JLIU7	dspcntr |= DISPPLANE_GAMMA_ENABLE; */
-
-	if (is_mipi2)
-	{
-		goto mrst_crtc_mode_set_exit;
-	}
-/* FIXME JLIU7 Add MDFLD HDMI supports */
-/* FIXME_MDFLD JLIU7 DSIPLL clock *= 8? */
-/* FIXME_MDFLD JLIU7 need to revist for dual MIPI supports */
-	clk = adjusted_mode->clock;
-
-	if (is_hdmi) {
-		if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
-		{
-			refclk = 19200;
-
-			if (is_mipi || is_mipi2)
-			{
-				clk_n = 1, clk_p2 = 8;
-			} else if (is_hdmi) {
-				clk_n = 1, clk_p2 = 10;
-			}
-		} else if (ksel == KSEL_BYPASS_25) { 
-			refclk = 25000;
-
-			if (is_mipi || is_mipi2)
-			{
-				clk_n = 1, clk_p2 = 8;
-			} else if (is_hdmi) {
-				clk_n = 1, clk_p2 = 10;
-			}
-		} else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) {
-			refclk = 83000;
-
-			if (is_mipi || is_mipi2)
-			{
-				clk_n = 4, clk_p2 = 8;
-			} else if (is_hdmi) {
-				clk_n = 4, clk_p2 = 10;
-			}
-		} else if ((ksel == KSEL_BYPASS_83_100) &&
-			   (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) {
-			refclk = 100000;
-			if (is_mipi || is_mipi2)
-			{
-				clk_n = 4, clk_p2 = 8;
-			} else if (is_hdmi) {
-				clk_n = 4, clk_p2 = 10;
-			}
-		}
-
-		if (is_mipi)
-			clk_byte = dev_priv->bpp / 8;
-		else if (is_mipi2)
-			clk_byte = dev_priv->bpp2 / 8;
-	
-		clk_tmp = clk * clk_n * clk_p2 * clk_byte;
-
-		dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d. \n", clk, clk_n, clk_p2);
-		dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d. \n", adjusted_mode->clock, clk_tmp);
-
-		ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
-
-		if (!ok) {
-			dev_err(dev->dev, 
-			   "mdfldFindBestPLL fail in mdfld_crtc_mode_set. \n");
-		} else {
-			m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)];
-
-			dev_dbg(dev->dev, "dot clock = %d,"
-				 "m = %d, p1 = %d, m_conv = %d. \n", clock.dot, clock.m,
-				 clock.p1, m_conv);
-		}
-
-		dpll = REG_READ(dpll_reg);
-
-		if (dpll & DPLL_VCO_ENABLE) {
-			dpll &= ~DPLL_VCO_ENABLE;
-			REG_WRITE(dpll_reg, dpll);
-			REG_READ(dpll_reg);
-
-			/* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
-			/* FIXME_MDFLD PO - change 500 to 1 after PO */
-			udelay(500);
-
-			/* reset M1, N1 & P1 */
-			REG_WRITE(fp_reg, 0);
-			dpll &= ~MDFLD_P1_MASK;
-			REG_WRITE(dpll_reg, dpll);
-			/* FIXME_MDFLD PO - change 500 to 1 after PO */
-			udelay(500);
-		}
-
-		/* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
-		if (dpll & MDFLD_PWR_GATE_EN) {
-			dpll &= ~MDFLD_PWR_GATE_EN;
-			REG_WRITE(dpll_reg, dpll);
-			/* FIXME_MDFLD PO - change 500 to 1 after PO */
-			udelay(500);
-		}	
-
-		dpll = 0; 
-
-#if 0 /* FIXME revisit later */
-		if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19) || (ksel == KSEL_BYPASS_25)) {
-			dpll &= ~MDFLD_INPUT_REF_SEL;	
-		} else if (ksel == KSEL_BYPASS_83_100) { 
-			dpll |= MDFLD_INPUT_REF_SEL;	
-		}
-#endif /* FIXME revisit later */
-
-		if (is_hdmi)
-			dpll |= MDFLD_VCO_SEL;	
-
-		fp = (clk_n / 2) << 16;
-		fp |= m_conv; 
-
-		/* compute bitmask from p1 value */
-		dpll |= (1 << (clock.p1 - 2)) << 17;
-
-#if 0 /* 1080p30 & 720p */
-        	dpll = 0x00050000;
-        	fp = 0x000001be;
-#endif 
-#if 0 /* 480p */
-        	dpll = 0x02010000;
-        	fp = 0x000000d2;
-#endif 
-	} else {
-#if 0 /*DBI_TPO_480x864*/
-		dpll = 0x00020000;
-		fp = 0x00000156; 
-#endif /* DBI_TPO_480x864 */ /* get from spec. */
-
-        	dpll = 0x00800000;
-	        fp = 0x000000c1;
-}
-
-	REG_WRITE(fp_reg, fp);
-	REG_WRITE(dpll_reg, dpll);
-	/* FIXME_MDFLD PO - change 500 to 1 after PO */
-	udelay(500);
-
-	dpll |= DPLL_VCO_ENABLE;
-	REG_WRITE(dpll_reg, dpll);
-	REG_READ(dpll_reg);
-
-	/* wait for DSI PLL to lock */
-	while ((timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
-		udelay(150);
-		timeout ++;
-	}
-
-	if (is_mipi)
-		goto mrst_crtc_mode_set_exit;
-
-	dev_dbg(dev->dev, "is_mipi = 0x%x \n", is_mipi);
-
-	REG_WRITE(pipeconf_reg, *pipeconf);
-	REG_READ(pipeconf_reg);
-
-	/* Wait for for the pipe enable to take effect. */
-//FIXME_JLIU7 HDMI	mrstWaitForPipeEnable(dev);
-
-	REG_WRITE(dspcntr_reg, *dspcntr);
-	psb_intel_wait_for_vblank(dev);
-
-mrst_crtc_mode_set_exit:
-
-	gma_power_end(dev);
-
-	return 0;
-}
-
-static void mdfld_crtc_prepare(struct drm_crtc *crtc)
-{
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void mdfld_crtc_commit(struct drm_crtc *crtc)
-{
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-static bool mdfld_crtc_mode_fixup(struct drm_crtc *crtc,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-const struct drm_crtc_helper_funcs mdfld_helper_funcs = {
-	.dpms = mdfld_crtc_dpms,
-	.mode_fixup = mdfld_crtc_mode_fixup,
-	.mode_set = mdfld_crtc_mode_set,
-	.mode_set_base = mdfld__intel_pipe_set_base,
-	.prepare = mdfld_crtc_prepare,
-	.commit = mdfld_crtc_commit,
-};
diff --git a/drivers/staging/gma500/mdfld_msic.h b/drivers/staging/gma500/mdfld_msic.h
deleted file mode 100644
index a7ad6547..0000000
--- a/drivers/staging/gma500/mdfld_msic.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *	Jim Liu <jim.liu@intel.com>
- */
-
-#define MSIC_PCI_DEVICE_ID	0x831
-
-int msic_regsiter_driver(void);
-int msic_unregister_driver(void);
-extern void hpd_notify_um(void);
diff --git a/drivers/staging/gma500/mdfld_output.c b/drivers/staging/gma500/mdfld_output.c
deleted file mode 100644
index eabf53d..0000000
--- a/drivers/staging/gma500/mdfld_output.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-
-#include "displays/tpo_cmd.h"
-#include "displays/tpo_vid.h"
-#include "displays/tmd_cmd.h"
-#include "displays/tmd_vid.h"
-#include "displays/pyr_cmd.h"
-#include "displays/pyr_vid.h"
-/* #include "displays/hdmi.h" */
-
-static int mdfld_dual_mipi;
-static int mdfld_hdmi;
-static int mdfld_dpu;
-
-module_param(mdfld_dual_mipi, int, 0600);
-MODULE_PARM_DESC(mdfld_dual_mipi, "Enable dual MIPI configuration");
-module_param(mdfld_hdmi, int, 0600);
-MODULE_PARM_DESC(mdfld_hdmi, "Enable Medfield HDMI");
-module_param(mdfld_dpu, int, 0600);
-MODULE_PARM_DESC(mdfld_dpu, "Enable Medfield DPU");
-
-/* For now a single type per device is all we cope with */
-int mdfld_get_panel_type(struct drm_device *dev, int pipe)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	return dev_priv->panel_id;
-}
-
-int mdfld_panel_dpi(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	switch (dev_priv->panel_id) {
-	case TMD_VID:
-	case TPO_VID:
-	case PYR_VID:
-		return true;
-	case TMD_CMD:
-	case TPO_CMD:
-	case PYR_CMD:
-	default:
-		return false;
-	}
-}
-
-static int init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
-{
-	struct panel_funcs *p_cmd_funcs;
-	struct panel_funcs *p_vid_funcs;
-
-	/* Oh boy ... FIXME */
-	p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
-	if (p_cmd_funcs == NULL)
-		return -ENODEV;
-	p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
-	if (p_vid_funcs == NULL) {
-		kfree(p_cmd_funcs);
-		return -ENODEV;
-	}
-
-	switch (p_type) {
-	case TPO_CMD:
-		tpo_cmd_init(dev, p_cmd_funcs);
-		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
-		break;
-	case TPO_VID:
-		tpo_vid_init(dev, p_vid_funcs);
-		mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
-		break;
-	case TMD_CMD:
-		/*tmd_cmd_init(dev, p_cmd_funcs); */
-		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
-		break;
-	case TMD_VID:
-		tmd_vid_init(dev, p_vid_funcs);
-		mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
-		break;
-	case PYR_CMD:
-		pyr_cmd_init(dev, p_cmd_funcs);
-		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
-		break;
-	case PYR_VID:
-		mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
-		break;
-	case TPO:	/* TPO panel supports both cmd & vid interfaces */
-		tpo_cmd_init(dev, p_cmd_funcs);
-		tpo_vid_init(dev, p_vid_funcs);
-		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs,
-				      p_vid_funcs);
-		break;
-	case TMD:
-		break;
-	case PYR:
-		break;
-#if 0
-	case HDMI:
-		dev_dbg(dev->dev, "Initializing HDMI");
-		mdfld_hdmi_init(dev, &dev_priv->mode_dev);
-		break;
-#endif
-	default:
-		dev_err(dev->dev, "Unsupported interface %d", p_type);
-		return -ENODEV;
-	}
-	return 0;
-}
-
-int mdfld_output_init(struct drm_device *dev)
-{
-	int type;
-
-	/* MIPI panel 1 */
-	type = mdfld_get_panel_type(dev, 0);
-	dev_info(dev->dev, "panel 1: type is %d\n", type);
-	init_panel(dev, 0, type);
-
-	if (mdfld_dual_mipi) {
-		/* MIPI panel 2 */
-		type = mdfld_get_panel_type(dev, 2);
-		dev_info(dev->dev, "panel 2: type is %d\n", type);
-		init_panel(dev, 2, type);
-	}
-	if (mdfld_hdmi)
-		/* HDMI panel */
-		init_panel(dev, 0, HDMI);
-	return 0;
-}
-
-void mdfld_output_setup(struct drm_device *dev)
-{
-	/* FIXME: this is not the right place for this stuff ! */
-	if (IS_MFLD(dev)) {
-		if (mdfld_dpu)
-			mdfld_dbi_dpu_init(dev);
-		else
-			mdfld_dbi_dsr_init(dev);
-	}
-}
diff --git a/drivers/staging/gma500/mdfld_output.h b/drivers/staging/gma500/mdfld_output.h
deleted file mode 100644
index daf33e7..0000000
--- a/drivers/staging/gma500/mdfld_output.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#ifndef MDFLD_OUTPUT_H
-#define MDFLD_OUTPUT_H
-
-int mdfld_output_init(struct drm_device *dev);
-int mdfld_panel_dpi(struct drm_device *dev);
-int mdfld_get_panel_type(struct drm_device *dev, int pipe);
-void mdfld_disable_crtc (struct drm_device *dev, int pipe);
-
-extern const struct drm_crtc_helper_funcs mdfld_helper_funcs;
-extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
-
-extern void mdfld_output_setup(struct drm_device *dev);
-
-#endif
diff --git a/drivers/staging/gma500/mdfld_pyr_cmd.c b/drivers/staging/gma500/mdfld_pyr_cmd.c
deleted file mode 100644
index 523f2d8..0000000
--- a/drivers/staging/gma500/mdfld_pyr_cmd.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
-*/
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/pyr_cmd.h"
-
-static struct drm_display_mode *pyr_cmd_get_config_mode(struct drm_device *dev)
-{
-	struct drm_display_mode *mode;
-
-	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-	if (!mode) {
-		dev_err(dev->dev, "Out of memory\n");
-		return NULL;
-	}
-
-	dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
-	dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
-	dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
-	dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
-	dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
-	dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
-	dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
-	dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
-	dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-
-	mode->hdisplay = 480;
-	mode->vdisplay = 864;
-	mode->hsync_start = 487;
-	mode->hsync_end = 490;
-	mode->htotal = 499;
-	mode->vsync_start = 874;
-	mode->vsync_end = 878;
-	mode->vtotal = 886;
-	mode->clock = 25777;
-
-	drm_mode_set_name(mode);
-	drm_mode_set_crtcinfo(mode, 0);
-
-	mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-	return mode;
-}
-
-static bool pyr_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct drm_display_mode *fixed_mode = pyr_cmd_get_config_mode(dev);
-
-	if (fixed_mode) {
-		adjusted_mode->hdisplay = fixed_mode->hdisplay;
-		adjusted_mode->hsync_start = fixed_mode->hsync_start;
-		adjusted_mode->hsync_end = fixed_mode->hsync_end;
-		adjusted_mode->htotal = fixed_mode->htotal;
-		adjusted_mode->vdisplay = fixed_mode->vdisplay;
-		adjusted_mode->vsync_start = fixed_mode->vsync_start;
-		adjusted_mode->vsync_end = fixed_mode->vsync_end;
-		adjusted_mode->vtotal = fixed_mode->vtotal;
-		adjusted_mode->clock = fixed_mode->clock;
-		drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-		kfree(fixed_mode);
-	}
-	return true;
-}
-
-static void pyr_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
-{
-	int ret = 0;
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dbi_output =
-				MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-	struct drm_device *dev = encoder->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 reg_offset = 0;
-	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
-
-	dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n", pipe,
-			on ? "On" : "Off",
-			dbi_output->dbi_panel_on ? "True" : "False");
-
-	if (pipe == 2) {
-		if (on)
-			dev_priv->dual_mipi = true;
-		else
-			dev_priv->dual_mipi = false;
-
-		reg_offset = MIPIC_REG_OFFSET;
-	} else {
-		if (!on)
-			dev_priv->dual_mipi = false;
-	}
-
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-
-
-	if (on) {
-		if (dbi_output->dbi_panel_on)
-			goto out_err;
-
-		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
-		if (ret) {
-			dev_err(dev->dev, "power on error\n");
-			goto out_err;
-		}
-
-		dbi_output->dbi_panel_on = true;
-
-		if (pipe == 2) {
-			dev_priv->dbi_panel_on2 = true;
-		} else {
-			dev_priv->dbi_panel_on = true;
-			mdfld_enable_te(dev, 0);
-		}
-	} else {
-		if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
-			goto out_err;
-
-		dbi_output->dbi_panel_on = false;
-		dbi_output->first_boot = false;
-
-		if (pipe == 2) {
-			dev_priv->dbi_panel_on2 = false;
-			mdfld_disable_te(dev, 2);
-		} else {
-			dev_priv->dbi_panel_on = false;
-			mdfld_disable_te(dev, 0);
-
-			if (dev_priv->dbi_panel_on2)
-				mdfld_enable_te(dev, 2);
-		}
-
-		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
-		if (ret) {
-			dev_err(dev->dev, "power on error\n");
-			goto out_err;
-		}
-	}
-
-out_err:
-	gma_power_end(dev);
-
-	if (ret)
-		dev_err(dev->dev, "failed\n");
-}
-
-static void pyr_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
-								int pipe)
-{
-	struct drm_device *dev = dsi_config->dev;
-	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
-	int lane_count = dsi_config->lane_count;
-	u32 val = 0;
-
-	dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
-
-	/* Un-ready device */
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
-
-	/* Init dsi adapter before kicking off */
-	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
-
-	/* TODO: figure out how to setup these registers */
-	REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c600F);
-	REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
-								0x000a0014);
-	REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
-	REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
-
-	/* Enable all interrupts */
-	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-	/* Max value: 20 clock cycles of txclkesc */
-	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
-	/* Min 21 txclkesc, max: ffffh */
-	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
-	/* Min: 7d0 max: 4e20 */
-	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
-
-	/* Set up func_prg */
-	val |= lane_count;
-	val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
-	val |= DSI_DBI_COLOR_FORMAT_OPTION2;
-	REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
-
-	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
-	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
-
-	/* De-assert dbi_stall when half of DBI FIFO is empty */
-	/* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
-
-	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
-	REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000002);
-	REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
-	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
-}
-
-static void pyr_dsi_dbi_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
-{
-	int ret = 0;
-	struct drm_device *dev = encoder->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dsi_output =
-					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-	struct mdfld_dsi_config *dsi_config =
-				mdfld_dsi_encoder_get_config(dsi_encoder);
-	struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
-	int pipe = dsi_connector->pipe;
-	u8 param = 0;
-
-	/* Regs */
-	u32 mipi_reg = MIPI;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 reg_offset = 0;
-
-	/* Values */
-	u32 dspcntr_val = dev_priv->dspcntr;
-	u32 pipeconf_val = dev_priv->pipeconf;
-	u32 h_active_area = mode->hdisplay;
-	u32 v_active_area = mode->vdisplay;
-	u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
-							TE_TRIGGER_GPIO_PIN);
-
-	dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
-
-	dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
-	dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
-
-	if (pipe == 2) {
-		mipi_reg = MIPI_C;
-		dspcntr_reg = DSPCCNTR;
-		pipeconf_reg = PIPECCONF;
-
-		reg_offset = MIPIC_REG_OFFSET;
-
-		dspcntr_val = dev_priv->dspcntr2;
-		pipeconf_val = dev_priv->pipeconf2;
-	} else {
-		mipi_val |= 0x2; /* Two lanes for port A and C respectively */
-	}
-
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-
-	/* Set up pipe related registers */
-	REG_WRITE(mipi_reg, mipi_val);
-	REG_READ(mipi_reg);
-
-	pyr_dsi_controller_dbi_init(dsi_config, pipe);
-
-	msleep(20);
-
-	REG_WRITE(dspcntr_reg, dspcntr_val);
-	REG_READ(dspcntr_reg);
-
-	/* 20ms delay before sending exit_sleep_mode */
-	msleep(20);
-
-	/* Send exit_sleep_mode DCS */
-	ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL,
-						0, CMD_DATA_SRC_SYSTEM_MEM);
-	if (ret) {
-		dev_err(dev->dev, "sent exit_sleep_mode faild\n");
-		goto out_err;
-	}
-
-	/*send set_tear_on DCS*/
-	ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on,
-					&param, 1, CMD_DATA_SRC_SYSTEM_MEM);
-	if (ret) {
-		dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
-		goto out_err;
-	}
-
-	/* Do some init stuff */
-	mdfld_dsi_brightness_init(dsi_config, pipe);
-	mdfld_dsi_gen_fifo_ready(dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset),
-				HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-
-	REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
-	REG_READ(pipeconf_reg);
-
-	/* TODO: this looks ugly, try to move it to CRTC mode setting */
-	if (pipe == 2)
-		dev_priv->pipeconf2 |= PIPEACONF_DSR;
-	else
-		dev_priv->pipeconf |= PIPEACONF_DSR;
-
-	dev_dbg(dev->dev, "pipeconf %x\n",  REG_READ(pipeconf_reg));
-
-	ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
-				h_active_area - 1, v_active_area - 1);
-	if (ret) {
-		dev_err(dev->dev, "update area failed\n");
-		goto out_err;
-	}
-
-out_err:
-	gma_power_end(dev);
-
-	if (ret)
-		dev_err(dev->dev, "mode set failed\n");
-	else
-		dev_dbg(dev->dev, "mode set done successfully\n");
-}
-
-static void pyr_dsi_dbi_prepare(struct drm_encoder *encoder)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dbi_output =
-					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-
-	dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
-	dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
-
-	pyr_dsi_dbi_set_power(encoder, false);
-}
-
-static void pyr_dsi_dbi_commit(struct drm_encoder *encoder)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dbi_output =
-					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-	struct drm_device *dev = dbi_output->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_drm_dpu_rect rect;
-
-	pyr_dsi_dbi_set_power(encoder, true);
-
-	dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
-
-	rect.x = rect.y = 0;
-	rect.width = 864;
-	rect.height = 480;
-
-	if (dbi_output->channel_num == 1) {
-		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
-		/* If DPU enabled report a fullscreen damage */
-		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
-	} else {
-		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
-		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
-	}
-	dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
-}
-
-static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dbi_output =
-					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-	struct drm_device *dev = dbi_output->dev;
-
-	dev_dbg(dev->dev, "%s\n",  (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
-
-	if (mode == DRM_MODE_DPMS_ON)
-		pyr_dsi_dbi_set_power(encoder, true);
-	else
-		pyr_dsi_dbi_set_power(encoder, false);
-}
-
-/*
- * Update the DBI MIPI Panel Frame Buffer.
- */
-static void pyr_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
-								int pipe)
-{
-	struct mdfld_dsi_pkg_sender *sender =
-		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-	struct drm_device *dev = dbi_output->dev;
-	struct drm_crtc *crtc = dbi_output->base.base.crtc;
-	struct psb_intel_crtc *psb_crtc = (crtc) ?
-				to_psb_intel_crtc(crtc) : NULL;
-
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 dsplinoff_reg = DSPALINOFF;
-	u32 dspsurf_reg = DSPASURF;
-	u32 hs_gen_ctrl_reg = HS_GEN_CTRL_REG;
-	u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
-	u32 reg_offset = 0;
-
-	u32 intr_status;
-	u32 fifo_stat_reg_val;
-	u32 dpll_reg_val;
-	u32 dspcntr_reg_val;
-	u32 pipeconf_reg_val;
-
-	/* If mode setting on-going, back off */
-	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
-		!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
-		return;
-
-	/*
-	 * Look for errors here.  In particular we're checking for whatever
-	 * error status might have appeared during the last frame transmit
-	 * (memory write).
-	 *
-	 * Normally, the bits we're testing here would be set infrequently,
-	 * if at all.  However, one panel (at least) returns at least one
-	 * error bit on most frames.  So we've disabled the kernel message
-	 * for now.
-	 *
-	 * Still clear whatever error bits are set, except don't clear the
-	 * ones that would make the Penwell DSI controller reset if we
-	 * cleared them.
-	 */
-	intr_status = REG_READ(INTR_STAT_REG);
-	if ((intr_status & 0x26FFFFFF) != 0) {
-		/* dev_err(dev->dev, "DSI status: 0x%08X\n", intr_status); */
-		intr_status &= 0x26F3FFFF;
-		REG_WRITE(INTR_STAT_REG, intr_status);
-	}
-
-	if (pipe == 2) {
-		dspcntr_reg = DSPCCNTR;
-		pipeconf_reg = PIPECCONF;
-		dsplinoff_reg = DSPCLINOFF;
-		dspsurf_reg = DSPCSURF;
-
-		hs_gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
-		gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET,
-
-		reg_offset = MIPIC_REG_OFFSET;
-	}
-
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-
-	fifo_stat_reg_val = REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset);
-	dpll_reg_val = REG_READ(dpll_reg);
-	dspcntr_reg_val = REG_READ(dspcntr_reg);
-	pipeconf_reg_val = REG_READ(pipeconf_reg);
-
-	if (!(fifo_stat_reg_val & (1 << 27)) ||
-		(dpll_reg_val & DPLL_VCO_ENABLE) ||
-		!(dspcntr_reg_val & DISPLAY_PLANE_ENABLE) ||
-		!(pipeconf_reg_val & DISPLAY_PLANE_ENABLE)) {
-		goto update_fb_out0;
-	}
-
-	/* Refresh plane changes */
-	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
-	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
-	REG_READ(dspsurf_reg);
-
-	mdfld_dsi_send_dcs(sender,
-			   write_mem_start,
-			   NULL,
-			   0,
-			   CMD_DATA_SRC_PIPE,
-			   MDFLD_DSI_SEND_PACKAGE);
-
-	/*
-	 * The idea here is to transmit a Generic Read command after the
-	 * Write Memory Start/Continue commands finish.  This asks for
-	 * the panel to return an "ACK No Errors," or (if it has errors
-	 * to report) an Error Report.  This allows us to monitor the
-	 * panel's perception of the health of the DSI.
-	 */
-	mdfld_dsi_gen_fifo_ready(dev, gen_fifo_stat_reg,
-				HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
-	REG_WRITE(hs_gen_ctrl_reg, (1 << WORD_COUNTS_POS) | GEN_READ_0);
-
-	dbi_output->dsr_fb_update_done = true;
-update_fb_out0:
-	gma_power_end(dev);
-}
-
-/*
- * TODO: will be removed later, should work out display interfaces for power
- */
-void pyr_dsi_adapter_init(struct mdfld_dsi_config *dsi_config, int pipe)
-{
-	if (!dsi_config || (pipe != 0 && pipe != 2)) {
-		WARN_ON(1);
-		return;
-	}
-	pyr_dsi_controller_dbi_init(dsi_config, pipe);
-}
-
-static int pyr_cmd_get_panel_info(struct drm_device *dev, int pipe,
-							struct panel_info *pi)
-{
-	if (!dev || !pi)
-		return -EINVAL;
-
-	pi->width_mm = PYR_PANEL_WIDTH;
-	pi->height_mm = PYR_PANEL_HEIGHT;
-
-	return 0;
-}
-
-/* PYR DBI encoder helper funcs */
-static const struct drm_encoder_helper_funcs pyr_dsi_dbi_helper_funcs = {
-	.dpms = pyr_dsi_dbi_dpms,
-	.mode_fixup = pyr_dsi_dbi_mode_fixup,
-	.prepare = pyr_dsi_dbi_prepare,
-	.mode_set = pyr_dsi_dbi_mode_set,
-	.commit = pyr_dsi_dbi_commit,
-};
-
-/* PYR DBI encoder funcs */
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
-void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
-	p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
-	p_funcs->encoder_helper_funcs = &pyr_dsi_dbi_helper_funcs;
-	p_funcs->get_config_mode = &pyr_cmd_get_config_mode;
-	p_funcs->update_fb = pyr_dsi_dbi_update_fb;
-	p_funcs->get_panel_info = pyr_cmd_get_panel_info;
-}
diff --git a/drivers/staging/gma500/mdfld_tmd_vid.c b/drivers/staging/gma500/mdfld_tmd_vid.c
deleted file mode 100644
index affdc09..0000000
--- a/drivers/staging/gma500/mdfld_tmd_vid.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jim Liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- * Gideon Eaton <eaton.
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tmd_vid.h"
-
-/* FIXME: static ? */
-struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev)
-{
-	struct drm_display_mode *mode;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-	bool use_gct = false; /*Disable GCT for now*/
-
-	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-	if (!mode) {
-		dev_err(dev->dev, "Out of memory\n");
-		return NULL;
-	}
-
-	if (use_gct) {
-		dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
-		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-		mode->hsync_start = mode->hdisplay +
-				((ti->hsync_offset_hi << 8) |
-				ti->hsync_offset_lo);
-		mode->hsync_end = mode->hsync_start +
-				((ti->hsync_pulse_width_hi << 8) |
-				ti->hsync_pulse_width_lo);
-		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) |
-								ti->hblank_lo);
-		mode->vsync_start = \
-			mode->vdisplay + ((ti->vsync_offset_hi << 8) |
-						ti->vsync_offset_lo);
-		mode->vsync_end = \
-			mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
-						ti->vsync_pulse_width_lo);
-		mode->vtotal = mode->vdisplay +
-				((ti->vblank_hi << 8) | ti->vblank_lo);
-		mode->clock = ti->pixel_clock * 10;
-
-		dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
-		dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
-		dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
-		dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
-		dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
-		dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
-		dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
-		dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
-		dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-	} else {
-		mode->hdisplay = 480;
-		mode->vdisplay = 854;
-		mode->hsync_start = 487;
-		mode->hsync_end = 490;
-		mode->htotal = 499;
-		mode->vsync_start = 861;
-		mode->vsync_end = 865;
-		mode->vtotal = 873;
-		mode->clock = 33264;
-	}
-	drm_mode_set_name(mode);
-	drm_mode_set_crtcinfo(mode, 0);
-
-	mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-	return mode;
-}
-
-static int tmd_vid_get_panel_info(struct drm_device *dev,
-				int pipe,
-				struct panel_info *pi)
-{
-	if (!dev || !pi)
-		return -EINVAL;
-
-	pi->width_mm = TMD_PANEL_WIDTH;
-	pi->height_mm = TMD_PANEL_HEIGHT;
-
-	return 0;
-}
-
-/*
- *	mdfld_init_TMD_MIPI	-	initialise a TMD interface
- *	@dsi_config: configuration
- *	@pipe: pipe to configure
- *
- *	This function is called only by mrst_dsi_mode_set and
- *	restore_display_registers.  since this function does not
- *	acquire the mutex, it is important that the calling function
- *	does!
- */
-
-
-static void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config,
-				      int pipe)
-{
-	static u32 tmd_cmd_mcap_off[] = {0x000000b2};
-	static u32 tmd_cmd_enable_lane_switch[] = {0x000101ef};
-	static u32 tmd_cmd_set_lane_num[] = {0x006360ef};
-	static u32 tmd_cmd_pushing_clock0[] = {0x00cc2fef};
-	static u32 tmd_cmd_pushing_clock1[] = {0x00dd6eef};
-	static u32 tmd_cmd_set_mode[] = {0x000000b3};
-	static u32 tmd_cmd_set_sync_pulse_mode[] = {0x000961ef};
-	static u32 tmd_cmd_set_column[] = {0x0100002a, 0x000000df};
-	static u32 tmd_cmd_set_page[] = {0x0300002b, 0x00000055};
-	static u32 tmd_cmd_set_video_mode[] = {0x00000153};
-	/*no auto_bl,need add in furture*/
-	static u32 tmd_cmd_enable_backlight[] = {0x00005ab4};
-	static u32 tmd_cmd_set_backlight_dimming[] = {0x00000ebd};
-
-	struct mdfld_dsi_pkg_sender *sender
-			= mdfld_dsi_get_pkg_sender(dsi_config);
-
-	DRM_INFO("Enter mdfld init TMD MIPI display.\n");
-
-	if (!sender) {
-		DRM_ERROR("Cannot get sender\n");
-		return;
-	}
-
-	if (dsi_config->dvr_ic_inited)
-		return;
-
-	msleep(3);
-
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_mcap_off, 1, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_lane_switch, 1, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_lane_num, 1, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_pushing_clock0, 1, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_pushing_clock1, 1, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_mode, 1, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_sync_pulse_mode, 1, 0);
-	mdfld_dsi_send_mcs_long_lp(sender, tmd_cmd_set_column, 2, 0);
-	mdfld_dsi_send_mcs_long_lp(sender, tmd_cmd_set_page, 2, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_video_mode, 1, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_backlight, 1, 0);
-	mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_backlight_dimming, 1, 0);
-
-	dsi_config->dvr_ic_inited = 1;
-}
-
-/* TMD DPI encoder helper funcs */
-static const struct drm_encoder_helper_funcs
-					mdfld_tpo_dpi_encoder_helper_funcs = {
-	.dpms = mdfld_dsi_dpi_dpms,
-	.mode_fixup = mdfld_dsi_dpi_mode_fixup,
-	.prepare = mdfld_dsi_dpi_prepare,
-	.mode_set = mdfld_dsi_dpi_mode_set,
-	.commit = mdfld_dsi_dpi_commit,
-};
-
-/* TMD DPI encoder funcs */
-static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
-void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
-	if (!dev || !p_funcs) {
-		dev_err(dev->dev, "Invalid parameters\n");
-		return;
-	}
-
-	p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
-	p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
-	p_funcs->get_config_mode = &tmd_vid_get_config_mode;
-	p_funcs->update_fb = NULL;
-	p_funcs->get_panel_info = tmd_vid_get_panel_info;
-	p_funcs->reset = mdfld_dsi_panel_reset;
-	p_funcs->drv_ic_init = mdfld_dsi_tmd_drv_ic_init;
-}
diff --git a/drivers/staging/gma500/mdfld_tpo_cmd.c b/drivers/staging/gma500/mdfld_tpo_cmd.c
deleted file mode 100644
index c7f7c9c..0000000
--- a/drivers/staging/gma500/mdfld_tpo_cmd.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (c)  2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicensen
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Eaton <thomas.g.eaton@intel.com>
- * Scott Rowe <scott.m.rowe@intel.com>
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_dbi_dpu.h"
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tpo_cmd.h"
-
-static struct drm_display_mode *tpo_cmd_get_config_mode(struct drm_device *dev)
-{
-	struct drm_display_mode *mode;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-	bool use_gct = false;
-
-	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-	if (!mode)
-		return NULL;
-
-	if (use_gct) {
-		dev_dbg(dev->dev, "gct find MIPI panel.\n");
-
-		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-		mode->hsync_start = mode->hdisplay + \
-				((ti->hsync_offset_hi << 8) | \
-				ti->hsync_offset_lo);
-		mode->hsync_end = mode->hsync_start + \
-				((ti->hsync_pulse_width_hi << 8) | \
-				ti->hsync_pulse_width_lo);
-		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
-								ti->hblank_lo);
-		mode->vsync_start = \
-			mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
-						ti->vsync_offset_lo);
-		mode->vsync_end = \
-			mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
-						ti->vsync_pulse_width_lo);
-		mode->vtotal = mode->vdisplay + \
-				((ti->vblank_hi << 8) | ti->vblank_lo);
-		mode->clock = ti->pixel_clock * 10;
-
-		dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
-		dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
-		dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
-		dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
-		dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
-		dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
-		dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
-		dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
-		dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-	} else {
-		mode->hdisplay = 864;
-		mode->vdisplay = 480;
-		mode->hsync_start = 872;
-		mode->hsync_end = 876;
-		mode->htotal = 884;
-		mode->vsync_start = 482;
-		mode->vsync_end = 494;
-		mode->vtotal = 486;
-		mode->clock = 25777;
-	}
-
-	drm_mode_set_name(mode);
-	drm_mode_set_crtcinfo(mode, 0);
-
-	mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-	return mode;
-}
-
-static bool mdfld_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
-				     struct drm_display_mode *mode,
-				     struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct drm_display_mode *fixed_mode = tpo_cmd_get_config_mode(dev);
-
-	if (fixed_mode) {
-		adjusted_mode->hdisplay = fixed_mode->hdisplay;
-		adjusted_mode->hsync_start = fixed_mode->hsync_start;
-		adjusted_mode->hsync_end = fixed_mode->hsync_end;
-		adjusted_mode->htotal = fixed_mode->htotal;
-		adjusted_mode->vdisplay = fixed_mode->vdisplay;
-		adjusted_mode->vsync_start = fixed_mode->vsync_start;
-		adjusted_mode->vsync_end = fixed_mode->vsync_end;
-		adjusted_mode->vtotal = fixed_mode->vtotal;
-		adjusted_mode->clock = fixed_mode->clock;
-		drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-		kfree(fixed_mode);
-	}
-	return true;
-}
-
-static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
-{
-	int ret = 0;
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dbi_output =
-				MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-	struct mdfld_dsi_config *dsi_config =
-		mdfld_dsi_encoder_get_config(dsi_encoder);
-	struct mdfld_dsi_pkg_sender *sender =
-		mdfld_dsi_encoder_get_pkg_sender(dsi_encoder);
-	struct drm_device *dev = encoder->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 reg_offset = 0;
-	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
-	u32 data = 0;
-
-	dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n",
-			pipe, on ? "On" : "Off",
-			dbi_output->dbi_panel_on ? "True" : "False");
-
-	if (pipe == 2) {
-		if (on)
-			dev_priv->dual_mipi = true;
-		else
-			dev_priv->dual_mipi = false;
-		reg_offset = MIPIC_REG_OFFSET;
-	} else {
-		if (!on)
-			dev_priv->dual_mipi = false;
-	}
-
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-
-	if (on) {
-		if (dbi_output->dbi_panel_on)
-			goto out_err;
-
-		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
-		if (ret) {
-			dev_err(dev->dev, "power on error\n");
-			goto out_err;
-		}
-
-		dbi_output->dbi_panel_on = true;
-
-		if (pipe == 2)
-			dev_priv->dbi_panel_on2 = true;
-		else
-			dev_priv->dbi_panel_on = true;
-		mdfld_enable_te(dev, pipe);
-	} else {
-		if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
-			goto out_err;
-
-		dbi_output->dbi_panel_on = false;
-		dbi_output->first_boot = false;
-
-		if (pipe == 2)
-			dev_priv->dbi_panel_on2 = false;
-		else
-			dev_priv->dbi_panel_on = false;
-
-		mdfld_disable_te(dev, pipe);
-
-		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
-		if (ret) {
-			dev_err(dev->dev, "power on error\n");
-			goto out_err;
-		}
-	}
-
-	/*
-	 * FIXME: this is a WA for TPO panel crash on DPMS on & off around
-	 * 83 times. the root cause of this issue is that Booster in
-	 * drvIC crashed. Add this WA so that we can resume the driver IC
-	 * once we found that booster has a fault
-	 */
-	mdfld_dsi_get_power_mode(dsi_config,
-				&data,
-				MDFLD_DSI_HS_TRANSMISSION);
-
-	if (on && data && !(data & (1 << 7))) {
-		/* Soft reset */
-		mdfld_dsi_send_dcs(sender,
-				   DCS_SOFT_RESET,
-				   NULL,
-				   0,
-				   CMD_DATA_SRC_PIPE,
-				   MDFLD_DSI_SEND_PACKAGE);
-
-		/* Init drvIC */
-		if (dbi_output->p_funcs->drv_ic_init)
-			dbi_output->p_funcs->drv_ic_init(dsi_config,
-							 pipe);
-	}
- 
-out_err:
-	gma_power_end(dev);
-	if (ret)
-		dev_err(dev->dev, "failed\n");
-}
-
-
-static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder,
-				   struct drm_display_mode *mode,
-				   struct drm_display_mode *adjusted_mode)
-{
-	int ret = 0;
-	struct drm_device *dev = encoder->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dsi_output =
-					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-	struct mdfld_dsi_config *dsi_config =
-				mdfld_dsi_encoder_get_config(dsi_encoder);
-	struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
-	int pipe = dsi_connector->pipe;
-	u8 param = 0;
-
-	/* Regs */
-	u32 mipi_reg = MIPI;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 reg_offset = 0;
-
-	/* Values */
-	u32 dspcntr_val = dev_priv->dspcntr;
-	u32 pipeconf_val = dev_priv->pipeconf;
-	u32 h_active_area = mode->hdisplay;
-	u32 v_active_area = mode->vdisplay;
-	u32 mipi_val;
-
-	mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
-						TE_TRIGGER_GPIO_PIN);
-
-	dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
-
-	dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
-	dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
-
-	if (pipe == 2) {
-		mipi_reg = MIPI_C;
-		dspcntr_reg = DSPCCNTR;
-		pipeconf_reg = PIPECCONF;
-
-		reg_offset = MIPIC_REG_OFFSET;
-
-		dspcntr_val = dev_priv->dspcntr2;
-		pipeconf_val = dev_priv->pipeconf2;
-	} else {
-		mipi_val |= 0x2; /*two lanes for port A and C respectively*/
-	}
-
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-
-	REG_WRITE(dspcntr_reg, dspcntr_val);
-	REG_READ(dspcntr_reg);
-
-	/* 20ms delay before sending exit_sleep_mode */
-	msleep(20);
-
-	/* Send exit_sleep_mode DCS */
-	ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_EXIT_SLEEP_MODE,
-					NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
-	if (ret) {
-		dev_err(dev->dev, "sent exit_sleep_mode faild\n");
-		goto out_err;
-	}
-
-	/* Send set_tear_on DCS */
-	ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_SET_TEAR_ON,
-					&param, 1, CMD_DATA_SRC_SYSTEM_MEM);
-	if (ret) {
-		dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
-		goto out_err;
-	}
-
-	/* Do some init stuff */
-	REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
-	REG_READ(pipeconf_reg);
-
-	/* TODO: this looks ugly, try to move it to CRTC mode setting*/
-	if (pipe == 2)
-		dev_priv->pipeconf2 |= PIPEACONF_DSR;
-	else
-		dev_priv->pipeconf |= PIPEACONF_DSR;
-
-	dev_dbg(dev->dev, "pipeconf %x\n",  REG_READ(pipeconf_reg));
-
-	ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
-				h_active_area - 1, v_active_area - 1);
-	if (ret) {
-		dev_err(dev->dev, "update area failed\n");
-		goto out_err;
-	}
-
-out_err:
-	gma_power_end(dev);
-
-	if (ret)
-		dev_err(dev->dev, "mode set failed\n");
-}
-
-static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dbi_output
-				= MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-
-	dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
-	dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
-
-	mdfld_dsi_dbi_set_power(encoder, false);
-}
-
-static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dbi_output =
-					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-	struct drm_device *dev = dbi_output->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_drm_dpu_rect rect;
-
-	mdfld_dsi_dbi_set_power(encoder, true);
-	dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
-
-	rect.x = rect.y = 0;
-	rect.width = 864;
-	rect.height = 480;
-
-	if (dbi_output->channel_num == 1) {
-		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
-		/*if dpu enabled report a fullscreen damage*/
-		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
-	} else {
-		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
-		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
-	}
-	dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
-}
-
-static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
-	struct mdfld_dsi_dbi_output *dbi_output
-				= MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
-	struct drm_device *dev = dbi_output->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	static bool bdispoff;
-
-	dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
-
-	if (mode == DRM_MODE_DPMS_ON) {
-		/*
-		 * FIXME: in case I am wrong!
-		 * we don't need to exit dsr here to wake up plane/pipe/pll
-		 * if everything goes right, hw_begin will resume them all
-		 * during set_power.
-		 */
-		if (bdispoff /* FIXME && gbgfxsuspended */) {
-			mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D);
-			bdispoff = false;
-			dev_priv->dispstatus = true;
-		}
-
-		mdfld_dsi_dbi_set_power(encoder, true);
-		/* FIXME if (gbgfxsuspended)
-			gbgfxsuspended = false; */
-	} else {
-		/*
-		 * I am not sure whether this is the perfect place to
-		 * turn rpm on since we still have a lot of CRTC turnning
-		 * on work to do.
-		 */
-		bdispoff = true;
-		dev_priv->dispstatus = false;
-		mdfld_dsi_dbi_set_power(encoder, false);
-	}
-}
-
-
-/*
- * Update the DBI MIPI Panel Frame Buffer.
- */
-static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
-								int pipe)
-{
-	struct mdfld_dsi_pkg_sender *sender =
-		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
-	struct drm_device *dev = dbi_output->dev;
-	struct drm_crtc *crtc = dbi_output->base.base.crtc;
-	struct psb_intel_crtc *psb_crtc = (crtc) ?
-					to_psb_intel_crtc(crtc) : NULL;
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 dsplinoff_reg = DSPALINOFF;
-	u32 dspsurf_reg = DSPASURF;
-	u32 reg_offset = 0;
-
-	/* If mode setting on-going, back off */
-	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
-		!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
-		return;
-
-	if (pipe == 2) {
-		dspcntr_reg = DSPCCNTR;
-		pipeconf_reg = PIPECCONF;
-		dsplinoff_reg = DSPCLINOFF;
-		dspsurf_reg = DSPCSURF;
-		reg_offset = MIPIC_REG_OFFSET;
-	}
-
-	if (!gma_power_begin(dev, true)) {
-		dev_err(dev->dev, "hw begin failed\n");
-		return;
-	}
-
-	/* Check DBI FIFO status */
-	if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
-	   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
-	   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
-		goto update_fb_out0;
-
-	/* Refresh plane changes */
-	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
-	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
-	REG_READ(dspsurf_reg);
-
-	mdfld_dsi_send_dcs(sender,
-			   DCS_WRITE_MEM_START,
-			   NULL,
-			   0,
-			   CMD_DATA_SRC_PIPE,
-			   MDFLD_DSI_SEND_PACKAGE);
-
-	dbi_output->dsr_fb_update_done = true;
-update_fb_out0:
-	gma_power_end(dev);
-}
-
-static int tpo_cmd_get_panel_info(struct drm_device *dev,
-				int pipe,
-				struct panel_info *pi)
-{
-	if (!dev || !pi)
-		return -EINVAL;
-
-	pi->width_mm = TPO_PANEL_WIDTH;
-	pi->height_mm = TPO_PANEL_HEIGHT;
-
-	return 0;
-}
-
-
-/* TPO DBI encoder helper funcs */
-static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
-	.dpms = mdfld_dsi_dbi_dpms,
-	.mode_fixup = mdfld_dsi_dbi_mode_fixup,
-	.prepare = mdfld_dsi_dbi_prepare,
-	.mode_set = mdfld_dsi_dbi_mode_set,
-	.commit = mdfld_dsi_dbi_commit,
-};
-
-/* TPO DBI encoder funcs */
-static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
-void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
-	p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
-	p_funcs->encoder_helper_funcs = &mdfld_dsi_dbi_helper_funcs;
-	p_funcs->get_config_mode = &tpo_cmd_get_config_mode;
-	p_funcs->update_fb = mdfld_dsi_dbi_update_fb;
-	p_funcs->get_panel_info = tpo_cmd_get_panel_info;
-	p_funcs->reset = mdfld_dsi_panel_reset;
-	p_funcs->drv_ic_init = mdfld_dsi_brightness_init;
-}
diff --git a/drivers/staging/gma500/mdfld_tpo_vid.c b/drivers/staging/gma500/mdfld_tpo_vid.c
deleted file mode 100644
index 9549017..0000000
--- a/drivers/staging/gma500/mdfld_tpo_vid.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * jim liu <jim.liu@intel.com>
- * Jackie Li<yaodong.li@intel.com>
- */
-
-#include "mdfld_dsi_dbi.h"
-#include "mdfld_dsi_dpi.h"
-#include "mdfld_dsi_output.h"
-#include "mdfld_output.h"
-
-#include "mdfld_dsi_pkg_sender.h"
-
-#include "displays/tpo_vid.h"
-
-static struct drm_display_mode *tpo_vid_get_config_mode(struct drm_device *dev)
-{
-	struct drm_display_mode *mode;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-	bool use_gct = false;
-
-	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-	if (!mode) {
-		dev_err(dev->dev, "out of memory\n");
-		return NULL;
-	}
-
-	if (use_gct) {
-		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-		mode->hsync_start = mode->hdisplay + \
-				((ti->hsync_offset_hi << 8) | \
-				ti->hsync_offset_lo);
-		mode->hsync_end = mode->hsync_start + \
-				((ti->hsync_pulse_width_hi << 8) | \
-				ti->hsync_pulse_width_lo);
-		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
-								ti->hblank_lo);
-		mode->vsync_start = \
-			mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
-						ti->vsync_offset_lo);
-		mode->vsync_end = \
-			mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
-						ti->vsync_pulse_width_lo);
-		mode->vtotal = mode->vdisplay + \
-				((ti->vblank_hi << 8) | ti->vblank_lo);
-		mode->clock = ti->pixel_clock * 10;
-
-		dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
-		dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
-		dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
-		dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
-		dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
-		dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
-		dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
-		dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
-		dev_dbg(dev->dev, "clock is %d\n", mode->clock);
-	} else {
-		mode->hdisplay = 864;
-		mode->vdisplay = 480;
-		mode->hsync_start = 873;
-		mode->hsync_end = 876;
-		mode->htotal = 887;
-		mode->vsync_start = 487;
-		mode->vsync_end = 490;
-		mode->vtotal = 499;
-		mode->clock = 33264;
-	}
-
-	drm_mode_set_name(mode);
-	drm_mode_set_crtcinfo(mode, 0);
-
-	mode->type |= DRM_MODE_TYPE_PREFERRED;
-
-	return mode;
-}
-
-static int tpo_vid_get_panel_info(struct drm_device *dev,
-				int pipe,
-				struct panel_info *pi)
-{
-	if (!dev || !pi)
-		return -EINVAL;
-
-	pi->width_mm = TPO_PANEL_WIDTH;
-	pi->height_mm = TPO_PANEL_HEIGHT;
-
-	return 0;
-}
-
-/*TPO DPI encoder helper funcs*/
-static const struct drm_encoder_helper_funcs
-					mdfld_tpo_dpi_encoder_helper_funcs = {
-	.dpms = mdfld_dsi_dpi_dpms,
-	.mode_fixup = mdfld_dsi_dpi_mode_fixup,
-	.prepare = mdfld_dsi_dpi_prepare,
-	.mode_set = mdfld_dsi_dpi_mode_set,
-	.commit = mdfld_dsi_dpi_commit,
-};
-
-/*TPO DPI encoder funcs*/
-static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
-void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs)
-{
-	if (!dev || !p_funcs) {
-		dev_err(dev->dev, "tpo_vid_init: Invalid parameters\n");
-		return;
-	}
-
-	p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
-	p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
-	p_funcs->get_config_mode = &tpo_vid_get_config_mode;
-	p_funcs->update_fb = NULL;
-	p_funcs->get_panel_info = tpo_vid_get_panel_info;
-}
diff --git a/drivers/staging/gma500/medfield.h b/drivers/staging/gma500/medfield.h
deleted file mode 100644
index 09e9687..0000000
--- a/drivers/staging/gma500/medfield.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright © 2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/* Medfield DSI controller registers */
-
-#define MIPIA_DEVICE_READY_REG				0xb000
-#define MIPIA_INTR_STAT_REG				0xb004
-#define MIPIA_INTR_EN_REG				0xb008
-#define MIPIA_DSI_FUNC_PRG_REG				0xb00c
-#define MIPIA_HS_TX_TIMEOUT_REG				0xb010
-#define MIPIA_LP_RX_TIMEOUT_REG				0xb014
-#define MIPIA_TURN_AROUND_TIMEOUT_REG			0xb018
-#define MIPIA_DEVICE_RESET_TIMER_REG			0xb01c
-#define MIPIA_DPI_RESOLUTION_REG			0xb020
-#define MIPIA_DBI_FIFO_THROTTLE_REG			0xb024
-#define MIPIA_HSYNC_COUNT_REG				0xb028
-#define MIPIA_HBP_COUNT_REG				0xb02c
-#define MIPIA_HFP_COUNT_REG				0xb030
-#define MIPIA_HACTIVE_COUNT_REG				0xb034
-#define MIPIA_VSYNC_COUNT_REG				0xb038
-#define MIPIA_VBP_COUNT_REG				0xb03c
-#define MIPIA_VFP_COUNT_REG				0xb040
-#define MIPIA_HIGH_LOW_SWITCH_COUNT_REG			0xb044
-#define MIPIA_DPI_CONTROL_REG				0xb048
-#define MIPIA_DPI_DATA_REG				0xb04c
-#define MIPIA_INIT_COUNT_REG				0xb050
-#define MIPIA_MAX_RETURN_PACK_SIZE_REG			0xb054
-#define MIPIA_VIDEO_MODE_FORMAT_REG			0xb058
-#define MIPIA_EOT_DISABLE_REG				0xb05c
-#define MIPIA_LP_BYTECLK_REG				0xb060
-#define MIPIA_LP_GEN_DATA_REG				0xb064
-#define MIPIA_HS_GEN_DATA_REG				0xb068
-#define MIPIA_LP_GEN_CTRL_REG				0xb06c
-#define MIPIA_HS_GEN_CTRL_REG				0xb070
-#define MIPIA_GEN_FIFO_STAT_REG				0xb074
-#define MIPIA_HS_LS_DBI_ENABLE_REG			0xb078
-#define MIPIA_DPHY_PARAM_REG				0xb080
-#define MIPIA_DBI_BW_CTRL_REG				0xb084
-#define MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG		0xb088
-
-#define DSI_DEVICE_READY				(0x1)
-#define DSI_POWER_STATE_ULPS_ENTER			(0x2 << 1)
-#define DSI_POWER_STATE_ULPS_EXIT			(0x1 << 1)
-#define DSI_POWER_STATE_ULPS_OFFSET			(0x1)
-
-
-#define DSI_ONE_DATA_LANE				(0x1)
-#define DSI_TWO_DATA_LANE				(0x2)
-#define DSI_THREE_DATA_LANE				(0X3)
-#define DSI_FOUR_DATA_LANE				(0x4)
-#define DSI_DPI_VIRT_CHANNEL_OFFSET			(0x3)
-#define DSI_DBI_VIRT_CHANNEL_OFFSET			(0x5)
-#define DSI_DPI_COLOR_FORMAT_RGB565			(0x01 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB666			(0x02 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK		(0x03 << 7)
-#define DSI_DPI_COLOR_FORMAT_RGB888			(0x04 << 7)
-#define DSI_DBI_COLOR_FORMAT_OPTION2			(0x05 << 13)
-
-#define DSI_INTR_STATE_RXSOTERROR			1
-
-#define DSI_INTR_STATE_SPL_PKG_SENT			(1 << 30)
-#define DSI_INTR_STATE_TE				(1 << 31)
-
-#define DSI_HS_TX_TIMEOUT_MASK				(0xffffff)
-
-#define DSI_LP_RX_TIMEOUT_MASK				(0xffffff)
-
-#define DSI_TURN_AROUND_TIMEOUT_MASK			(0x3f)
-
-#define DSI_RESET_TIMER_MASK				(0xffff)
-
-#define DSI_DBI_FIFO_WM_HALF				(0x0)
-#define DSI_DBI_FIFO_WM_QUARTER				(0x1)
-#define DSI_DBI_FIFO_WM_LOW				(0x2)
-
-#define DSI_DPI_TIMING_MASK				(0xffff)
-
-#define DSI_INIT_TIMER_MASK				(0xffff)
-
-#define DSI_DBI_RETURN_PACK_SIZE_MASK			(0x3ff)
-
-#define DSI_LP_BYTECLK_MASK				(0x0ffff)
-
-#define DSI_HS_CTRL_GEN_SHORT_W0			(0x03)
-#define DSI_HS_CTRL_GEN_SHORT_W1			(0x13)
-#define DSI_HS_CTRL_GEN_SHORT_W2			(0x23)
-#define DSI_HS_CTRL_GEN_R0				(0x04)
-#define DSI_HS_CTRL_GEN_R1				(0x14)
-#define DSI_HS_CTRL_GEN_R2				(0x24)
-#define DSI_HS_CTRL_GEN_LONG_W				(0x29)
-#define DSI_HS_CTRL_MCS_SHORT_W0			(0x05)
-#define DSI_HS_CTRL_MCS_SHORT_W1			(0x15)
-#define DSI_HS_CTRL_MCS_R0				(0x06)
-#define DSI_HS_CTRL_MCS_LONG_W				(0x39)
-#define DSI_HS_CTRL_VC_OFFSET				(0x06)
-#define DSI_HS_CTRL_WC_OFFSET				(0x08)
-
-#define	DSI_FIFO_GEN_HS_DATA_FULL			(1 << 0)
-#define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY			(1 << 1)
-#define DSI_FIFO_GEN_HS_DATA_EMPTY			(1 << 2)
-#define DSI_FIFO_GEN_LP_DATA_FULL			(1 << 8)
-#define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY			(1 << 9)
-#define DSI_FIFO_GEN_LP_DATA_EMPTY			(1 << 10)
-#define DSI_FIFO_GEN_HS_CTRL_FULL			(1 << 16)
-#define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY			(1 << 17)
-#define DSI_FIFO_GEN_HS_CTRL_EMPTY			(1 << 18)
-#define DSI_FIFO_GEN_LP_CTRL_FULL			(1 << 24)
-#define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY			(1 << 25)
-#define DSI_FIFO_GEN_LP_CTRL_EMPTY			(1 << 26)
-#define DSI_FIFO_DBI_EMPTY				(1 << 27)
-#define DSI_FIFO_DPI_EMPTY				(1 << 28)
-
-#define DSI_DBI_HS_LP_SWITCH_MASK			(0x1)
-
-#define DSI_HS_LP_SWITCH_COUNTER_OFFSET			(0x0)
-#define DSI_LP_HS_SWITCH_COUNTER_OFFSET			(0x16)
-
-#define DSI_DPI_CTRL_HS_SHUTDOWN			(0x00000001)
-#define DSI_DPI_CTRL_HS_TURN_ON				(0x00000002)
-
-/* Medfield DSI adapter registers */
-#define MIPIA_CONTROL_REG				0xb104
-#define MIPIA_DATA_ADD_REG				0xb108
-#define MIPIA_DATA_LEN_REG				0xb10c
-#define MIPIA_CMD_ADD_REG				0xb110
-#define MIPIA_CMD_LEN_REG				0xb114
-
-/*dsi power modes*/
-#define DSI_POWER_MODE_DISPLAY_ON	(1 << 2)
-#define DSI_POWER_MODE_NORMAL_ON	(1 << 3)
-#define DSI_POWER_MODE_SLEEP_OUT	(1 << 4)
-#define DSI_POWER_MODE_PARTIAL_ON	(1 << 5)
-#define DSI_POWER_MODE_IDLE_ON		(1 << 6)
-
-enum {
-	MDFLD_DSI_ENCODER_DBI = 0,
-	MDFLD_DSI_ENCODER_DPI,
-};
-
-enum {
-	MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1,
-	MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2,
-	MDFLD_DSI_VIDEO_BURST_MODE = 3,
-};
-
-#define DSI_DPI_COMPLETE_LAST_LINE			(1 << 2)
-#define DSI_DPI_DISABLE_BTA				(1 << 3)
-/* Panel types */
-enum {
-	TPO_CMD,
-	TPO_VID,
-	TMD_CMD,
-	TMD_VID,
-	PYR_CMD,
-	PYR_VID,
-	TPO,
-	TMD,
-	PYR,
-	HDMI,
-	GCT_DETECT
-};
-
-/* Junk that belongs elsewhere */
-#define TPO_PANEL_WIDTH		84
-#define TPO_PANEL_HEIGHT	46
-#define TMD_PANEL_WIDTH		39
-#define TMD_PANEL_HEIGHT	71
-#define PYR_PANEL_WIDTH		53
-#define PYR_PANEL_HEIGHT	95
-
-/* Panel interface */
-struct panel_info {
-	u32 width_mm;
-	u32 height_mm;
-};
-
-struct mdfld_dsi_dbi_output;
-
-struct mdfld_dsi_connector_state {
-	u32 mipi_ctrl_reg;
-};
-
-struct mdfld_dsi_encoder_state {
-
-};
-
-struct mdfld_dsi_connector {
-	/*
-	 * This is ugly, but I have to use connector in it! :-(
-	 * FIXME: use drm_connector instead.
-	 */
-	struct psb_intel_output base;
-
-	int pipe;
-	void *private;
-	void *pkg_sender;
-
-	/* Connection status */
-	enum drm_connector_status status;
-};
-
-struct mdfld_dsi_encoder {
-	struct drm_encoder base;
-	void *private;
-};
-
-/*
- * DSI config, consists of one DSI connector, two DSI encoders.
- * DRM will pick up on DSI encoder basing on differents configs.
- */
-struct mdfld_dsi_config {
-	struct drm_device *dev;
-	struct drm_display_mode *fixed_mode;
-	struct drm_display_mode *mode;
-
-	struct mdfld_dsi_connector *connector;
-	struct mdfld_dsi_encoder *encoders[DRM_CONNECTOR_MAX_ENCODER];
-	struct mdfld_dsi_encoder *encoder;
-
-	int changed;
-
-	int bpp;
-	int type;
-	int lane_count;
-	/*Virtual channel number for this encoder*/
-	int channel_num;
-	/*video mode configure*/
-	int video_mode;
-
-	int dvr_ic_inited;
-};
-
-#define MDFLD_DSI_CONNECTOR(psb_output) \
-		(container_of(psb_output, struct mdfld_dsi_connector, base))
-
-#define MDFLD_DSI_ENCODER(encoder) \
-		(container_of(encoder, struct mdfld_dsi_encoder, base))
-
-struct panel_funcs {
-	const struct drm_encoder_funcs *encoder_funcs;
-	const struct drm_encoder_helper_funcs *encoder_helper_funcs;
-	struct drm_display_mode *(*get_config_mode) (struct drm_device *);
-	void (*update_fb) (struct mdfld_dsi_dbi_output *, int);
-	int (*get_panel_info) (struct drm_device *, int, struct panel_info *);
-	int (*reset)(int pipe);
-	void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe);
-};
-
diff --git a/drivers/staging/gma500/mid_bios.c b/drivers/staging/gma500/mid_bios.c
deleted file mode 100644
index ee3c036..0000000
--- a/drivers/staging/gma500/mid_bios.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-/* TODO
- * - Split functions by vbt type
- * - Make them all take drm_device
- * - Check ioremap failures
- */
-
-#include <linux/moduleparam.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "mid_bios.h"
-#include "mdfld_output.h"
-
-static int panel_id = GCT_DETECT;
-module_param_named(panel_id, panel_id, int, 0600);
-MODULE_PARM_DESC(panel_id, "Panel Identifier");
-
-
-static void mid_get_fuse_settings(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	uint32_t fuse_value = 0;
-	uint32_t fuse_value_tmp = 0;
-
-#define FB_REG06 0xD0810600
-#define FB_MIPI_DISABLE  (1 << 11)
-#define FB_REG09 0xD0810900
-#define FB_REG09 0xD0810900
-#define FB_SKU_MASK  0x7000
-#define FB_SKU_SHIFT 12
-#define FB_SKU_100 0
-#define FB_SKU_100L 1
-#define FB_SKU_83 2
-	pci_write_config_dword(pci_root, 0xD0, FB_REG06);
-	pci_read_config_dword(pci_root, 0xD4, &fuse_value);
-
-	/* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */
-	if (IS_MRST(dev))
-		dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;
-
-	DRM_INFO("internal display is %s\n",
-		 dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
-
-	 /* Prevent runtime suspend at start*/
-	 if (dev_priv->iLVDS_enable) {
-		dev_priv->is_lvds_on = true;
-		dev_priv->is_mipi_on = false;
-	} else {
-		dev_priv->is_mipi_on = true;
-		dev_priv->is_lvds_on = false;
-	}
-
-	dev_priv->video_device_fuse = fuse_value;
-
-	pci_write_config_dword(pci_root, 0xD0, FB_REG09);
-	pci_read_config_dword(pci_root, 0xD4, &fuse_value);
-
-	dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value);
-	fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
-
-	dev_priv->fuse_reg_value = fuse_value;
-
-	switch (fuse_value_tmp) {
-	case FB_SKU_100:
-		dev_priv->core_freq = 200;
-		break;
-	case FB_SKU_100L:
-		dev_priv->core_freq = 100;
-		break;
-	case FB_SKU_83:
-		dev_priv->core_freq = 166;
-		break;
-	default:
-		dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n",
-								fuse_value_tmp);
-		dev_priv->core_freq = 0;
-	}
-	dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq);
-	pci_dev_put(pci_root);
-}
-
-/*
- *	Get the revison ID, B0:D2:F0;0x08
- */
-static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
-{
-	uint32_t platform_rev_id = 0;
-	struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
-	pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
-	dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
-	pci_dev_put(pci_gfx_root);
-	dev_dbg(dev_priv->dev->dev, "platform_rev_id is %x\n",
-					dev_priv->platform_rev_id);
-}
-
-static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
-{
-	struct drm_device *dev = dev_priv->dev;
-	struct mrst_vbt *vbt = &dev_priv->vbt_data;
-	u32 addr;
-	u16 new_size;
-	u8 *vbt_virtual;
-	u8 bpi;
-	u8 number_desc = 0;
-	struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD;
-	struct gct_r10_timing_info ti;
-	void *pGCT;
-	struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
-	/* Get the address of the platform config vbt, B0:D2:F0;0xFC */
-	pci_read_config_dword(pci_gfx_root, 0xFC, &addr);
-	pci_dev_put(pci_gfx_root);
-
-	dev_dbg(dev->dev, "drm platform config address is %x\n", addr);
-
-	/* check for platform config address == 0. */
-	/* this means fw doesn't support vbt */
-
-	if (addr == 0) {
-		vbt->size = 0;
-		return;
-	}
-
-	/* get the virtual address of the vbt */
-	vbt_virtual = ioremap(addr, sizeof(*vbt));
-
-	memcpy(vbt, vbt_virtual, sizeof(*vbt));
-	iounmap(vbt_virtual); /* Free virtual address space */
-
-	dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision);
-
-	switch (vbt->revision) {
-	case 0:
-		vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4,
-					vbt->size - sizeof(*vbt) + 4);
-		pGCT = vbt->mrst_gct;
-		bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex;
-		dev_priv->gct_data.bpi = bpi;
-		dev_priv->gct_data.pt =
-			((struct mrst_gct_v1 *)pGCT)->PD.PanelType;
-		memcpy(&dev_priv->gct_data.DTD,
-			&((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD,
-				sizeof(struct mrst_timing_info));
-		dev_priv->gct_data.Panel_Port_Control =
-		  ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
-		dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
-			((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
-		break;
-	case 1:
-		vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4,
-					vbt->size - sizeof(*vbt) + 4);
-		pGCT = vbt->mrst_gct;
-		bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex;
-		dev_priv->gct_data.bpi = bpi;
-		dev_priv->gct_data.pt =
-			((struct mrst_gct_v2 *)pGCT)->PD.PanelType;
-		memcpy(&dev_priv->gct_data.DTD,
-			&((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD,
-				sizeof(struct mrst_timing_info));
-		dev_priv->gct_data.Panel_Port_Control =
-		  ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
-		dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
-			((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
-		break;
-	case 0x10:
-		/*header definition changed from rev 01 (v2) to rev 10h. */
-		/*so, some values have changed location*/
-		new_size = vbt->checksum; /*checksum contains lo size byte*/
-		/*LSB of mrst_gct contains hi size byte*/
-		new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8;
-
-		vbt->checksum = vbt->size; /*size contains the checksum*/
-		if (new_size > 0xff)
-			vbt->size = 0xff; /*restrict size to 255*/
-		else
-			vbt->size = new_size;
-
-		/* number of descriptors defined in the GCT */
-		number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8;
-		bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16;
-		vbt->mrst_gct = ioremap(addr + GCT_R10_HEADER_SIZE,
-				GCT_R10_DISPLAY_DESC_SIZE * number_desc);
-		pGCT = vbt->mrst_gct;
-		pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
-		dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
-
-		/*copy the GCT display timings into a temp structure*/
-		memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
-
-		/*now copy the temp struct into the dev_priv->gct_data*/
-		dp_ti->pixel_clock = ti.pixel_clock;
-		dp_ti->hactive_hi = ti.hactive_hi;
-		dp_ti->hactive_lo = ti.hactive_lo;
-		dp_ti->hblank_hi = ti.hblank_hi;
-		dp_ti->hblank_lo = ti.hblank_lo;
-		dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
-		dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
-		dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
-		dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
-		dp_ti->vactive_hi = ti.vactive_hi;
-		dp_ti->vactive_lo = ti.vactive_lo;
-		dp_ti->vblank_hi = ti.vblank_hi;
-		dp_ti->vblank_lo = ti.vblank_lo;
-		dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
-		dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
-		dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
-		dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
-
-		/* Move the MIPI_Display_Descriptor data from GCT to dev priv */
-		dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
-							*((u8 *)pGCT + 0x0d);
-		dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
-						(*((u8 *)pGCT + 0x0e)) << 8;
-		break;
-	default:
-		dev_err(dev->dev, "Unknown revision of GCT!\n");
-		vbt->size = 0;
-	}
-	if (IS_MFLD(dev_priv->dev)) {
-		if (panel_id == GCT_DETECT) {
-			if (dev_priv->gct_data.bpi == 2) {
-				dev_info(dev->dev, "[GFX] PYR Panel Detected\n");
-				dev_priv->panel_id = PYR_CMD;
-				panel_id = PYR_CMD;
-			} else if (dev_priv->gct_data.bpi == 0) {
-				dev_info(dev->dev, "[GFX] TMD Panel Detected.\n");
-				dev_priv->panel_id = TMD_VID;
-				panel_id = TMD_VID;
-			} else {
-				dev_info(dev->dev, "[GFX] Default Panel (TPO)\n");
-				dev_priv->panel_id = TPO_CMD;
-				panel_id = TPO_CMD;
-			}
-		} else {
-			dev_info(dev->dev, "[GFX] Panel Parameter Passed in through cmd line\n");
-			dev_priv->panel_id = panel_id;
-		}
-	}
-}
-
-int mid_chip_setup(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	mid_get_fuse_settings(dev);
-	mid_get_vbt_data(dev_priv);
-	mid_get_pci_revID(dev_priv);
-	return 0;
-}
diff --git a/drivers/staging/gma500/mid_bios.h b/drivers/staging/gma500/mid_bios.h
deleted file mode 100644
index 00e7d56..0000000
--- a/drivers/staging/gma500/mid_bios.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-extern int mid_chip_setup(struct drm_device *dev);
-
diff --git a/drivers/staging/gma500/mmu.c b/drivers/staging/gma500/mmu.c
deleted file mode 100644
index c904d73..0000000
--- a/drivers/staging/gma500/mmu.c
+++ /dev/null
@@ -1,858 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_reg.h"
-
-/*
- * Code for the SGX MMU:
- */
-
-/*
- * clflush on one processor only:
- * clflush should apparently flush the cache line on all processors in an
- * SMP system.
- */
-
-/*
- * kmap atomic:
- * The usage of the slots must be completely encapsulated within a spinlock, and
- * no other functions that may be using the locks for other purposed may be
- * called from within the locked region.
- * Since the slots are per processor, this will guarantee that we are the only
- * user.
- */
-
-/*
- * TODO: Inserting ptes from an interrupt handler:
- * This may be desirable for some SGX functionality where the GPU can fault in
- * needed pages. For that, we need to make an atomic insert_pages function, that
- * may fail.
- * If it fails, the caller need to insert the page using a workqueue function,
- * but on average it should be fast.
- */
-
-struct psb_mmu_driver {
-	/* protects driver- and pd structures. Always take in read mode
-	 * before taking the page table spinlock.
-	 */
-	struct rw_semaphore sem;
-
-	/* protects page tables, directory tables and pt tables.
-	 * and pt structures.
-	 */
-	spinlock_t lock;
-
-	atomic_t needs_tlbflush;
-
-	uint8_t __iomem *register_map;
-	struct psb_mmu_pd *default_pd;
-	/*uint32_t bif_ctrl;*/
-	int has_clflush;
-	int clflush_add;
-	unsigned long clflush_mask;
-
-	struct drm_psb_private *dev_priv;
-};
-
-struct psb_mmu_pd;
-
-struct psb_mmu_pt {
-	struct psb_mmu_pd *pd;
-	uint32_t index;
-	uint32_t count;
-	struct page *p;
-	uint32_t *v;
-};
-
-struct psb_mmu_pd {
-	struct psb_mmu_driver *driver;
-	int hw_context;
-	struct psb_mmu_pt **tables;
-	struct page *p;
-	struct page *dummy_pt;
-	struct page *dummy_page;
-	uint32_t pd_mask;
-	uint32_t invalid_pde;
-	uint32_t invalid_pte;
-};
-
-static inline uint32_t psb_mmu_pt_index(uint32_t offset)
-{
-	return (offset >> PSB_PTE_SHIFT) & 0x3FF;
-}
-
-static inline uint32_t psb_mmu_pd_index(uint32_t offset)
-{
-	return offset >> PSB_PDE_SHIFT;
-}
-
-static inline void psb_clflush(void *addr)
-{
-	__asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory");
-}
-
-static inline void psb_mmu_clflush(struct psb_mmu_driver *driver,
-				   void *addr)
-{
-	if (!driver->has_clflush)
-		return;
-
-	mb();
-	psb_clflush(addr);
-	mb();
-}
-
-static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page)
-{
-	uint32_t clflush_add = driver->clflush_add >> PAGE_SHIFT;
-	uint32_t clflush_count = PAGE_SIZE / clflush_add;
-	int i;
-	uint8_t *clf;
-
-	clf = kmap_atomic(page, KM_USER0);
-	mb();
-	for (i = 0; i < clflush_count; ++i) {
-		psb_clflush(clf);
-		clf += clflush_add;
-	}
-	mb();
-	kunmap_atomic(clf, KM_USER0);
-}
-
-static void psb_pages_clflush(struct psb_mmu_driver *driver,
-				struct page *page[], unsigned long num_pages)
-{
-	int i;
-
-	if (!driver->has_clflush)
-		return ;
-
-	for (i = 0; i < num_pages; i++)
-		psb_page_clflush(driver, *page++);
-}
-
-static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver,
-				    int force)
-{
-	atomic_set(&driver->needs_tlbflush, 0);
-}
-
-static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force)
-{
-	down_write(&driver->sem);
-	psb_mmu_flush_pd_locked(driver, force);
-	up_write(&driver->sem);
-}
-
-void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot)
-{
-	if (rc_prot)
-		down_write(&driver->sem);
-	if (rc_prot)
-		up_write(&driver->sem);
-}
-
-void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context)
-{
-	/*ttm_tt_cache_flush(&pd->p, 1);*/
-	psb_pages_clflush(pd->driver, &pd->p, 1);
-	down_write(&pd->driver->sem);
-	wmb();
-	psb_mmu_flush_pd_locked(pd->driver, 1);
-	pd->hw_context = hw_context;
-	up_write(&pd->driver->sem);
-
-}
-
-static inline unsigned long psb_pd_addr_end(unsigned long addr,
-					    unsigned long end)
-{
-
-	addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK;
-	return (addr < end) ? addr : end;
-}
-
-static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type)
-{
-	uint32_t mask = PSB_PTE_VALID;
-
-	if (type & PSB_MMU_CACHED_MEMORY)
-		mask |= PSB_PTE_CACHED;
-	if (type & PSB_MMU_RO_MEMORY)
-		mask |= PSB_PTE_RO;
-	if (type & PSB_MMU_WO_MEMORY)
-		mask |= PSB_PTE_WO;
-
-	return (pfn << PAGE_SHIFT) | mask;
-}
-
-struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
-				    int trap_pagefaults, int invalid_type)
-{
-	struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL);
-	uint32_t *v;
-	int i;
-
-	if (!pd)
-		return NULL;
-
-	pd->p = alloc_page(GFP_DMA32);
-	if (!pd->p)
-		goto out_err1;
-	pd->dummy_pt = alloc_page(GFP_DMA32);
-	if (!pd->dummy_pt)
-		goto out_err2;
-	pd->dummy_page = alloc_page(GFP_DMA32);
-	if (!pd->dummy_page)
-		goto out_err3;
-
-	if (!trap_pagefaults) {
-		pd->invalid_pde =
-		    psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt),
-				     invalid_type);
-		pd->invalid_pte =
-		    psb_mmu_mask_pte(page_to_pfn(pd->dummy_page),
-				     invalid_type);
-	} else {
-		pd->invalid_pde = 0;
-		pd->invalid_pte = 0;
-	}
-
-	v = kmap(pd->dummy_pt);
-	for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
-		v[i] = pd->invalid_pte;
-
-	kunmap(pd->dummy_pt);
-
-	v = kmap(pd->p);
-	for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
-		v[i] = pd->invalid_pde;
-
-	kunmap(pd->p);
-
-	clear_page(kmap(pd->dummy_page));
-	kunmap(pd->dummy_page);
-
-	pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024);
-	if (!pd->tables)
-		goto out_err4;
-
-	pd->hw_context = -1;
-	pd->pd_mask = PSB_PTE_VALID;
-	pd->driver = driver;
-
-	return pd;
-
-out_err4:
-	__free_page(pd->dummy_page);
-out_err3:
-	__free_page(pd->dummy_pt);
-out_err2:
-	__free_page(pd->p);
-out_err1:
-	kfree(pd);
-	return NULL;
-}
-
-void psb_mmu_free_pt(struct psb_mmu_pt *pt)
-{
-	__free_page(pt->p);
-	kfree(pt);
-}
-
-void psb_mmu_free_pagedir(struct psb_mmu_pd *pd)
-{
-	struct psb_mmu_driver *driver = pd->driver;
-	struct psb_mmu_pt *pt;
-	int i;
-
-	down_write(&driver->sem);
-	if (pd->hw_context != -1)
-		psb_mmu_flush_pd_locked(driver, 1);
-
-	/* Should take the spinlock here, but we don't need to do that
-	   since we have the semaphore in write mode. */
-
-	for (i = 0; i < 1024; ++i) {
-		pt = pd->tables[i];
-		if (pt)
-			psb_mmu_free_pt(pt);
-	}
-
-	vfree(pd->tables);
-	__free_page(pd->dummy_page);
-	__free_page(pd->dummy_pt);
-	__free_page(pd->p);
-	kfree(pd);
-	up_write(&driver->sem);
-}
-
-static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
-{
-	struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL);
-	void *v;
-	uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT;
-	uint32_t clflush_count = PAGE_SIZE / clflush_add;
-	spinlock_t *lock = &pd->driver->lock;
-	uint8_t *clf;
-	uint32_t *ptes;
-	int i;
-
-	if (!pt)
-		return NULL;
-
-	pt->p = alloc_page(GFP_DMA32);
-	if (!pt->p) {
-		kfree(pt);
-		return NULL;
-	}
-
-	spin_lock(lock);
-
-	v = kmap_atomic(pt->p, KM_USER0);
-	clf = (uint8_t *) v;
-	ptes = (uint32_t *) v;
-	for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
-		*ptes++ = pd->invalid_pte;
-
-
-	if (pd->driver->has_clflush && pd->hw_context != -1) {
-		mb();
-		for (i = 0; i < clflush_count; ++i) {
-			psb_clflush(clf);
-			clf += clflush_add;
-		}
-		mb();
-	}
-
-	kunmap_atomic(v, KM_USER0);
-	spin_unlock(lock);
-
-	pt->count = 0;
-	pt->pd = pd;
-	pt->index = 0;
-
-	return pt;
-}
-
-struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd,
-					     unsigned long addr)
-{
-	uint32_t index = psb_mmu_pd_index(addr);
-	struct psb_mmu_pt *pt;
-	uint32_t *v;
-	spinlock_t *lock = &pd->driver->lock;
-
-	spin_lock(lock);
-	pt = pd->tables[index];
-	while (!pt) {
-		spin_unlock(lock);
-		pt = psb_mmu_alloc_pt(pd);
-		if (!pt)
-			return NULL;
-		spin_lock(lock);
-
-		if (pd->tables[index]) {
-			spin_unlock(lock);
-			psb_mmu_free_pt(pt);
-			spin_lock(lock);
-			pt = pd->tables[index];
-			continue;
-		}
-
-		v = kmap_atomic(pd->p, KM_USER0);
-		pd->tables[index] = pt;
-		v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask;
-		pt->index = index;
-		kunmap_atomic((void *) v, KM_USER0);
-
-		if (pd->hw_context != -1) {
-			psb_mmu_clflush(pd->driver, (void *) &v[index]);
-			atomic_set(&pd->driver->needs_tlbflush, 1);
-		}
-	}
-	pt->v = kmap_atomic(pt->p, KM_USER0);
-	return pt;
-}
-
-static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd,
-					      unsigned long addr)
-{
-	uint32_t index = psb_mmu_pd_index(addr);
-	struct psb_mmu_pt *pt;
-	spinlock_t *lock = &pd->driver->lock;
-
-	spin_lock(lock);
-	pt = pd->tables[index];
-	if (!pt) {
-		spin_unlock(lock);
-		return NULL;
-	}
-	pt->v = kmap_atomic(pt->p, KM_USER0);
-	return pt;
-}
-
-static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
-{
-	struct psb_mmu_pd *pd = pt->pd;
-	uint32_t *v;
-
-	kunmap_atomic(pt->v, KM_USER0);
-	if (pt->count == 0) {
-		v = kmap_atomic(pd->p, KM_USER0);
-		v[pt->index] = pd->invalid_pde;
-		pd->tables[pt->index] = NULL;
-
-		if (pd->hw_context != -1) {
-			psb_mmu_clflush(pd->driver,
-					(void *) &v[pt->index]);
-			atomic_set(&pd->driver->needs_tlbflush, 1);
-		}
-		kunmap_atomic(pt->v, KM_USER0);
-		spin_unlock(&pd->driver->lock);
-		psb_mmu_free_pt(pt);
-		return;
-	}
-	spin_unlock(&pd->driver->lock);
-}
-
-static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt,
-				   unsigned long addr, uint32_t pte)
-{
-	pt->v[psb_mmu_pt_index(addr)] = pte;
-}
-
-static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt,
-					  unsigned long addr)
-{
-	pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
-}
-
-
-void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
-			uint32_t mmu_offset, uint32_t gtt_start,
-			uint32_t gtt_pages)
-{
-	uint32_t *v;
-	uint32_t start = psb_mmu_pd_index(mmu_offset);
-	struct psb_mmu_driver *driver = pd->driver;
-	int num_pages = gtt_pages;
-
-	down_read(&driver->sem);
-	spin_lock(&driver->lock);
-
-	v = kmap_atomic(pd->p, KM_USER0);
-	v += start;
-
-	while (gtt_pages--) {
-		*v++ = gtt_start | pd->pd_mask;
-		gtt_start += PAGE_SIZE;
-	}
-
-	/*ttm_tt_cache_flush(&pd->p, num_pages);*/
-	psb_pages_clflush(pd->driver, &pd->p, num_pages);
-	kunmap_atomic(v, KM_USER0);
-	spin_unlock(&driver->lock);
-
-	if (pd->hw_context != -1)
-		atomic_set(&pd->driver->needs_tlbflush, 1);
-
-	up_read(&pd->driver->sem);
-	psb_mmu_flush_pd(pd->driver, 0);
-}
-
-struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver)
-{
-	struct psb_mmu_pd *pd;
-
-	/* down_read(&driver->sem); */
-	pd = driver->default_pd;
-	/* up_read(&driver->sem); */
-
-	return pd;
-}
-
-/* Returns the physical address of the PD shared by sgx/msvdx */
-uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver)
-{
-	struct psb_mmu_pd *pd;
-
-	pd = psb_mmu_get_default_pd(driver);
-	return page_to_pfn(pd->p) << PAGE_SHIFT;
-}
-
-void psb_mmu_driver_takedown(struct psb_mmu_driver *driver)
-{
-	psb_mmu_free_pagedir(driver->default_pd);
-	kfree(driver);
-}
-
-struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
-					int trap_pagefaults,
-					int invalid_type,
-					struct drm_psb_private *dev_priv)
-{
-	struct psb_mmu_driver *driver;
-
-	driver = kmalloc(sizeof(*driver), GFP_KERNEL);
-
-	if (!driver)
-		return NULL;
-	driver->dev_priv = dev_priv;
-
-	driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults,
-					      invalid_type);
-	if (!driver->default_pd)
-		goto out_err1;
-
-	spin_lock_init(&driver->lock);
-	init_rwsem(&driver->sem);
-	down_write(&driver->sem);
-	driver->register_map = registers;
-	atomic_set(&driver->needs_tlbflush, 1);
-
-	driver->has_clflush = 0;
-
-	if (boot_cpu_has(X86_FEATURE_CLFLSH)) {
-		uint32_t tfms, misc, cap0, cap4, clflush_size;
-
-		/*
-		 * clflush size is determined at kernel setup for x86_64
-		 *  but not for i386. We have to do it here.
-		 */
-
-		cpuid(0x00000001, &tfms, &misc, &cap0, &cap4);
-		clflush_size = ((misc >> 8) & 0xff) * 8;
-		driver->has_clflush = 1;
-		driver->clflush_add =
-		    PAGE_SIZE * clflush_size / sizeof(uint32_t);
-		driver->clflush_mask = driver->clflush_add - 1;
-		driver->clflush_mask = ~driver->clflush_mask;
-	}
-
-	up_write(&driver->sem);
-	return driver;
-
-out_err1:
-	kfree(driver);
-	return NULL;
-}
-
-static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd,
-			       unsigned long address, uint32_t num_pages,
-			       uint32_t desired_tile_stride,
-			       uint32_t hw_tile_stride)
-{
-	struct psb_mmu_pt *pt;
-	uint32_t rows = 1;
-	uint32_t i;
-	unsigned long addr;
-	unsigned long end;
-	unsigned long next;
-	unsigned long add;
-	unsigned long row_add;
-	unsigned long clflush_add = pd->driver->clflush_add;
-	unsigned long clflush_mask = pd->driver->clflush_mask;
-
-	if (!pd->driver->has_clflush) {
-		/*ttm_tt_cache_flush(&pd->p, num_pages);*/
-		psb_pages_clflush(pd->driver, &pd->p, num_pages);
-		return;
-	}
-
-	if (hw_tile_stride)
-		rows = num_pages / desired_tile_stride;
-	else
-		desired_tile_stride = num_pages;
-
-	add = desired_tile_stride << PAGE_SHIFT;
-	row_add = hw_tile_stride << PAGE_SHIFT;
-	mb();
-	for (i = 0; i < rows; ++i) {
-
-		addr = address;
-		end = addr + add;
-
-		do {
-			next = psb_pd_addr_end(addr, end);
-			pt = psb_mmu_pt_map_lock(pd, addr);
-			if (!pt)
-				continue;
-			do {
-				psb_clflush(&pt->v
-					    [psb_mmu_pt_index(addr)]);
-			} while (addr +=
-				 clflush_add,
-				 (addr & clflush_mask) < next);
-
-			psb_mmu_pt_unmap_unlock(pt);
-		} while (addr = next, next != end);
-		address += row_add;
-	}
-	mb();
-}
-
-void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
-				 unsigned long address, uint32_t num_pages)
-{
-	struct psb_mmu_pt *pt;
-	unsigned long addr;
-	unsigned long end;
-	unsigned long next;
-	unsigned long f_address = address;
-
-	down_read(&pd->driver->sem);
-
-	addr = address;
-	end = addr + (num_pages << PAGE_SHIFT);
-
-	do {
-		next = psb_pd_addr_end(addr, end);
-		pt = psb_mmu_pt_alloc_map_lock(pd, addr);
-		if (!pt)
-			goto out;
-		do {
-			psb_mmu_invalidate_pte(pt, addr);
-			--pt->count;
-		} while (addr += PAGE_SIZE, addr < next);
-		psb_mmu_pt_unmap_unlock(pt);
-
-	} while (addr = next, next != end);
-
-out:
-	if (pd->hw_context != -1)
-		psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
-
-	up_read(&pd->driver->sem);
-
-	if (pd->hw_context != -1)
-		psb_mmu_flush(pd->driver, 0);
-
-	return;
-}
-
-void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address,
-			  uint32_t num_pages, uint32_t desired_tile_stride,
-			  uint32_t hw_tile_stride)
-{
-	struct psb_mmu_pt *pt;
-	uint32_t rows = 1;
-	uint32_t i;
-	unsigned long addr;
-	unsigned long end;
-	unsigned long next;
-	unsigned long add;
-	unsigned long row_add;
-	unsigned long f_address = address;
-
-	if (hw_tile_stride)
-		rows = num_pages / desired_tile_stride;
-	else
-		desired_tile_stride = num_pages;
-
-	add = desired_tile_stride << PAGE_SHIFT;
-	row_add = hw_tile_stride << PAGE_SHIFT;
-
-	/* down_read(&pd->driver->sem); */
-
-	/* Make sure we only need to flush this processor's cache */
-
-	for (i = 0; i < rows; ++i) {
-
-		addr = address;
-		end = addr + add;
-
-		do {
-			next = psb_pd_addr_end(addr, end);
-			pt = psb_mmu_pt_map_lock(pd, addr);
-			if (!pt)
-				continue;
-			do {
-				psb_mmu_invalidate_pte(pt, addr);
-				--pt->count;
-
-			} while (addr += PAGE_SIZE, addr < next);
-			psb_mmu_pt_unmap_unlock(pt);
-
-		} while (addr = next, next != end);
-		address += row_add;
-	}
-	if (pd->hw_context != -1)
-		psb_mmu_flush_ptes(pd, f_address, num_pages,
-				   desired_tile_stride, hw_tile_stride);
-
-	/* up_read(&pd->driver->sem); */
-
-	if (pd->hw_context != -1)
-		psb_mmu_flush(pd->driver, 0);
-}
-
-int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn,
-				unsigned long address, uint32_t num_pages,
-				int type)
-{
-	struct psb_mmu_pt *pt;
-	uint32_t pte;
-	unsigned long addr;
-	unsigned long end;
-	unsigned long next;
-	unsigned long f_address = address;
-	int ret = 0;
-
-	down_read(&pd->driver->sem);
-
-	addr = address;
-	end = addr + (num_pages << PAGE_SHIFT);
-
-	do {
-		next = psb_pd_addr_end(addr, end);
-		pt = psb_mmu_pt_alloc_map_lock(pd, addr);
-		if (!pt) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		do {
-			pte = psb_mmu_mask_pte(start_pfn++, type);
-			psb_mmu_set_pte(pt, addr, pte);
-			pt->count++;
-		} while (addr += PAGE_SIZE, addr < next);
-		psb_mmu_pt_unmap_unlock(pt);
-
-	} while (addr = next, next != end);
-
-out:
-	if (pd->hw_context != -1)
-		psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1);
-
-	up_read(&pd->driver->sem);
-
-	if (pd->hw_context != -1)
-		psb_mmu_flush(pd->driver, 1);
-
-	return ret;
-}
-
-int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
-			 unsigned long address, uint32_t num_pages,
-			 uint32_t desired_tile_stride,
-			 uint32_t hw_tile_stride, int type)
-{
-	struct psb_mmu_pt *pt;
-	uint32_t rows = 1;
-	uint32_t i;
-	uint32_t pte;
-	unsigned long addr;
-	unsigned long end;
-	unsigned long next;
-	unsigned long add;
-	unsigned long row_add;
-	unsigned long f_address = address;
-	int ret = 0;
-
-	if (hw_tile_stride) {
-		if (num_pages % desired_tile_stride != 0)
-			return -EINVAL;
-		rows = num_pages / desired_tile_stride;
-	} else {
-		desired_tile_stride = num_pages;
-	}
-
-	add = desired_tile_stride << PAGE_SHIFT;
-	row_add = hw_tile_stride << PAGE_SHIFT;
-
-	down_read(&pd->driver->sem);
-
-	for (i = 0; i < rows; ++i) {
-
-		addr = address;
-		end = addr + add;
-
-		do {
-			next = psb_pd_addr_end(addr, end);
-			pt = psb_mmu_pt_alloc_map_lock(pd, addr);
-			if (!pt) {
-				ret = -ENOMEM;
-				goto out;
-			}
-			do {
-				pte =
-				    psb_mmu_mask_pte(page_to_pfn(*pages++),
-						     type);
-				psb_mmu_set_pte(pt, addr, pte);
-				pt->count++;
-			} while (addr += PAGE_SIZE, addr < next);
-			psb_mmu_pt_unmap_unlock(pt);
-
-		} while (addr = next, next != end);
-
-		address += row_add;
-	}
-out:
-	if (pd->hw_context != -1)
-		psb_mmu_flush_ptes(pd, f_address, num_pages,
-				   desired_tile_stride, hw_tile_stride);
-
-	up_read(&pd->driver->sem);
-
-	if (pd->hw_context != -1)
-		psb_mmu_flush(pd->driver, 1);
-
-	return ret;
-}
-
-int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
-			   unsigned long *pfn)
-{
-	int ret;
-	struct psb_mmu_pt *pt;
-	uint32_t tmp;
-	spinlock_t *lock = &pd->driver->lock;
-
-	down_read(&pd->driver->sem);
-	pt = psb_mmu_pt_map_lock(pd, virtual);
-	if (!pt) {
-		uint32_t *v;
-
-		spin_lock(lock);
-		v = kmap_atomic(pd->p, KM_USER0);
-		tmp = v[psb_mmu_pd_index(virtual)];
-		kunmap_atomic(v, KM_USER0);
-		spin_unlock(lock);
-
-		if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) ||
-		    !(pd->invalid_pte & PSB_PTE_VALID)) {
-			ret = -EINVAL;
-			goto out;
-		}
-		ret = 0;
-		*pfn = pd->invalid_pte >> PAGE_SHIFT;
-		goto out;
-	}
-	tmp = pt->v[psb_mmu_pt_index(virtual)];
-	if (!(tmp & PSB_PTE_VALID)) {
-		ret = -EINVAL;
-	} else {
-		ret = 0;
-		*pfn = tmp >> PAGE_SHIFT;
-	}
-	psb_mmu_pt_unmap_unlock(pt);
-out:
-	up_read(&pd->driver->sem);
-	return ret;
-}
diff --git a/drivers/staging/gma500/mrst.h b/drivers/staging/gma500/mrst.h
deleted file mode 100644
index b563dbc..0000000
--- a/drivers/staging/gma500/mrst.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-/* MID device specific descriptors */
-
-struct mrst_vbt {
-	s8 signature[4];	/*4 bytes,"$GCT" */
-	u8 revision;
-	u8 size;
-	u8 checksum;
-	void *mrst_gct;
-} __packed;
-
-struct mrst_timing_info {
-	u16 pixel_clock;
-	u8 hactive_lo;
-	u8 hblank_lo;
-	u8 hblank_hi:4;
-	u8 hactive_hi:4;
-	u8 vactive_lo;
-	u8 vblank_lo;
-	u8 vblank_hi:4;
-	u8 vactive_hi:4;
-	u8 hsync_offset_lo;
-	u8 hsync_pulse_width_lo;
-	u8 vsync_pulse_width_lo:4;
-	u8 vsync_offset_lo:4;
-	u8 vsync_pulse_width_hi:2;
-	u8 vsync_offset_hi:2;
-	u8 hsync_pulse_width_hi:2;
-	u8 hsync_offset_hi:2;
-	u8 width_mm_lo;
-	u8 height_mm_lo;
-	u8 height_mm_hi:4;
-	u8 width_mm_hi:4;
-	u8 hborder;
-	u8 vborder;
-	u8 unknown0:1;
-	u8 hsync_positive:1;
-	u8 vsync_positive:1;
-	u8 separate_sync:2;
-	u8 stereo:1;
-	u8 unknown6:1;
-	u8 interlaced:1;
-} __packed;
-
-struct gct_r10_timing_info {
-	u16 pixel_clock;
-	u32 hactive_lo:8;
-	u32 hactive_hi:4;
-	u32 hblank_lo:8;
-	u32 hblank_hi:4;
-	u32 hsync_offset_lo:8;
-	u16 hsync_offset_hi:2;
-	u16 hsync_pulse_width_lo:8;
-	u16 hsync_pulse_width_hi:2;
-	u16 hsync_positive:1;
-	u16 rsvd_1:3;
-	u8  vactive_lo:8;
-	u16 vactive_hi:4;
-	u16 vblank_lo:8;
-	u16 vblank_hi:4;
-	u16 vsync_offset_lo:4;
-	u16 vsync_offset_hi:2;
-	u16 vsync_pulse_width_lo:4;
-	u16 vsync_pulse_width_hi:2;
-	u16 vsync_positive:1;
-	u16 rsvd_2:3;
-} __packed;
-
-struct mrst_panel_descriptor_v1 {
-	u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
-				/* 0x61190 if MIPI */
-	u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
-	u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
-	u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */
-						/* Register 0x61210 */
-	struct mrst_timing_info DTD;/*18 bytes, Standard definition */
-	u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */
-				/* Bit 0, Frequency, 15 bits,0 - 32767Hz */
-			/* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */
-	u16 Panel_MIPI_Display_Descriptor;
-			/*16 bits, Defined as follows: */
-			/* if MIPI, 0x0000 if LVDS */
-			/* Bit 0, Type, 2 bits, */
-			/* 0: Type-1, */
-			/* 1: Type-2, */
-			/* 2: Type-3, */
-			/* 3: Type-4 */
-			/* Bit 2, Pixel Format, 4 bits */
-			/* Bit0: 16bpp (not supported in LNC), */
-			/* Bit1: 18bpp loosely packed, */
-			/* Bit2: 18bpp packed, */
-			/* Bit3: 24bpp */
-			/* Bit 6, Reserved, 2 bits, 00b */
-			/* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
-			/* Bit 14, Reserved, 2 bits, 00b */
-} __packed;
-
-struct mrst_panel_descriptor_v2 {
-	u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
-				/* 0x61190 if MIPI */
-	u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
-	u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
-	u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */
-						/* Register 0x61210 */
-	struct mrst_timing_info DTD;/*18 bytes, Standard definition */
-	u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/
-				/*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/
-	u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */
-			/*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/
-	u16 Panel_MIPI_Display_Descriptor;
-			/*16 bits, Defined as follows: */
-			/* if MIPI, 0x0000 if LVDS */
-			/* Bit 0, Type, 2 bits, */
-			/* 0: Type-1, */
-			/* 1: Type-2, */
-			/* 2: Type-3, */
-			/* 3: Type-4 */
-			/* Bit 2, Pixel Format, 4 bits */
-			/* Bit0: 16bpp (not supported in LNC), */
-			/* Bit1: 18bpp loosely packed, */
-			/* Bit2: 18bpp packed, */
-			/* Bit3: 24bpp */
-			/* Bit 6, Reserved, 2 bits, 00b */
-			/* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
-			/* Bit 14, Reserved, 2 bits, 00b */
-} __packed;
-
-union mrst_panel_rx {
-	struct {
-		u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/
-			/* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */
-		u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */
-		/*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/
-		u16 SupportedVideoTransferMode:2; /*0: Non-burst only */
-					/* 1: Burst and non-burst */
-					/* 2/3: Reserved */
-		u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/
-		u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/
-		u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/
-		u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */
-		u16 Rsvd:5;/*5 bits,00000b */
-	} panelrx;
-	u16 panel_receiver;
-} __packed;
-
-struct mrst_gct_v1 {
-	union { /*8 bits,Defined as follows: */
-		struct {
-			u8 PanelType:4; /*4 bits, Bit field for panels*/
-					/* 0 - 3: 0 = LVDS, 1 = MIPI*/
-					/*2 bits,Specifies which of the*/
-			u8 BootPanelIndex:2;
-					/* 4 panels to use by default*/
-			u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
-					/* the 4 MIPI DSI receivers to use*/
-		} PD;
-		u8 PanelDescriptor;
-	};
-	struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/
-	union mrst_panel_rx panelrx[4]; /* panel receivers*/
-} __packed;
-
-struct mrst_gct_v2 {
-	union { /*8 bits,Defined as follows: */
-		struct {
-			u8 PanelType:4; /*4 bits, Bit field for panels*/
-					/* 0 - 3: 0 = LVDS, 1 = MIPI*/
-					/*2 bits,Specifies which of the*/
-			u8 BootPanelIndex:2;
-					/* 4 panels to use by default*/
-			u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
-					/* the 4 MIPI DSI receivers to use*/
-		} PD;
-		u8 PanelDescriptor;
-	};
-	struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/
-	union mrst_panel_rx panelrx[4]; /* panel receivers*/
-} __packed;
-
-struct mrst_gct_data {
-	u8 bpi; /* boot panel index, number of panel used during boot */
-	u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */
-	struct mrst_timing_info DTD; /* timing info for the selected panel */
-	u32 Panel_Port_Control;
-	u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/
-	u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/
-	u32 PP_Cycle_Delay;
-	u16 Panel_Backlight_Inverter_Descriptor;
-	u16 Panel_MIPI_Display_Descriptor;
-} __packed;
-
-#define MODE_SETTING_IN_CRTC		0x1
-#define MODE_SETTING_IN_ENCODER		0x2
-#define MODE_SETTING_ON_GOING		0x3
-#define MODE_SETTING_IN_DSR		0x4
-#define MODE_SETTING_ENCODER_DONE	0x8
-
-#define GCT_R10_HEADER_SIZE		16
-#define GCT_R10_DISPLAY_DESC_SIZE	28
-
-/*
- *	Moorestown HDMI interfaces
- */
-
-struct mrst_hdmi_dev {
-	struct pci_dev *dev;
-	void __iomem *regs;
-	unsigned int mmio, mmio_len;
-	int dpms_mode;
-	struct hdmi_i2c_dev *i2c_dev;
-
-	/* register state */
-	u32 saveDPLL_CTRL;
-	u32 saveDPLL_DIV_CTRL;
-	u32 saveDPLL_ADJUST;
-	u32 saveDPLL_UPDATE;
-	u32 saveDPLL_CLK_ENABLE;
-	u32 savePCH_HTOTAL_B;
-	u32 savePCH_HBLANK_B;
-	u32 savePCH_HSYNC_B;
-	u32 savePCH_VTOTAL_B;
-	u32 savePCH_VBLANK_B;
-	u32 savePCH_VSYNC_B;
-	u32 savePCH_PIPEBCONF;
-	u32 savePCH_PIPEBSRC;
-};
-
-extern void mrst_hdmi_setup(struct drm_device *dev);
-extern void mrst_hdmi_teardown(struct drm_device *dev);
-extern int  mrst_hdmi_i2c_init(struct pci_dev *dev);
-extern void mrst_hdmi_i2c_exit(struct pci_dev *dev);
-extern void mrst_hdmi_save(struct drm_device *dev);
-extern void mrst_hdmi_restore(struct drm_device *dev);
-extern void mrst_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev);
diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c
deleted file mode 100644
index 980837e..0000000
--- a/drivers/staging/gma500/mrst_crtc.c
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-
-#include <drm/drmP.h>
-#include "framebuffer.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_display.h"
-#include "power.h"
-
-struct psb_intel_range_t {
-	int min, max;
-};
-
-struct mrst_limit_t {
-	struct psb_intel_range_t dot, m, p1;
-};
-
-struct mrst_clock_t {
-	/* derived values */
-	int dot;
-	int m;
-	int p1;
-};
-
-#define MRST_LIMIT_LVDS_100L	    0
-#define MRST_LIMIT_LVDS_83	    1
-#define MRST_LIMIT_LVDS_100	    2
-
-#define MRST_DOT_MIN		  19750
-#define MRST_DOT_MAX		  120000
-#define MRST_M_MIN_100L		    20
-#define MRST_M_MIN_100		    10
-#define MRST_M_MIN_83		    12
-#define MRST_M_MAX_100L		    34
-#define MRST_M_MAX_100		    17
-#define MRST_M_MAX_83		    20
-#define MRST_P1_MIN		    2
-#define MRST_P1_MAX_0		    7
-#define MRST_P1_MAX_1		    8
-
-static const struct mrst_limit_t mrst_limits[] = {
-	{			/* MRST_LIMIT_LVDS_100L */
-	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
-	 .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
-	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
-	 },
-	{			/* MRST_LIMIT_LVDS_83L */
-	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
-	 .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
-	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
-	 },
-	{			/* MRST_LIMIT_LVDS_100 */
-	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
-	 .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
-	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
-	 },
-};
-
-#define MRST_M_MIN	    10
-static const u32 mrst_m_converts[] = {
-	0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C,
-	0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25,
-	0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
-};
-
-static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)
-{
-	const struct mrst_limit_t *limit = NULL;
-	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
-	    || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
-		switch (dev_priv->core_freq) {
-		case 100:
-			limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
-			break;
-		case 166:
-			limit = &mrst_limits[MRST_LIMIT_LVDS_83];
-			break;
-		case 200:
-			limit = &mrst_limits[MRST_LIMIT_LVDS_100];
-			break;
-		}
-	} else {
-		limit = NULL;
-		dev_err(dev->dev, "mrst_limit Wrong display type.\n");
-	}
-
-	return limit;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-static void mrst_clock(int refclk, struct mrst_clock_t *clock)
-{
-	clock->dot = (refclk * clock->m) / (14 * clock->p1);
-}
-
-void mrstPrintPll(char *prefix, struct mrst_clock_t *clock)
-{
-	pr_debug("%s: dotclock = %d,  m = %d, p1 = %d.\n",
-	     prefix, clock->dot, clock->m, clock->p1);
-}
-
-/**
- * Returns a set of divisors for the desired target clock with the given refclk,
- * or FALSE.  Divisor values are the actual divisors for
- */
-static bool
-mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
-		struct mrst_clock_t *best_clock)
-{
-	struct mrst_clock_t clock;
-	const struct mrst_limit_t *limit = mrst_limit(crtc);
-	int err = target;
-
-	memset(best_clock, 0, sizeof(*best_clock));
-
-	for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
-		for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
-		     clock.p1++) {
-			int this_err;
-
-			mrst_clock(refclk, &clock);
-
-			this_err = abs(clock.dot - target);
-			if (this_err < err) {
-				*best_clock = clock;
-				err = this_err;
-			}
-		}
-	}
-	dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err);
-	return err != target;
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE;
-	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-	u32 temp;
-	bool enabled;
-
-	if (!gma_power_begin(dev, true))
-		return;
-
-	/* XXX: When our outputs are all unaware of DPMS modes other than off
-	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-	 */
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-		/* Enable the DPLL */
-		temp = REG_READ(dpll_reg);
-		if ((temp & DPLL_VCO_ENABLE) == 0) {
-			REG_WRITE(dpll_reg, temp);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-		}
-		/* Enable the pipe */
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_ENABLE) == 0)
-			REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
-		/* Enable the plane */
-		temp = REG_READ(dspcntr_reg);
-		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-			REG_WRITE(dspcntr_reg,
-				  temp | DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-		}
-
-		psb_intel_crtc_load_lut(crtc);
-
-		/* Give the overlay scaler a chance to enable
-		   if it's on this pipe */
-		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
-		break;
-	case DRM_MODE_DPMS_OFF:
-		/* Give the overlay scaler a chance to disable
-		 * if it's on this pipe */
-		/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-
-		/* Disable the VGA plane that we never use */
-		REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-		/* Disable display plane */
-		temp = REG_READ(dspcntr_reg);
-		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-			REG_WRITE(dspcntr_reg,
-				  temp & ~DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-			REG_READ(dspbase_reg);
-		}
-
-		/* Next, disable display pipes */
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_ENABLE) != 0) {
-			REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
-			REG_READ(pipeconf_reg);
-		}
-		/* Wait for for the pipe disable to take effect. */
-		psb_intel_wait_for_vblank(dev);
-
-		temp = REG_READ(dpll_reg);
-		if ((temp & DPLL_VCO_ENABLE) != 0) {
-			REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-		}
-
-		/* Wait for the clocks to turn off. */
-		udelay(150);
-		break;
-	}
-
-	enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-
-	/*Set FIFO Watermarks*/
-	REG_WRITE(DSPARB, 0x3FFF);
-	REG_WRITE(DSPFW1, 0x3F88080A);
-	REG_WRITE(DSPFW2, 0x0b060808);
-	REG_WRITE(DSPFW3, 0x0);
-	REG_WRITE(DSPFW4, 0x08030404);
-	REG_WRITE(DSPFW5, 0x04040404);
-	REG_WRITE(DSPFW6, 0x78);
-	REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000);
-	/* Must write Bit 14 of the Chicken Bit Register */
-
-	gma_power_end(dev);
-}
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int mrst_panel_fitter_pipe(struct drm_device *dev)
-{
-	u32 pfit_control;
-
-	pfit_control = REG_READ(PFIT_CONTROL);
-
-	/* See if the panel fitter is in use */
-	if ((pfit_control & PFIT_ENABLE) == 0)
-		return -1;
-	return (pfit_control >> 29) & 3;
-}
-
-static int mrst_crtc_mode_set(struct drm_crtc *crtc,
-			      struct drm_display_mode *mode,
-			      struct drm_display_mode *adjusted_mode,
-			      int x, int y,
-			      struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int pipe = psb_intel_crtc->pipe;
-	int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0;
-	int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-	int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
-	int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
-	int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
-	int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
-	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
-	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-	int refclk = 0;
-	struct mrst_clock_t clock;
-	u32 dpll = 0, fp = 0, dspcntr, pipeconf;
-	bool ok, is_sdvo = false;
-	bool is_crt = false, is_lvds = false, is_tv = false;
-	bool is_mipi = false;
-	struct drm_mode_config *mode_config = &dev->mode_config;
-	struct psb_intel_output *psb_intel_output = NULL;
-	uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
-	struct drm_encoder *encoder;
-
-	if (!gma_power_begin(dev, true))
-		return 0;
-
-	memcpy(&psb_intel_crtc->saved_mode,
-		mode,
-		sizeof(struct drm_display_mode));
-	memcpy(&psb_intel_crtc->saved_adjusted_mode,
-		adjusted_mode,
-		sizeof(struct drm_display_mode));
-
-	list_for_each_entry(encoder, &mode_config->encoder_list, head) {
-
-		if (encoder->crtc != crtc)
-			continue;
-
-		psb_intel_output = enc_to_psb_intel_output(encoder);
-		switch (psb_intel_output->type) {
-		case INTEL_OUTPUT_LVDS:
-			is_lvds = true;
-			break;
-		case INTEL_OUTPUT_SDVO:
-			is_sdvo = true;
-			break;
-		case INTEL_OUTPUT_TVOUT:
-			is_tv = true;
-			break;
-		case INTEL_OUTPUT_ANALOG:
-			is_crt = true;
-			break;
-		case INTEL_OUTPUT_MIPI:
-			is_mipi = true;
-			break;
-		}
-	}
-
-	/* Disable the VGA plane that we never use */
-	REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-	/* Disable the panel fitter if it was on our pipe */
-	if (mrst_panel_fitter_pipe(dev) == pipe)
-		REG_WRITE(PFIT_CONTROL, 0);
-
-	REG_WRITE(pipesrc_reg,
-		  ((mode->crtc_hdisplay - 1) << 16) |
-		  (mode->crtc_vdisplay - 1));
-
-	if (psb_intel_output)
-		drm_connector_property_get_value(&psb_intel_output->base,
-			dev->mode_config.scaling_mode_property, &scalingType);
-
-	if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
-		/* Moorestown doesn't have register support for centering so
-		 * we need to mess with the h/vblank and h/vsync start and
-		 * ends to get centering */
-		int offsetX = 0, offsetY = 0;
-
-		offsetX = (adjusted_mode->crtc_hdisplay -
-			   mode->crtc_hdisplay) / 2;
-		offsetY = (adjusted_mode->crtc_vdisplay -
-			   mode->crtc_vdisplay) / 2;
-
-		REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
-			((adjusted_mode->crtc_htotal - 1) << 16));
-		REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
-			((adjusted_mode->crtc_vtotal - 1) << 16));
-		REG_WRITE(hblank_reg,
-			(adjusted_mode->crtc_hblank_start - offsetX - 1) |
-			((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
-		REG_WRITE(hsync_reg,
-			(adjusted_mode->crtc_hsync_start - offsetX - 1) |
-			((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
-		REG_WRITE(vblank_reg,
-			(adjusted_mode->crtc_vblank_start - offsetY - 1) |
-			((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
-		REG_WRITE(vsync_reg,
-			(adjusted_mode->crtc_vsync_start - offsetY - 1) |
-			((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
-	} else {
-		REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
-			((adjusted_mode->crtc_htotal - 1) << 16));
-		REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
-			((adjusted_mode->crtc_vtotal - 1) << 16));
-		REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
-			((adjusted_mode->crtc_hblank_end - 1) << 16));
-		REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
-			((adjusted_mode->crtc_hsync_end - 1) << 16));
-		REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
-			((adjusted_mode->crtc_vblank_end - 1) << 16));
-		REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
-			((adjusted_mode->crtc_vsync_end - 1) << 16));
-	}
-
-	/* Flush the plane changes */
-	{
-		struct drm_crtc_helper_funcs *crtc_funcs =
-		    crtc->helper_private;
-		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-	}
-
-	/* setup pipeconf */
-	pipeconf = REG_READ(pipeconf_reg);
-
-	/* Set up the display plane register */
-	dspcntr = REG_READ(dspcntr_reg);
-	dspcntr |= DISPPLANE_GAMMA_ENABLE;
-
-	if (pipe == 0)
-		dspcntr |= DISPPLANE_SEL_PIPE_A;
-	else
-		dspcntr |= DISPPLANE_SEL_PIPE_B;
-
-	dev_priv->dspcntr = dspcntr |= DISPLAY_PLANE_ENABLE;
-	dev_priv->pipeconf = pipeconf |= PIPEACONF_ENABLE;
-
-	if (is_mipi)
-		goto mrst_crtc_mode_set_exit;
-
-	refclk = dev_priv->core_freq * 1000;
-
-	dpll = 0;		/*BIT16 = 0 for 100MHz reference */
-
-	ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock);
-
-	if (!ok) {
-		dev_dbg(dev->dev, "mrstFindBestPLL fail in mrst_crtc_mode_set.\n");
-	} else {
-		dev_dbg(dev->dev, "mrst_crtc_mode_set pixel clock = %d,"
-			 "m = %x, p1 = %x.\n", clock.dot, clock.m,
-			 clock.p1);
-	}
-
-	fp = mrst_m_converts[(clock.m - MRST_M_MIN)] << 8;
-
-	dpll |= DPLL_VGA_MODE_DIS;
-
-
-	dpll |= DPLL_VCO_ENABLE;
-
-	if (is_lvds)
-		dpll |= DPLLA_MODE_LVDS;
-	else
-		dpll |= DPLLB_MODE_DAC_SERIAL;
-
-	if (is_sdvo) {
-		int sdvo_pixel_multiply =
-		    adjusted_mode->clock / mode->clock;
-
-		dpll |= DPLL_DVO_HIGH_SPEED;
-		dpll |=
-		    (sdvo_pixel_multiply -
-		     1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-	}
-
-
-	/* compute bitmask from p1 value */
-	dpll |= (1 << (clock.p1 - 2)) << 17;
-
-	dpll |= DPLL_VCO_ENABLE;
-
-	mrstPrintPll("chosen", &clock);
-
-	if (dpll & DPLL_VCO_ENABLE) {
-		REG_WRITE(fp_reg, fp);
-		REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
-		REG_READ(dpll_reg);
-		/* Check the DPLLA lock bit PIPEACONF[29] */
-		udelay(150);
-	}
-
-	REG_WRITE(fp_reg, fp);
-	REG_WRITE(dpll_reg, dpll);
-	REG_READ(dpll_reg);
-	/* Wait for the clocks to stabilize. */
-	udelay(150);
-
-	/* write it again -- the BIOS does, after all */
-	REG_WRITE(dpll_reg, dpll);
-	REG_READ(dpll_reg);
-	/* Wait for the clocks to stabilize. */
-	udelay(150);
-
-	REG_WRITE(pipeconf_reg, pipeconf);
-	REG_READ(pipeconf_reg);
-	psb_intel_wait_for_vblank(dev);
-
-	REG_WRITE(dspcntr_reg, dspcntr);
-	psb_intel_wait_for_vblank(dev);
-
-mrst_crtc_mode_set_exit:
-	gma_power_end(dev);
-	return 0;
-}
-
-static bool mrst_crtc_mode_fixup(struct drm_crtc *crtc,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-int mrst_pipe_set_base(struct drm_crtc *crtc,
-			    int x, int y, struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-	int pipe = psb_intel_crtc->pipe;
-	unsigned long start, offset;
-
-	int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE);
-	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
-	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	u32 dspcntr;
-	int ret = 0;
-
-	/* no fb bound */
-	if (!crtc->fb) {
-		dev_dbg(dev->dev, "No FB bound\n");
-		return 0;
-	}
-
-	if (!gma_power_begin(dev, true))
-		return 0;
-
-	start = psbfb->gtt->offset;
-	offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
-	REG_WRITE(dspstride, crtc->fb->pitches[0]);
-
-	dspcntr = REG_READ(dspcntr_reg);
-	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
-	switch (crtc->fb->bits_per_pixel) {
-	case 8:
-		dspcntr |= DISPPLANE_8BPP;
-		break;
-	case 16:
-		if (crtc->fb->depth == 15)
-			dspcntr |= DISPPLANE_15_16BPP;
-		else
-			dspcntr |= DISPPLANE_16BPP;
-		break;
-	case 24:
-	case 32:
-		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-		break;
-	default:
-		dev_err(dev->dev, "Unknown color depth\n");
-		ret = -EINVAL;
-		goto pipe_set_base_exit;
-	}
-	REG_WRITE(dspcntr_reg, dspcntr);
-
-	REG_WRITE(dspbase, offset);
-	REG_READ(dspbase);
-	REG_WRITE(dspsurf, start);
-	REG_READ(dspsurf);
-
-pipe_set_base_exit:
-	gma_power_end(dev);
-	return ret;
-}
-
-static void mrst_crtc_prepare(struct drm_crtc *crtc)
-{
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void mrst_crtc_commit(struct drm_crtc *crtc)
-{
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-const struct drm_crtc_helper_funcs mrst_helper_funcs = {
-	.dpms = mrst_crtc_dpms,
-	.mode_fixup = mrst_crtc_mode_fixup,
-	.mode_set = mrst_crtc_mode_set,
-	.mode_set_base = mrst_pipe_set_base,
-	.prepare = mrst_crtc_prepare,
-	.commit = mrst_crtc_commit,
-};
-
diff --git a/drivers/staging/gma500/mrst_device.c b/drivers/staging/gma500/mrst_device.c
deleted file mode 100644
index 6707faf..0000000
--- a/drivers/staging/gma500/mrst_device.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/backlight.h>
-#include <linux/module.h>
-#include <linux/dmi.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include <asm/mrst.h>
-#include <asm/intel_scu_ipc.h>
-#include "mid_bios.h"
-
-static int devtype;
-
-module_param_named(type, devtype, int, 0600);
-MODULE_PARM_DESC(type, "Moorestown/Oaktrail device type");
-
-#define DEVICE_MOORESTOWN		1
-#define DEVICE_OAKTRAIL			2
-#define DEVICE_MOORESTOWN_MM		3
-
-static int mrst_device_ident(struct drm_device *dev)
-{
-	/* User forced */
-	if (devtype)
-		return devtype;
-	if (dmi_match(DMI_PRODUCT_NAME, "OakTrail") ||
-		dmi_match(DMI_PRODUCT_NAME, "OakTrail platform"))
-		return DEVICE_OAKTRAIL;
-#if defined(CONFIG_X86_MRST)
-	if (dmi_match(DMI_PRODUCT_NAME, "MM") ||
-		dmi_match(DMI_PRODUCT_NAME, "MM 10"))
-		return DEVICE_MOORESTOWN_MM;
-	if (mrst_identify_cpu())
-		return DEVICE_MOORESTOWN;
-#endif
-	return DEVICE_OAKTRAIL;
-}
-
-
-/* IPC message and command defines used to enable/disable mipi panel voltages */
-#define IPC_MSG_PANEL_ON_OFF    0xE9
-#define IPC_CMD_PANEL_ON        1
-#define IPC_CMD_PANEL_OFF       0
-
-static int mrst_output_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	if (dev_priv->iLVDS_enable)
-		mrst_lvds_init(dev, &dev_priv->mode_dev);
-	else
-		dev_err(dev->dev, "DSI is not supported\n");
-	if (dev_priv->hdmi_priv)
-		mrst_hdmi_init(dev, &dev_priv->mode_dev);
-	return 0;
-}
-
-/*
- *	Provide the low level interfaces for the Moorestown backlight
- */
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-#define MRST_BLC_MAX_PWM_REG_FREQ	    0xFFFF
-#define BLC_PWM_PRECISION_FACTOR 100	/* 10000000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 1000000
-#define BLC_ADJUSTMENT_MAX 100
-
-static struct backlight_device *mrst_backlight_device;
-static int mrst_brightness;
-
-static int mrst_set_brightness(struct backlight_device *bd)
-{
-	struct drm_device *dev = bl_get_data(mrst_backlight_device);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int level = bd->props.brightness;
-	u32 blc_pwm_ctl;
-	u32 max_pwm_blc;
-
-	/* Percentage 1-100% being valid */
-	if (level < 1)
-		level = 1;
-
-	if (gma_power_begin(dev, 0)) {
-		/* Calculate and set the brightness value */
-		max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
-		blc_pwm_ctl = level * max_pwm_blc / 100;
-
-		/* Adjust the backlight level with the percent in
-		 * dev_priv->blc_adj1;
-		 */
-		blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1;
-		blc_pwm_ctl = blc_pwm_ctl / 100;
-
-		/* Adjust the backlight level with the percent in
-		 * dev_priv->blc_adj2;
-		 */
-		blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2;
-		blc_pwm_ctl = blc_pwm_ctl / 100;
-
-		/* force PWM bit on */
-		REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
-		REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
-		gma_power_end(dev);
-	}
-	mrst_brightness = level;
-	return 0;
-}
-
-static int mrst_get_brightness(struct backlight_device *bd)
-{
-	/* return locally cached var instead of HW read (due to DPST etc.) */
-	/* FIXME: ideally return actual value in case firmware fiddled with
-	   it */
-	return mrst_brightness;
-}
-
-static int device_backlight_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long core_clock;
-	u16 bl_max_freq;
-	uint32_t value;
-	uint32_t blc_pwm_precision_factor;
-
-	dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
-	dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
-	bl_max_freq = 256;
-	/* this needs to be set elsewhere */
-	blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR;
-
-	core_clock = dev_priv->core_freq;
-
-	value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
-	value *= blc_pwm_precision_factor;
-	value /= bl_max_freq;
-	value /= blc_pwm_precision_factor;
-
-	if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
-			return -ERANGE;
-
-	if (gma_power_begin(dev, false)) {
-		REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
-		REG_WRITE(BLC_PWM_CTL, value | (value << 16));
-		gma_power_end(dev);
-	}
-	return 0;
-}
-
-static const struct backlight_ops mrst_ops = {
-	.get_brightness = mrst_get_brightness,
-	.update_status  = mrst_set_brightness,
-};
-
-int mrst_backlight_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int ret;
-	struct backlight_properties props;
-
-	memset(&props, 0, sizeof(struct backlight_properties));
-	props.max_brightness = 100;
-	props.type = BACKLIGHT_PLATFORM;
-
-	mrst_backlight_device = backlight_device_register("mrst-bl",
-					NULL, (void *)dev, &mrst_ops, &props);
-
-	if (IS_ERR(mrst_backlight_device))
-		return PTR_ERR(mrst_backlight_device);
-
-	ret = device_backlight_init(dev);
-	if (ret < 0) {
-		backlight_device_unregister(mrst_backlight_device);
-		return ret;
-	}
-	mrst_backlight_device->props.brightness = 100;
-	mrst_backlight_device->props.max_brightness = 100;
-	backlight_update_status(mrst_backlight_device);
-	dev_priv->backlight_device = mrst_backlight_device;
-	return 0;
-}
-
-#endif
-
-/*
- *	Provide the Moorestown specific chip logic and low level methods
- *	for power management
- */
-
-static void mrst_init_pm(struct drm_device *dev)
-{
-}
-
-/**
- *	mrst_save_display_registers	-	save registers lost on suspend
- *	@dev: our DRM device
- *
- *	Save the state we need in order to be able to restore the interface
- *	upon resume from suspend
- */
-static int mrst_save_display_registers(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int i;
-	u32 pp_stat;
-
-	/* Display arbitration control + watermarks */
-	dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
-	dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
-	dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
-	dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
-	dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
-	dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
-	dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
-	dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
-
-	/* Pipe & plane A info */
-	dev_priv->savePIPEACONF = PSB_RVDC32(PIPEACONF);
-	dev_priv->savePIPEASRC = PSB_RVDC32(PIPEASRC);
-	dev_priv->saveFPA0 = PSB_RVDC32(MRST_FPA0);
-	dev_priv->saveFPA1 = PSB_RVDC32(MRST_FPA1);
-	dev_priv->saveDPLL_A = PSB_RVDC32(MRST_DPLL_A);
-	dev_priv->saveHTOTAL_A = PSB_RVDC32(HTOTAL_A);
-	dev_priv->saveHBLANK_A = PSB_RVDC32(HBLANK_A);
-	dev_priv->saveHSYNC_A = PSB_RVDC32(HSYNC_A);
-	dev_priv->saveVTOTAL_A = PSB_RVDC32(VTOTAL_A);
-	dev_priv->saveVBLANK_A = PSB_RVDC32(VBLANK_A);
-	dev_priv->saveVSYNC_A = PSB_RVDC32(VSYNC_A);
-	dev_priv->saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A);
-	dev_priv->saveDSPACNTR = PSB_RVDC32(DSPACNTR);
-	dev_priv->saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE);
-	dev_priv->saveDSPAADDR = PSB_RVDC32(DSPABASE);
-	dev_priv->saveDSPASURF = PSB_RVDC32(DSPASURF);
-	dev_priv->saveDSPALINOFF = PSB_RVDC32(DSPALINOFF);
-	dev_priv->saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF);
-
-	/* Save cursor regs */
-	dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
-	dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
-	dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
-
-	/* Save palette (gamma) */
-	for (i = 0; i < 256; i++)
-		dev_priv->save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i << 2));
-
-	if (dev_priv->hdmi_priv)
-		mrst_hdmi_save(dev);
-
-	/* Save performance state */
-	dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE);
-
-	/* LVDS state */
-	dev_priv->savePP_CONTROL = PSB_RVDC32(PP_CONTROL);
-	dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
-	dev_priv->savePFIT_AUTO_RATIOS = PSB_RVDC32(PFIT_AUTO_RATIOS);
-	dev_priv->saveBLC_PWM_CTL = PSB_RVDC32(BLC_PWM_CTL);
-	dev_priv->saveBLC_PWM_CTL2 = PSB_RVDC32(BLC_PWM_CTL2);
-	dev_priv->saveLVDS = PSB_RVDC32(LVDS);
-	dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
-	dev_priv->savePP_ON_DELAYS = PSB_RVDC32(LVDSPP_ON);
-	dev_priv->savePP_OFF_DELAYS = PSB_RVDC32(LVDSPP_OFF);
-	dev_priv->savePP_DIVISOR = PSB_RVDC32(PP_CYCLE);
-
-	/* HW overlay */
-	dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
-	dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
-	dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
-	dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
-	dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
-	dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
-	dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
-
-	/* DPST registers */
-	dev_priv->saveHISTOGRAM_INT_CONTROL_REG =
-					PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-	dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG =
-					PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
-	dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC);
-
-	if (dev_priv->iLVDS_enable) {
-		/* Shut down the panel */
-		PSB_WVDC32(0, PP_CONTROL);
-
-		do {
-			pp_stat = PSB_RVDC32(PP_STATUS);
-		} while (pp_stat & 0x80000000);
-
-		/* Turn off the plane */
-		PSB_WVDC32(0x58000000, DSPACNTR);
-		/* Trigger the plane disable */
-		PSB_WVDC32(0, DSPASURF);
-
-		/* Wait ~4 ticks */
-		msleep(4);
-
-		/* Turn off pipe */
-		PSB_WVDC32(0x0, PIPEACONF);
-		/* Wait ~8 ticks */
-		msleep(8);
-
-		/* Turn off PLLs */
-		PSB_WVDC32(0, MRST_DPLL_A);
-	}
-	return 0;
-}
-
-/**
- *	mrst_restore_display_registers	-	restore lost register state
- *	@dev: our DRM device
- *
- *	Restore register state that was lost during suspend and resume.
- */
-static int mrst_restore_display_registers(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 pp_stat;
-	int i;
-
-	/* Display arbitration + watermarks */
-	PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
-	PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
-	PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
-	PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
-	PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
-	PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
-	PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
-	PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
-
-	/* Make sure VGA plane is off. it initializes to on after reset!*/
-	PSB_WVDC32(0x80000000, VGACNTRL);
-
-	/* set the plls */
-	PSB_WVDC32(dev_priv->saveFPA0, MRST_FPA0);
-	PSB_WVDC32(dev_priv->saveFPA1, MRST_FPA1);
-
-	/* Actually enable it */
-	PSB_WVDC32(dev_priv->saveDPLL_A, MRST_DPLL_A);
-	DRM_UDELAY(150);
-
-	/* Restore mode */
-	PSB_WVDC32(dev_priv->saveHTOTAL_A, HTOTAL_A);
-	PSB_WVDC32(dev_priv->saveHBLANK_A, HBLANK_A);
-	PSB_WVDC32(dev_priv->saveHSYNC_A, HSYNC_A);
-	PSB_WVDC32(dev_priv->saveVTOTAL_A, VTOTAL_A);
-	PSB_WVDC32(dev_priv->saveVBLANK_A, VBLANK_A);
-	PSB_WVDC32(dev_priv->saveVSYNC_A, VSYNC_A);
-	PSB_WVDC32(dev_priv->savePIPEASRC, PIPEASRC);
-	PSB_WVDC32(dev_priv->saveBCLRPAT_A, BCLRPAT_A);
-
-	/* Restore performance mode*/
-	PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE);
-
-	/* Enable the pipe*/
-	if (dev_priv->iLVDS_enable)
-		PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF);
-
-	/* Set up the plane*/
-	PSB_WVDC32(dev_priv->saveDSPALINOFF, DSPALINOFF);
-	PSB_WVDC32(dev_priv->saveDSPASTRIDE, DSPASTRIDE);
-	PSB_WVDC32(dev_priv->saveDSPATILEOFF, DSPATILEOFF);
-
-	/* Enable the plane */
-	PSB_WVDC32(dev_priv->saveDSPACNTR, DSPACNTR);
-	PSB_WVDC32(dev_priv->saveDSPASURF, DSPASURF);
-
-	/* Enable Cursor A */
-	PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
-	PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
-	PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
-
-	/* Restore palette (gamma) */
-	for (i = 0; i < 256; i++)
-		PSB_WVDC32(dev_priv->save_palette_a[i], PALETTE_A + (i << 2));
-
-	if (dev_priv->hdmi_priv)
-		mrst_hdmi_restore(dev);
-
-	if (dev_priv->iLVDS_enable) {
-		PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2);
-		PSB_WVDC32(dev_priv->saveLVDS, LVDS); /*port 61180h*/
-		PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
-		PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
-		PSB_WVDC32(dev_priv->savePFIT_AUTO_RATIOS, PFIT_AUTO_RATIOS);
-		PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL);
-		PSB_WVDC32(dev_priv->savePP_ON_DELAYS, LVDSPP_ON);
-		PSB_WVDC32(dev_priv->savePP_OFF_DELAYS, LVDSPP_OFF);
-		PSB_WVDC32(dev_priv->savePP_DIVISOR, PP_CYCLE);
-		PSB_WVDC32(dev_priv->savePP_CONTROL, PP_CONTROL);
-	}
-
-	/* Wait for cycle delay */
-	do {
-		pp_stat = PSB_RVDC32(PP_STATUS);
-	} while (pp_stat & 0x08000000);
-
-	/* Wait for panel power up */
-	do {
-		pp_stat = PSB_RVDC32(PP_STATUS);
-	} while (pp_stat & 0x10000000);
-
-	/* Restore HW overlay */
-	PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
-	PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
-
-	/* DPST registers */
-	PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG,
-						HISTOGRAM_INT_CONTROL);
-	PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG,
-						HISTOGRAM_LOGIC_CONTROL);
-	PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC);
-
-	return 0;
-}
-
-/**
- *	mrst_power_down	-	power down the display island
- *	@dev: our DRM device
- *
- *	Power down the display interface of our device
- */
-static int mrst_power_down(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 pwr_mask ;
-	u32 pwr_sts;
-
-	pwr_mask = PSB_PWRGT_DISPLAY_MASK;
-	outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC);
-
-	while (true) {
-		pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
-		if ((pwr_sts & pwr_mask) == pwr_mask)
-			break;
-		else
-			udelay(10);
-	}
-	return 0;
-}
-
-/*
- * mrst_power_up
- *
- * Restore power to the specified island(s) (powergating)
- */
-static int mrst_power_up(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
-	u32 pwr_sts, pwr_cnt;
-
-	pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
-	pwr_cnt &= ~pwr_mask;
-	outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
-
-	while (true) {
-		pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
-		if ((pwr_sts & pwr_mask) == 0)
-			break;
-		else
-			udelay(10);
-	}
-	return 0;
-}
-
-#if defined(CONFIG_X86_MRST)
-static void mrst_lvds_cache_bl(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	intel_scu_ipc_ioread8(0x28, &(dev_priv->saveBKLTCNT));
-	intel_scu_ipc_ioread8(0x29, &(dev_priv->saveBKLTREQ));
-	intel_scu_ipc_ioread8(0x2A, &(dev_priv->saveBKLTBRTL));
-}
-
-static void mrst_mm_bl_power(struct drm_device *dev, bool on)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (on) {
-		intel_scu_ipc_iowrite8(0x2A, dev_priv->saveBKLTBRTL);
-		intel_scu_ipc_iowrite8(0x28, dev_priv->saveBKLTCNT);
-		intel_scu_ipc_iowrite8(0x29, dev_priv->saveBKLTREQ);
-	} else {
-		intel_scu_ipc_iowrite8(0x2A, 0);
-		intel_scu_ipc_iowrite8(0x28, 0);
-		intel_scu_ipc_iowrite8(0x29, 0);
-	}
-}
-
-static const struct psb_ops mrst_mm_chip_ops = {
-	.name = "Moorestown MM ",
-	.accel_2d = 1,
-	.pipes = 1,
-	.crtcs = 1,
-	.sgx_offset = MRST_SGX_OFFSET,
-
-	.crtc_helper = &mrst_helper_funcs,
-	.crtc_funcs = &psb_intel_crtc_funcs,
-
-	.output_init = mrst_output_init,
-
-	.lvds_bl_power = mrst_mm_bl_power,
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	.backlight_init = mrst_backlight_init,
-#endif
-
-	.init_pm = mrst_init_pm,
-	.save_regs = mrst_save_display_registers,
-	.restore_regs = mrst_restore_display_registers,
-	.power_down = mrst_power_down,
-	.power_up = mrst_power_up,
-
-	.i2c_bus = 0,
-};
-
-#endif
-
-static void oaktrail_teardown(struct drm_device *dev)
-{
-	mrst_hdmi_teardown(dev);
-}
-
-static const struct psb_ops oaktrail_chip_ops = {
-	.name = "Oaktrail",
-	.accel_2d = 1,
-	.pipes = 2,
-	.crtcs = 2,
-	.sgx_offset = MRST_SGX_OFFSET,
-
-	.chip_setup = mid_chip_setup,
-	.chip_teardown = oaktrail_teardown,
-	.crtc_helper = &mrst_helper_funcs,
-	.crtc_funcs = &psb_intel_crtc_funcs,
-
-	.output_init = mrst_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	.backlight_init = mrst_backlight_init,
-#endif
-
-	.init_pm = mrst_init_pm,
-	.save_regs = mrst_save_display_registers,
-	.restore_regs = mrst_restore_display_registers,
-	.power_down = mrst_power_down,
-	.power_up = mrst_power_up,
-
-	.i2c_bus = 1,
-};
-
-/**
- *	mrst_chip_setup		-	perform the initial chip init
- *	@dev: Our drm_device
- *
- *	Figure out which incarnation we are and then scan the firmware for
- *	tables and information.
- */
-static int mrst_chip_setup(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	switch (mrst_device_ident(dev)) {
-	case DEVICE_OAKTRAIL:
-		/* Dual CRTC, PC compatible, HDMI, I2C #2 */
-		dev_priv->ops = &oaktrail_chip_ops;
-		mrst_hdmi_setup(dev);
-		return mid_chip_setup(dev);
-#if defined(CONFIG_X86_MRST)
-	case DEVICE_MOORESTOWN_MM:
-		/* Single CRTC, No HDMI, I2C #0, BL control */
-		mrst_lvds_cache_bl(dev);
-		dev_priv->ops = &mrst_mm_chip_ops;
-		return mid_chip_setup(dev);
-	case DEVICE_MOORESTOWN:
-		/* Dual CRTC, No HDMI(?), I2C #1 */
-		return mid_chip_setup(dev);
-#endif
-	default:
-		dev_err(dev->dev, "unsupported device type.\n");
-		return -ENODEV;
-	}
-}
-
-const struct psb_ops mrst_chip_ops = {
-	.name = "Moorestown",
-	.accel_2d = 1,
-	.pipes = 2,
-	.crtcs = 2,
-	.sgx_offset = MRST_SGX_OFFSET,
-
-	.chip_setup = mrst_chip_setup,
-	.crtc_helper = &mrst_helper_funcs,
-	.crtc_funcs = &psb_intel_crtc_funcs,
-
-	.output_init = mrst_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	.backlight_init = mrst_backlight_init,
-#endif
-
-	.init_pm = mrst_init_pm,
-	.save_regs = mrst_save_display_registers,
-	.restore_regs = mrst_restore_display_registers,
-	.power_down = mrst_power_down,
-	.power_up = mrst_power_up,
-
-	.i2c_bus = 2,
-};
-
diff --git a/drivers/staging/gma500/mrst_hdmi.c b/drivers/staging/gma500/mrst_hdmi.c
deleted file mode 100644
index e66607e..0000000
--- a/drivers/staging/gma500/mrst_hdmi.c
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *	Li Peng <peng.li@intel.com>
- */
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_drv.h"
-
-#define HDMI_READ(reg)		readl(hdmi_dev->regs + (reg))
-#define HDMI_WRITE(reg, val)	writel(val, hdmi_dev->regs + (reg))
-
-#define HDMI_HCR	0x1000
-#define HCR_ENABLE_HDCP		(1 << 5)
-#define HCR_ENABLE_AUDIO	(1 << 2)
-#define HCR_ENABLE_PIXEL	(1 << 1)
-#define HCR_ENABLE_TMDS		(1 << 0)
-
-#define HDMI_HICR	0x1004
-#define HDMI_HSR	0x1008
-#define HDMI_HISR	0x100C
-#define HDMI_DETECT_HDP		(1 << 0)
-
-#define HDMI_VIDEO_REG	0x3000
-#define HDMI_UNIT_EN		(1 << 7)
-#define HDMI_MODE_OUTPUT	(1 << 0)
-#define HDMI_HBLANK_A	0x3100
-
-#define HDMI_AUDIO_CTRL	0x4000
-#define HDMI_ENABLE_AUDIO	(1 << 0)
-
-#define PCH_HTOTAL_B	0x3100
-#define PCH_HBLANK_B	0x3104
-#define PCH_HSYNC_B	0x3108
-#define PCH_VTOTAL_B	0x310C
-#define PCH_VBLANK_B	0x3110
-#define PCH_VSYNC_B	0x3114
-#define PCH_PIPEBSRC	0x311C
-
-#define PCH_PIPEB_DSL	0x3800
-#define PCH_PIPEB_SLC	0x3804
-#define PCH_PIPEBCONF	0x3808
-#define PCH_PIPEBSTAT	0x3824
-
-#define CDVO_DFT	0x5000
-#define CDVO_SLEWRATE	0x5004
-#define CDVO_STRENGTH	0x5008
-#define CDVO_RCOMP	0x500C
-
-#define DPLL_CTRL       0x6000
-#define DPLL_PDIV_SHIFT		16
-#define DPLL_PDIV_MASK		(0xf << 16)
-#define DPLL_PWRDN		(1 << 4)
-#define DPLL_RESET		(1 << 3)
-#define DPLL_FASTEN		(1 << 2)
-#define DPLL_ENSTAT		(1 << 1)
-#define DPLL_DITHEN		(1 << 0)
-
-#define DPLL_DIV_CTRL   0x6004
-#define DPLL_CLKF_MASK		0xffffffc0
-#define DPLL_CLKR_MASK		(0x3f)
-
-#define DPLL_CLK_ENABLE 0x6008
-#define DPLL_EN_DISP		(1 << 31)
-#define DPLL_SEL_HDMI		(1 << 8)
-#define DPLL_EN_HDMI		(1 << 1)
-#define DPLL_EN_VGA		(1 << 0)
-
-#define DPLL_ADJUST     0x600C
-#define DPLL_STATUS     0x6010
-#define DPLL_UPDATE     0x6014
-#define DPLL_DFT        0x6020
-
-struct intel_range {
-	int	min, max;
-};
-
-struct mrst_hdmi_limit {
-	struct intel_range vco, np, nr, nf;
-};
-
-struct mrst_hdmi_clock {
-	int np;
-	int nr;
-	int nf;
-	int dot;
-};
-
-#define VCO_MIN		320000
-#define VCO_MAX		1650000
-#define	NP_MIN		1
-#define	NP_MAX		15
-#define	NR_MIN		1
-#define	NR_MAX		64
-#define NF_MIN		2
-#define NF_MAX		4095
-
-static const struct mrst_hdmi_limit mrst_hdmi_limit = {
-	.vco = { .min = VCO_MIN,		.max = VCO_MAX },
-	.np  = { .min = NP_MIN,			.max = NP_MAX  },
-	.nr  = { .min = NR_MIN,			.max = NR_MAX  },
-	.nf  = { .min = NF_MIN,			.max = NF_MAX  },
-};
-
-static void wait_for_vblank(struct drm_device *dev)
-{
-	/* FIXME: Can we do this as a sleep ? */
-	/* Wait for 20ms, i.e. one cycle at 50hz. */
-	mdelay(20);
-}
-
-static void scu_busy_loop(void *scu_base)
-{
-	u32 status = 0;
-	u32 loop_count = 0;
-
-	status = readl(scu_base + 0x04);
-	while (status & 1) {
-		udelay(1); /* scu processing time is in few u secods */
-		status = readl(scu_base + 0x04);
-		loop_count++;
-		/* break if scu doesn't reset busy bit after huge retry */
-		if (loop_count > 1000) {
-			DRM_DEBUG_KMS("SCU IPC timed out");
-			return;
-		}
-	}
-}
-
-static void mrst_hdmi_reset(struct drm_device *dev)
-{
-	void *base;
-	/* FIXME: at least make these defines */
-	unsigned int scu_ipc_mmio = 0xff11c000;
-	int scu_len = 1024;
-
-	base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
-	if (base == NULL) {
-		DRM_ERROR("failed to map SCU mmio\n");
-		return;
-	}
-
-	/* scu ipc: assert hdmi controller reset */
-	writel(0xff11d118, base + 0x0c);
-	writel(0x7fffffdf, base + 0x80);
-	writel(0x42005, base + 0x0);
-	scu_busy_loop(base);
-
-	/* scu ipc: de-assert hdmi controller reset */
-	writel(0xff11d118, base + 0x0c);
-	writel(0x7fffffff, base + 0x80);
-	writel(0x42005, base + 0x0);
-	scu_busy_loop(base);
-
-	iounmap(base);
-}
-
-static void mrst_hdmi_audio_enable(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-
-	HDMI_WRITE(HDMI_HCR, 0x67);
-	HDMI_READ(HDMI_HCR);
-
-	HDMI_WRITE(0x51a8, 0x10);
-	HDMI_READ(0x51a8);
-
-	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
-	HDMI_READ(HDMI_AUDIO_CTRL);
-}
-
-static void mrst_hdmi_audio_disable(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-
-	HDMI_WRITE(0x51a8, 0x0);
-	HDMI_READ(0x51a8);
-
-	HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
-	HDMI_READ(HDMI_AUDIO_CTRL);
-
-	HDMI_WRITE(HDMI_HCR, 0x47);
-	HDMI_READ(HDMI_HCR);
-}
-
-void mrst_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
-{
-	struct drm_device *dev = crtc->dev;
-	u32 temp;
-
-	switch (mode) {
-	case DRM_MODE_DPMS_OFF:
-		/* Disable VGACNTRL */
-		REG_WRITE(VGACNTRL, 0x80000000);
-
-		/* Disable plane */
-		temp = REG_READ(DSPBCNTR);
-		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-			REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
-			REG_READ(DSPBCNTR);
-			/* Flush the plane changes */
-			REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
-			REG_READ(DSPBSURF);
-		}
-
-		/* Disable pipe B */
-		temp = REG_READ(PIPEBCONF);
-		if ((temp & PIPEACONF_ENABLE) != 0) {
-			REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
-			REG_READ(PIPEBCONF);
-		}
-
-		/* Disable LNW Pipes, etc */
-		temp = REG_READ(PCH_PIPEBCONF);
-		if ((temp & PIPEACONF_ENABLE) != 0) {
-			REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
-			REG_READ(PCH_PIPEBCONF);
-		}
-		/* wait for pipe off */
-		udelay(150);
-		/* Disable dpll */
-		temp = REG_READ(DPLL_CTRL);
-		if ((temp & DPLL_PWRDN) == 0) {
-			REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
-			REG_WRITE(DPLL_STATUS, 0x1);
-		}
-		/* wait for dpll off */
-		udelay(150);
-		break;
-	case DRM_MODE_DPMS_ON:
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-		/* Enable dpll */
-		temp = REG_READ(DPLL_CTRL);
-		if ((temp & DPLL_PWRDN) != 0) {
-			REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
-			temp = REG_READ(DPLL_CLK_ENABLE);
-			REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
-			REG_READ(DPLL_CLK_ENABLE);
-		}
-		/* wait for dpll warm up */
-		udelay(150);
-
-		/* Enable pipe B */
-		temp = REG_READ(PIPEBCONF);
-		if ((temp & PIPEACONF_ENABLE) == 0) {
-			REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
-			REG_READ(PIPEBCONF);
-		}
-
-		/* Enable LNW Pipe B */
-		temp = REG_READ(PCH_PIPEBCONF);
-		if ((temp & PIPEACONF_ENABLE) == 0) {
-			REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
-			REG_READ(PCH_PIPEBCONF);
-		}
-		wait_for_vblank(dev);
-
-		/* Enable plane */
-		temp = REG_READ(DSPBCNTR);
-		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-			REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
-			REG_READ(DSPBSURF);
-		}
-		psb_intel_crtc_load_lut(crtc);
-	}
-	/* DSPARB */
-	REG_WRITE(DSPARB, 0x00003fbf);
-	/* FW1 */
-	REG_WRITE(0x70034, 0x3f880a0a);
-	/* FW2 */
-	REG_WRITE(0x70038, 0x0b060808);
-	/* FW4 */
-	REG_WRITE(0x70050, 0x08030404);
-	/* FW5 */
-	REG_WRITE(0x70054, 0x04040404);
-	/* LNC Chicken Bits */
-	REG_WRITE(0x70400, 0x4000);
-}
-
-
-static void mrst_hdmi_dpms(struct drm_encoder *encoder, int mode)
-{
-	static int dpms_mode = -1;
-
-	struct drm_device *dev = encoder->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-	u32 temp;
-
-	if (dpms_mode == mode)
-		return;
-
-	if (mode != DRM_MODE_DPMS_ON)
-		temp = 0x0;
-	else
-		temp = 0x99;
-
-	dpms_mode = mode;
-	HDMI_WRITE(HDMI_VIDEO_REG, temp);
-}
-
-static unsigned int htotal_calculate(struct drm_display_mode *mode)
-{
-	u32 htotal, new_crtc_htotal;
-
-	htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16);
-
-	/*
-	 * 1024 x 768  new_crtc_htotal = 0x1024;
-	 * 1280 x 1024 new_crtc_htotal = 0x0c34;
-	 */
-	new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
-
-	return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
-}
-
-static void mrst_hdmi_find_dpll(struct drm_crtc *crtc, int target,
-				int refclk, struct mrst_hdmi_clock *best_clock)
-{
-	int np_min, np_max, nr_min, nr_max;
-	int np, nr, nf;
-
-	np_min = DIV_ROUND_UP(mrst_hdmi_limit.vco.min, target * 10);
-	np_max = mrst_hdmi_limit.vco.max / (target * 10);
-	if (np_min < mrst_hdmi_limit.np.min)
-		np_min = mrst_hdmi_limit.np.min;
-	if (np_max > mrst_hdmi_limit.np.max)
-		np_max = mrst_hdmi_limit.np.max;
-
-	nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
-	nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
-	if (nr_min < mrst_hdmi_limit.nr.min)
-		nr_min = mrst_hdmi_limit.nr.min;
-	if (nr_max > mrst_hdmi_limit.nr.max)
-		nr_max = mrst_hdmi_limit.nr.max;
-
-	np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
-	nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
-	nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
-	DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
-
-	/*
-	 * 1024 x 768  np = 1; nr = 0x26; nf = 0x0fd8000;
-	 * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
-	 */
-	best_clock->np = np;
-	best_clock->nr = nr - 1;
-	best_clock->nf = (nf << 14);
-}
-
-int mrst_crtc_hdmi_mode_set(struct drm_crtc *crtc,
-			    struct drm_display_mode *mode,
-			    struct drm_display_mode *adjusted_mode,
-			    int x, int y,
-			    struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-	int pipe = 1;
-	int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
-	int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
-	int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
-	int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
-	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
-	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-	int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
-	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
-	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-	int refclk;
-	struct mrst_hdmi_clock clock;
-	u32 dspcntr, pipeconf, dpll, temp;
-	int dspcntr_reg = DSPBCNTR;
-
-	/* Disable the VGA plane that we never use */
-	REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-	/* XXX: Disable the panel fitter if it was on our pipe */
-
-	/* Disable dpll if necessary */
-	dpll = REG_READ(DPLL_CTRL);
-	if ((dpll & DPLL_PWRDN) == 0) {
-		REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
-		REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
-		REG_WRITE(DPLL_STATUS, 0x1);
-	}
-	udelay(150);
-
-	/* reset controller: FIXME - can we sort out the ioremap mess ? */
-	iounmap(hdmi_dev->regs);
-	mrst_hdmi_reset(dev);
-
-	/* program and enable dpll */
-	refclk = 25000;
-	mrst_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
-
-	/* Setting DPLL */
-	dpll = REG_READ(DPLL_CTRL);
-	dpll &= ~DPLL_PDIV_MASK;
-	dpll &= ~(DPLL_PWRDN | DPLL_RESET);
-	REG_WRITE(DPLL_CTRL, 0x00000008);
-	REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
-	REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
-	REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
-	REG_WRITE(DPLL_UPDATE, 0x80000000);
-	REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
-	udelay(150);
-
-	hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
-	if (hdmi_dev->regs == NULL) {
-		DRM_ERROR("failed to do hdmi mmio mapping\n");
-		return -ENOMEM;
-	}
-
-	/* configure HDMI */
-	HDMI_WRITE(0x1004, 0x1fd);
-	HDMI_WRITE(0x2000, 0x1);
-	HDMI_WRITE(0x2008, 0x0);
-	HDMI_WRITE(0x3130, 0x8);
-	HDMI_WRITE(0x101c, 0x1800810);
-
-	temp = htotal_calculate(adjusted_mode);
-	REG_WRITE(htot_reg, temp);
-	REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
-	REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
-	REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
-	REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
-	REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
-	REG_WRITE(pipesrc_reg,
-		((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
-
-	REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
-	REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
-	REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
-	REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
-	REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
-	REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
-	REG_WRITE(PCH_PIPEBSRC,
-		((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
-
-	temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
-	HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) |  temp);
-
-	REG_WRITE(dspsize_reg,
-			((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
-	REG_WRITE(dsppos_reg, 0);
-
-	/* Flush the plane changes */
-	{
-		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-	}
-
-	/* Set up the display plane register */
-	dspcntr = REG_READ(dspcntr_reg);
-	dspcntr |= DISPPLANE_GAMMA_ENABLE;
-	dspcntr |= DISPPLANE_SEL_PIPE_B;
-	dspcntr |= DISPLAY_PLANE_ENABLE;
-
-	/* setup pipeconf */
-	pipeconf = REG_READ(pipeconf_reg);
-	pipeconf |= PIPEACONF_ENABLE;
-
-	REG_WRITE(pipeconf_reg, pipeconf);
-	REG_READ(pipeconf_reg);
-
-	REG_WRITE(PCH_PIPEBCONF, pipeconf);
-	REG_READ(PCH_PIPEBCONF);
-	wait_for_vblank(dev);
-
-	REG_WRITE(dspcntr_reg, dspcntr);
-	wait_for_vblank(dev);
-
-	return 0;
-}
-
-static int mrst_hdmi_mode_valid(struct drm_connector *connector,
-				struct drm_display_mode *mode)
-{
-	if (mode->clock > 165000)
-		return MODE_CLOCK_HIGH;
-	if (mode->clock < 20000)
-		return MODE_CLOCK_LOW;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-		return MODE_NO_DBLESCAN;
-
-	return MODE_OK;
-}
-
-static bool mrst_hdmi_mode_fixup(struct drm_encoder *encoder,
-				 struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-static enum drm_connector_status
-mrst_hdmi_detect(struct drm_connector *connector, bool force)
-{
-	enum drm_connector_status status;
-	struct drm_device *dev = connector->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-	u32 temp;
-
-	temp = HDMI_READ(HDMI_HSR);
-	DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
-
-	if ((temp & HDMI_DETECT_HDP) != 0)
-		status = connector_status_connected;
-	else
-		status = connector_status_disconnected;
-
-	return status;
-}
-
-static const unsigned char raw_edid[] = {
-	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
-	0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
-	0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
-	0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
-	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
-	0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
-	0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
-	0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
-	0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
-	0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
-};
-
-static int mrst_hdmi_get_modes(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct i2c_adapter *i2c_adap;
-	struct edid *edid;
-	struct drm_display_mode *mode, *t;
-	int i = 0, ret = 0;
-
-	i2c_adap = i2c_get_adapter(3);
-	if (i2c_adap == NULL) {
-		DRM_ERROR("No ddc adapter available!\n");
-		edid = (struct edid *)raw_edid;
-	} else {
-		edid = (struct edid *)raw_edid;
-		/* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
-	}
-
-	if (edid) {
-		drm_mode_connector_update_edid_property(connector, edid);
-		ret = drm_add_edid_modes(connector, edid);
-		connector->display_info.raw_edid = NULL;
-	}
-
-	/*
-	 * prune modes that require frame buffer bigger than stolen mem
-	 */
-	list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
-		if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) {
-			i++;
-			drm_mode_remove(connector, mode);
-		}
-	}
-	return ret - i;
-}
-
-static void mrst_hdmi_mode_set(struct drm_encoder *encoder,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-
-	mrst_hdmi_audio_enable(dev);
-	return;
-}
-
-static void mrst_hdmi_destroy(struct drm_connector *connector)
-{
-	return;
-}
-
-static const struct drm_encoder_helper_funcs mrst_hdmi_helper_funcs = {
-	.dpms = mrst_hdmi_dpms,
-	.mode_fixup = mrst_hdmi_mode_fixup,
-	.prepare = psb_intel_encoder_prepare,
-	.mode_set = mrst_hdmi_mode_set,
-	.commit = psb_intel_encoder_commit,
-};
-
-static const struct drm_connector_helper_funcs
-					mrst_hdmi_connector_helper_funcs = {
-	.get_modes = mrst_hdmi_get_modes,
-	.mode_valid = mrst_hdmi_mode_valid,
-	.best_encoder = psb_intel_best_encoder,
-};
-
-static const struct drm_connector_funcs mrst_hdmi_connector_funcs = {
-	.dpms = drm_helper_connector_dpms,
-	.detect = mrst_hdmi_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = mrst_hdmi_destroy,
-};
-
-static void mrst_hdmi_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs mrst_hdmi_enc_funcs = {
-	.destroy = mrst_hdmi_enc_destroy,
-};
-
-void mrst_hdmi_init(struct drm_device *dev,
-					struct psb_intel_mode_device *mode_dev)
-{
-	struct psb_intel_output *psb_intel_output;
-	struct drm_connector *connector;
-	struct drm_encoder *encoder;
-
-	psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
-	if (!psb_intel_output)
-		return;
-
-	psb_intel_output->mode_dev = mode_dev;
-	connector = &psb_intel_output->base;
-	encoder = &psb_intel_output->enc;
-	drm_connector_init(dev, &psb_intel_output->base,
-			   &mrst_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_DVID);
-
-	drm_encoder_init(dev, &psb_intel_output->enc,
-			 &mrst_hdmi_enc_funcs,
-			 DRM_MODE_ENCODER_TMDS);
-
-	drm_mode_connector_attach_encoder(&psb_intel_output->base,
-					  &psb_intel_output->enc);
-
-	psb_intel_output->type = INTEL_OUTPUT_HDMI;
-	drm_encoder_helper_add(encoder, &mrst_hdmi_helper_funcs);
-	drm_connector_helper_add(connector, &mrst_hdmi_connector_helper_funcs);
-
-	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-	connector->interlace_allowed = false;
-	connector->doublescan_allowed = false;
-	drm_sysfs_connector_add(connector);
-
-	return;
-}
-
-static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
-	{}
-};
-
-void mrst_hdmi_setup(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct pci_dev *pdev;
-	struct mrst_hdmi_dev *hdmi_dev;
-	int ret;
-
-	pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
-	if (!pdev)
-		return;
-
-	hdmi_dev = kzalloc(sizeof(struct mrst_hdmi_dev), GFP_KERNEL);
-	if (!hdmi_dev) {
-		dev_err(dev->dev, "failed to allocate memory\n");
-		goto out;
-	}
-
-
-	ret = pci_enable_device(pdev);
-	if (ret) {
-		dev_err(dev->dev, "failed to enable hdmi controller\n");
-		goto free;
-	}
-
-	hdmi_dev->mmio = pci_resource_start(pdev, 0);
-	hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
-	hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
-	if (!hdmi_dev->regs) {
-		dev_err(dev->dev, "failed to map hdmi mmio\n");
-		goto free;
-	}
-
-	hdmi_dev->dev = pdev;
-	pci_set_drvdata(pdev, hdmi_dev);
-
-	/* Initialize i2c controller */
-	ret = mrst_hdmi_i2c_init(hdmi_dev->dev);
-	if (ret)
-		dev_err(dev->dev, "HDMI I2C initialization failed\n");
-
-	dev_priv->hdmi_priv = hdmi_dev;
-	mrst_hdmi_audio_disable(dev);
-	return;
-
-free:
-	kfree(hdmi_dev);
-out:
-	return;
-}
-
-void mrst_hdmi_teardown(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-	struct pci_dev *pdev;
-
-	if (hdmi_dev) {
-		pdev = hdmi_dev->dev;
-		pci_set_drvdata(pdev, NULL);
-		mrst_hdmi_i2c_exit(pdev);
-		iounmap(hdmi_dev->regs);
-		kfree(hdmi_dev);
-		pci_dev_put(pdev);
-	}
-}
-
-/* save HDMI register state */
-void mrst_hdmi_save(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-	int i;
-
-	/* dpll */
-	hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
-	hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
-	hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
-	hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
-	hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
-
-	/* pipe B */
-	dev_priv->savePIPEBCONF = PSB_RVDC32(PIPEBCONF);
-	dev_priv->savePIPEBSRC  = PSB_RVDC32(PIPEBSRC);
-	dev_priv->saveHTOTAL_B  = PSB_RVDC32(HTOTAL_B);
-	dev_priv->saveHBLANK_B  = PSB_RVDC32(HBLANK_B);
-	dev_priv->saveHSYNC_B   = PSB_RVDC32(HSYNC_B);
-	dev_priv->saveVTOTAL_B  = PSB_RVDC32(VTOTAL_B);
-	dev_priv->saveVBLANK_B  = PSB_RVDC32(VBLANK_B);
-	dev_priv->saveVSYNC_B   = PSB_RVDC32(VSYNC_B);
-
-	hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
-	hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
-	hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
-	hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
-	hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
-	hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
-	hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
-	hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
-
-	/* plane */
-	dev_priv->saveDSPBCNTR = PSB_RVDC32(DSPBCNTR);
-	dev_priv->saveDSPBSTRIDE = PSB_RVDC32(DSPBSTRIDE);
-	dev_priv->saveDSPBADDR = PSB_RVDC32(DSPBBASE);
-	dev_priv->saveDSPBSURF = PSB_RVDC32(DSPBSURF);
-	dev_priv->saveDSPBLINOFF = PSB_RVDC32(DSPBLINOFF);
-	dev_priv->saveDSPBTILEOFF = PSB_RVDC32(DSPBTILEOFF);
-
-	/* cursor B */
-	dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
-	dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
-	dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
-
-	/* save palette */
-	for (i = 0; i < 256; i++)
-		dev_priv->save_palette_b[i] = PSB_RVDC32(PALETTE_B + (i << 2));
-}
-
-/* restore HDMI register state */
-void mrst_hdmi_restore(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
-	int i;
-
-	/* dpll */
-	PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
-	PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
-	PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
-	PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
-	PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
-	DRM_UDELAY(150);
-
-	/* pipe */
-	PSB_WVDC32(dev_priv->savePIPEBSRC, PIPEBSRC);
-	PSB_WVDC32(dev_priv->saveHTOTAL_B, HTOTAL_B);
-	PSB_WVDC32(dev_priv->saveHBLANK_B, HBLANK_B);
-	PSB_WVDC32(dev_priv->saveHSYNC_B,  HSYNC_B);
-	PSB_WVDC32(dev_priv->saveVTOTAL_B, VTOTAL_B);
-	PSB_WVDC32(dev_priv->saveVBLANK_B, VBLANK_B);
-	PSB_WVDC32(dev_priv->saveVSYNC_B,  VSYNC_B);
-
-	PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
-	PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
-	PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
-	PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
-	PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
-	PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
-	PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
-
-	PSB_WVDC32(dev_priv->savePIPEBCONF, PIPEBCONF);
-	PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
-
-	/* plane */
-	PSB_WVDC32(dev_priv->saveDSPBLINOFF, DSPBLINOFF);
-	PSB_WVDC32(dev_priv->saveDSPBSTRIDE, DSPBSTRIDE);
-	PSB_WVDC32(dev_priv->saveDSPBTILEOFF, DSPBTILEOFF);
-	PSB_WVDC32(dev_priv->saveDSPBCNTR, DSPBCNTR);
-	PSB_WVDC32(dev_priv->saveDSPBSURF, DSPBSURF);
-
-	/* cursor B */
-	PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
-	PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
-	PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
-
-	/* restore palette */
-	for (i = 0; i < 256; i++)
-		PSB_WVDC32(dev_priv->save_palette_b[i], PALETTE_B + (i << 2));
-}
diff --git a/drivers/staging/gma500/mrst_hdmi_i2c.c b/drivers/staging/gma500/mrst_hdmi_i2c.c
deleted file mode 100644
index 36e7edc..0000000
--- a/drivers/staging/gma500/mrst_hdmi_i2c.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *	Li Peng <peng.li@intel.com>
- */
-
-#include <linux/mutex.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/export.h>
-#include "psb_drv.h"
-
-#define HDMI_READ(reg)		readl(hdmi_dev->regs + (reg))
-#define HDMI_WRITE(reg, val)	writel(val, hdmi_dev->regs + (reg))
-
-#define HDMI_HCR	0x1000
-#define HCR_DETECT_HDP		(1 << 6)
-#define HCR_ENABLE_HDCP		(1 << 5)
-#define HCR_ENABLE_AUDIO	(1 << 2)
-#define HCR_ENABLE_PIXEL	(1 << 1)
-#define HCR_ENABLE_TMDS		(1 << 0)
-#define HDMI_HICR	0x1004
-#define HDMI_INTR_I2C_ERROR	(1 << 4)
-#define HDMI_INTR_I2C_FULL	(1 << 3)
-#define HDMI_INTR_I2C_DONE	(1 << 2)
-#define HDMI_INTR_HPD		(1 << 0)
-#define HDMI_HSR	0x1008
-#define HDMI_HISR	0x100C
-#define HDMI_HI2CRDB0	0x1200
-#define HDMI_HI2CHCR	0x1240
-#define HI2C_HDCP_WRITE		(0 << 2)
-#define HI2C_HDCP_RI_READ	(1 << 2)
-#define HI2C_HDCP_READ		(2 << 2)
-#define HI2C_EDID_READ		(3 << 2)
-#define HI2C_READ_CONTINUE	(1 << 1)
-#define HI2C_ENABLE_TRANSACTION	(1 << 0)
-
-#define HDMI_ICRH	0x1100
-#define HDMI_HI2CTDR0	0x1244
-#define HDMI_HI2CTDR1	0x1248
-
-#define I2C_STAT_INIT		0
-#define I2C_READ_DONE		1
-#define I2C_TRANSACTION_DONE	2
-
-struct hdmi_i2c_dev {
-	struct i2c_adapter *adap;
-	struct mutex i2c_lock;
-	struct completion complete;
-	int status;
-	struct i2c_msg *msg;
-	int buf_offset;
-};
-
-static void hdmi_i2c_irq_enable(struct mrst_hdmi_dev *hdmi_dev)
-{
-	u32 temp;
-
-	temp = HDMI_READ(HDMI_HICR);
-	temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE);
-	HDMI_WRITE(HDMI_HICR, temp);
-	HDMI_READ(HDMI_HICR);
-}
-
-static void hdmi_i2c_irq_disable(struct mrst_hdmi_dev *hdmi_dev)
-{
-	HDMI_WRITE(HDMI_HICR, 0x0);
-	HDMI_READ(HDMI_HICR);
-}
-
-static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
-{
-	struct mrst_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
-	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-	u32 temp;
-
-	i2c_dev->status = I2C_STAT_INIT;
-	i2c_dev->msg = pmsg;
-	i2c_dev->buf_offset = 0;
-	INIT_COMPLETION(i2c_dev->complete);
-
-	/* Enable I2C transaction */
-	temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION;
-	HDMI_WRITE(HDMI_HI2CHCR, temp);
-	HDMI_READ(HDMI_HI2CHCR);
-
-	while (i2c_dev->status != I2C_TRANSACTION_DONE)
-		wait_for_completion_interruptible_timeout(&i2c_dev->complete,
-								10 * HZ);
-
-	return 0;
-}
-
-static int xfer_write(struct i2c_adapter *adap, struct i2c_msg *pmsg)
-{
-	/*
-	 * XXX: i2c write seems isn't useful for EDID probe, don't do anything
-	 */
-	return 0;
-}
-
-static int mrst_hdmi_i2c_access(struct i2c_adapter *adap,
-				struct i2c_msg *pmsg,
-				int num)
-{
-	struct mrst_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
-	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-	int i, err = 0;
-
-	mutex_lock(&i2c_dev->i2c_lock);
-
-	/* Enable i2c unit */
-	HDMI_WRITE(HDMI_ICRH, 0x00008760);
-
-	/* Enable irq */
-	hdmi_i2c_irq_enable(hdmi_dev);
-	for (i = 0; i < num; i++) {
-		if (pmsg->len && pmsg->buf) {
-			if (pmsg->flags & I2C_M_RD)
-				err = xfer_read(adap, pmsg);
-			else
-				err = xfer_write(adap, pmsg);
-		}
-		pmsg++;         /* next message */
-	}
-
-	/* Disable irq */
-	hdmi_i2c_irq_disable(hdmi_dev);
-
-	mutex_unlock(&i2c_dev->i2c_lock);
-
-	return i;
-}
-
-static u32 mrst_hdmi_i2c_func(struct i2c_adapter *adapter)
-{
-	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
-}
-
-static const struct i2c_algorithm mrst_hdmi_i2c_algorithm = {
-	.master_xfer	= mrst_hdmi_i2c_access,
-	.functionality  = mrst_hdmi_i2c_func,
-};
-
-static struct i2c_adapter mrst_hdmi_i2c_adapter = {
-	.name		= "mrst_hdmi_i2c",
-	.nr		= 3,
-	.owner		= THIS_MODULE,
-	.class		= I2C_CLASS_DDC,
-	.algo		= &mrst_hdmi_i2c_algorithm,
-};
-
-static void hdmi_i2c_read(struct mrst_hdmi_dev *hdmi_dev)
-{
-	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-	struct i2c_msg *msg = i2c_dev->msg;
-	u8 *buf = msg->buf;
-	u32 temp;
-	int i, offset;
-
-	offset = i2c_dev->buf_offset;
-	for (i = 0; i < 0x10; i++) {
-		temp = HDMI_READ(HDMI_HI2CRDB0 + (i * 4));
-		memcpy(buf + (offset + i * 4), &temp, 4);
-	}
-	i2c_dev->buf_offset += (0x10 * 4);
-
-	/* clearing read buffer full intr */
-	temp = HDMI_READ(HDMI_HISR);
-	HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_FULL);
-	HDMI_READ(HDMI_HISR);
-
-	/* continue read transaction */
-	temp = HDMI_READ(HDMI_HI2CHCR);
-	HDMI_WRITE(HDMI_HI2CHCR, temp | HI2C_READ_CONTINUE);
-	HDMI_READ(HDMI_HI2CHCR);
-
-	i2c_dev->status = I2C_READ_DONE;
-	return;
-}
-
-static void hdmi_i2c_transaction_done(struct mrst_hdmi_dev *hdmi_dev)
-{
-	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-	u32 temp;
-
-	/* clear transaction done intr */
-	temp = HDMI_READ(HDMI_HISR);
-	HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_DONE);
-	HDMI_READ(HDMI_HISR);
-
-
-	temp = HDMI_READ(HDMI_HI2CHCR);
-	HDMI_WRITE(HDMI_HI2CHCR, temp & ~HI2C_ENABLE_TRANSACTION);
-	HDMI_READ(HDMI_HI2CHCR);
-
-	i2c_dev->status = I2C_TRANSACTION_DONE;
-	return;
-}
-
-static irqreturn_t mrst_hdmi_i2c_handler(int this_irq, void *dev)
-{
-	struct mrst_hdmi_dev *hdmi_dev = dev;
-	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
-	u32 stat;
-
-	stat = HDMI_READ(HDMI_HISR);
-
-	if (stat & HDMI_INTR_HPD) {
-		HDMI_WRITE(HDMI_HISR, stat | HDMI_INTR_HPD);
-		HDMI_READ(HDMI_HISR);
-	}
-
-	if (stat & HDMI_INTR_I2C_FULL)
-		hdmi_i2c_read(hdmi_dev);
-
-	if (stat & HDMI_INTR_I2C_DONE)
-		hdmi_i2c_transaction_done(hdmi_dev);
-
-	complete(&i2c_dev->complete);
-
-	return IRQ_HANDLED;
-}
-
-/*
- * choose alternate function 2 of GPIO pin 52, 53,
- * which is used by HDMI I2C logic
- */
-static void mrst_hdmi_i2c_gpio_fix(void)
-{
-	void *base;
-	unsigned int gpio_base = 0xff12c000;
-	int gpio_len = 0x1000;
-	u32 temp;
-
-	base = ioremap((resource_size_t)gpio_base, gpio_len);
-	if (base == NULL) {
-		DRM_ERROR("gpio ioremap fail\n");
-		return;
-	}
-
-	temp = readl(base + 0x44);
-	DRM_DEBUG_DRIVER("old gpio val %x\n", temp);
-	writel((temp | 0x00000a00), (base +  0x44));
-	temp = readl(base + 0x44);
-	DRM_DEBUG_DRIVER("new gpio val %x\n", temp);
-
-	iounmap(base);
-}
-
-int mrst_hdmi_i2c_init(struct pci_dev *dev)
-{
-	struct mrst_hdmi_dev *hdmi_dev;
-	struct hdmi_i2c_dev *i2c_dev;
-	int ret;
-
-	hdmi_dev = pci_get_drvdata(dev);
-
-	i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL);
-	if (i2c_dev == NULL) {
-		DRM_ERROR("Can't allocate interface\n");
-		ret = -ENOMEM;
-		goto exit;
-	}
-
-	i2c_dev->adap = &mrst_hdmi_i2c_adapter;
-	i2c_dev->status = I2C_STAT_INIT;
-	init_completion(&i2c_dev->complete);
-	mutex_init(&i2c_dev->i2c_lock);
-	i2c_set_adapdata(&mrst_hdmi_i2c_adapter, hdmi_dev);
-	hdmi_dev->i2c_dev = i2c_dev;
-
-	/* Enable HDMI I2C function on gpio */
-	mrst_hdmi_i2c_gpio_fix();
-
-	/* request irq */
-	ret = request_irq(dev->irq, mrst_hdmi_i2c_handler, IRQF_SHARED,
-			  mrst_hdmi_i2c_adapter.name, hdmi_dev);
-	if (ret) {
-		DRM_ERROR("Failed to request IRQ for I2C controller\n");
-		goto err;
-	}
-
-	/* Adapter registration */
-	ret = i2c_add_numbered_adapter(&mrst_hdmi_i2c_adapter);
-	return ret;
-
-err:
-	kfree(i2c_dev);
-exit:
-	return ret;
-}
-
-void mrst_hdmi_i2c_exit(struct pci_dev *dev)
-{
-	struct mrst_hdmi_dev *hdmi_dev;
-	struct hdmi_i2c_dev *i2c_dev;
-
-	hdmi_dev = pci_get_drvdata(dev);
-	if (i2c_del_adapter(&mrst_hdmi_i2c_adapter))
-		DRM_DEBUG_DRIVER("Failed to delete hdmi-i2c adapter\n");
-
-	i2c_dev = hdmi_dev->i2c_dev;
-	kfree(i2c_dev);
-	free_irq(dev->irq, hdmi_dev);
-}
diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c
deleted file mode 100644
index e7999a2..0000000
--- a/drivers/staging/gma500/mrst_lvds.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright © 2006-2009 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- *	Dave Airlie <airlied@linux.ie>
- *	Jesse Barnes <jesse.barnes@intel.com>
- */
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-#include <asm/mrst.h>
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include <linux/pm_runtime.h>
-
-/* The max/min PWM frequency in BPCR[31:17] - */
-/* The smallest number is 1 (not 0) that can fit in the
- * 15-bit field of the and then*/
-/* shifts to the left by one bit to get the actual 16-bit
- * value that the 15-bits correspond to.*/
-#define MRST_BLC_MAX_PWM_REG_FREQ	    0xFFFF
-#define BRIGHTNESS_MAX_LEVEL 100
-
-/**
- * Sets the power state for the panel.
- */
-static void mrst_lvds_set_power(struct drm_device *dev,
-				struct psb_intel_output *output, bool on)
-{
-	u32 pp_status;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (!gma_power_begin(dev, true))
-		return;
-
-	if (on) {
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
-			  POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
-		dev_priv->is_lvds_on = true;
-		if (dev_priv->ops->lvds_bl_power)
-			dev_priv->ops->lvds_bl_power(dev, true);
-	} else {
-		if (dev_priv->ops->lvds_bl_power)
-			dev_priv->ops->lvds_bl_power(dev, false);
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
-			  ~POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while (pp_status & PP_ON);
-		dev_priv->is_lvds_on = false;
-		pm_request_idle(&dev->pdev->dev);
-	}
-	gma_power_end(dev);
-}
-
-static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-
-	if (mode == DRM_MODE_DPMS_ON)
-		mrst_lvds_set_power(dev, output, true);
-	else
-		mrst_lvds_set_power(dev, output, false);
-
-	/* XXX: We never power down the LVDS pairs. */
-}
-
-static void mrst_lvds_mode_set(struct drm_encoder *encoder,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode)
-{
-	struct psb_intel_mode_device *mode_dev =
-				enc_to_psb_intel_output(encoder)->mode_dev;
-	struct drm_device *dev = encoder->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 lvds_port;
-	uint64_t v = DRM_MODE_SCALE_FULLSCREEN;
-
-	if (!gma_power_begin(dev, true))
-		return;
-
-	/*
-	 * The LVDS pin pair will already have been turned on in the
-	 * psb_intel_crtc_mode_set since it has a large impact on the DPLL
-	 * settings.
-	 */
-	lvds_port = (REG_READ(LVDS) &
-		    (~LVDS_PIPEB_SELECT)) |
-		    LVDS_PORT_EN |
-		    LVDS_BORDER_EN;
-
-	/* If the firmware says dither on Moorestown, or the BIOS does
-	   on Oaktrail then enable dithering */
-	if (mode_dev->panel_wants_dither || dev_priv->lvds_dither)
-		lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
-
-	REG_WRITE(LVDS, lvds_port);
-
-	drm_connector_property_get_value(
-		&enc_to_psb_intel_output(encoder)->base,
-		dev->mode_config.scaling_mode_property,
-		&v);
-
-	if (v == DRM_MODE_SCALE_NO_SCALE)
-		REG_WRITE(PFIT_CONTROL, 0);
-	else if (v == DRM_MODE_SCALE_ASPECT) {
-		if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
-		    (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
-			if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) ==
-			    (mode->hdisplay * adjusted_mode->crtc_vdisplay))
-				REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
-			else if ((adjusted_mode->crtc_hdisplay *
-				mode->vdisplay) > (mode->hdisplay *
-				adjusted_mode->crtc_vdisplay))
-				REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
-					  PFIT_SCALING_MODE_PILLARBOX);
-			else
-				REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
-					  PFIT_SCALING_MODE_LETTERBOX);
-		} else
-			REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
-	} else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/
-		REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
-
-	gma_power_end(dev);
-}
-
-static void mrst_lvds_prepare(struct drm_encoder *encoder)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-	if (!gma_power_begin(dev, true))
-		return;
-
-	mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
-	mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
-					  BACKLIGHT_DUTY_CYCLE_MASK);
-	mrst_lvds_set_power(dev, output, false);
-	gma_power_end(dev);
-}
-
-static u32 mrst_lvds_get_max_backlight(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 ret;
-
-	if (gma_power_begin(dev, false)) {
-		ret = ((REG_READ(BLC_PWM_CTL) &
-			  BACKLIGHT_MODULATION_FREQ_MASK) >>
-			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
-		gma_power_end(dev);
-	} else
-		ret = ((dev_priv->saveBLC_PWM_CTL &
-			  BACKLIGHT_MODULATION_FREQ_MASK) >>
-			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
-	return ret;
-}
-
-static void mrst_lvds_commit(struct drm_encoder *encoder)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-	if (mode_dev->backlight_duty_cycle == 0)
-		mode_dev->backlight_duty_cycle =
-					mrst_lvds_get_max_backlight(dev);
-	mrst_lvds_set_power(dev, output, true);
-}
-
-static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = {
-	.dpms = mrst_lvds_dpms,
-	.mode_fixup = psb_intel_lvds_mode_fixup,
-	.prepare = mrst_lvds_prepare,
-	.mode_set = mrst_lvds_mode_set,
-	.commit = mrst_lvds_commit,
-};
-
-static struct drm_display_mode lvds_configuration_modes[] = {
-	/* hard coded fixed mode for TPO LTPS LPJ040K001A */
-	{ DRM_MODE("800x480",  DRM_MODE_TYPE_DRIVER, 33264, 800, 836,
-		   846, 1056, 0, 480, 489, 491, 525, 0, 0) },
-	/* hard coded fixed mode for LVDS 800x480 */
-	{ DRM_MODE("800x480",  DRM_MODE_TYPE_DRIVER, 30994, 800, 801,
-		   802, 1024, 0, 480, 481, 482, 525, 0, 0) },
-	/* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
-	{ DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072,
-		   1104, 1184, 0, 600, 603, 604, 608, 0, 0) },
-	/* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
-	{ DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104,
-		   1136, 1184, 0, 600, 603, 604, 608, 0, 0) },
-	/* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
-	{ DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124,
-		   1204, 1312, 0, 600, 607, 610, 621, 0, 0) },
-	/* hard coded fixed mode for LVDS 1024x768 */
-	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
-		   1184, 1344, 0, 768, 771, 777, 806, 0, 0) },
-	/* hard coded fixed mode for LVDS 1366x768 */
-	{ DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430,
-		   1558, 1664, 0, 768, 769, 770, 776, 0, 0) },
-};
-
-/* Returns the panel fixed mode from configuration. */
-
-static struct drm_display_mode *
-mrst_lvds_get_configuration_mode(struct drm_device *dev)
-{
-	struct drm_display_mode *mode = NULL;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
-
-	if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/
-		mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-		if (!mode)
-			return NULL;
-
-		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
-		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
-		mode->hsync_start = mode->hdisplay + \
-				((ti->hsync_offset_hi << 8) | \
-				ti->hsync_offset_lo);
-		mode->hsync_end = mode->hsync_start + \
-				((ti->hsync_pulse_width_hi << 8) | \
-				ti->hsync_pulse_width_lo);
-		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
-							ti->hblank_lo);
-		mode->vsync_start = \
-			mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
-						ti->vsync_offset_lo);
-		mode->vsync_end = \
-			mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
-						ti->vsync_pulse_width_lo);
-		mode->vtotal = mode->vdisplay + \
-				((ti->vblank_hi << 8) | ti->vblank_lo);
-		mode->clock = ti->pixel_clock * 10;
-#if 0
-		printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
-		printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
-		printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
-		printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
-		printk(KERN_INFO "htotal is %d\n", mode->htotal);
-		printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
-		printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
-		printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
-		printk(KERN_INFO "clock is %d\n", mode->clock);
-#endif
-	} else
-		mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
-
-	drm_mode_set_name(mode);
-	drm_mode_set_crtcinfo(mode, 0);
-
-	return mode;
-}
-
-/**
- * mrst_lvds_init - setup LVDS connectors on this device
- * @dev: drm device
- *
- * Create the connector, register the LVDS DDC bus, and try to figure out what
- * modes we can display on the LVDS panel (if present).
- */
-void mrst_lvds_init(struct drm_device *dev,
-		    struct psb_intel_mode_device *mode_dev)
-{
-	struct psb_intel_output *psb_intel_output;
-	struct drm_connector *connector;
-	struct drm_encoder *encoder;
-	struct drm_psb_private *dev_priv =
-				(struct drm_psb_private *) dev->dev_private;
-	struct edid *edid;
-	int ret = 0;
-	struct i2c_adapter *i2c_adap;
-	struct drm_display_mode *scan;	/* *modes, *bios_mode; */
-
-	psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
-	if (!psb_intel_output)
-		return;
-
-	psb_intel_output->mode_dev = mode_dev;
-	connector = &psb_intel_output->base;
-	encoder = &psb_intel_output->enc;
-	dev_priv->is_lvds_on = true;
-	drm_connector_init(dev, &psb_intel_output->base,
-			   &psb_intel_lvds_connector_funcs,
-			   DRM_MODE_CONNECTOR_LVDS);
-
-	drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
-			 DRM_MODE_ENCODER_LVDS);
-
-	drm_mode_connector_attach_encoder(&psb_intel_output->base,
-					  &psb_intel_output->enc);
-	psb_intel_output->type = INTEL_OUTPUT_LVDS;
-
-	drm_encoder_helper_add(encoder, &mrst_lvds_helper_funcs);
-	drm_connector_helper_add(connector,
-				 &psb_intel_lvds_connector_helper_funcs);
-	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-	connector->interlace_allowed = false;
-	connector->doublescan_allowed = false;
-
-	drm_connector_attach_property(connector,
-					dev->mode_config.scaling_mode_property,
-					DRM_MODE_SCALE_FULLSCREEN);
-	drm_connector_attach_property(connector,
-					dev_priv->backlight_property,
-					BRIGHTNESS_MAX_LEVEL);
-
-	mode_dev->panel_wants_dither = false;
-	if (dev_priv->vbt_data.size != 0x00)
-		mode_dev->panel_wants_dither = (dev_priv->gct_data.
-			Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
-
-	/*
-	 * LVDS discovery:
-	 * 1) check for EDID on DDC
-	 * 2) check for VBT data
-	 * 3) check to see if LVDS is already on
-	 *    if none of the above, no panel
-	 * 4) make sure lid is open
-	 *    if closed, act like it's not there for now
-	 */
-
-	i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus);
-
-	if (i2c_adap == NULL)
-		dev_err(dev->dev, "No ddc adapter available!\n");
-	/*
-	 * Attempt to get the fixed panel mode from DDC.  Assume that the
-	 * preferred mode is the right one.
-	 */
-	if (i2c_adap) {
-		edid = drm_get_edid(connector, i2c_adap);
-		if (edid) {
-			drm_mode_connector_update_edid_property(connector,
-									edid);
-			ret = drm_add_edid_modes(connector, edid);
-			kfree(edid);
-		}
-
-		list_for_each_entry(scan, &connector->probed_modes, head) {
-			if (scan->type & DRM_MODE_TYPE_PREFERRED) {
-				mode_dev->panel_fixed_mode =
-				    drm_mode_duplicate(dev, scan);
-				goto out;	/* FIXME: check for quirks */
-			}
-		}
-	}
-	/*
-	 * If we didn't get EDID, try geting panel timing
-	 * from configuration data
-	 */
-	mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev);
-
-	if (mode_dev->panel_fixed_mode) {
-		mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
-		goto out;	/* FIXME: check for quirks */
-	}
-
-	/* If we still don't have a mode after all that, give up. */
-	if (!mode_dev->panel_fixed_mode) {
-		dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
-		goto failed_find;
-	}
-
-out:
-	drm_sysfs_connector_add(connector);
-	return;
-
-failed_find:
-	dev_dbg(dev->dev, "No LVDS modes found, disabling.\n");
-	if (psb_intel_output->ddc_bus)
-		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-
-/* failed_ddc: */
-
-	drm_encoder_cleanup(encoder);
-	drm_connector_cleanup(connector);
-	kfree(connector);
-}
-
diff --git a/drivers/staging/gma500/power.c b/drivers/staging/gma500/power.c
deleted file mode 100644
index 4082570..0000000
--- a/drivers/staging/gma500/power.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2009-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Benjamin Defnet <benjamin.r.defnet@intel.com>
- *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- * Massively reworked
- *    Alan Cox <alan@linux.intel.com>
- */
-
-#include "power.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include <linux/mutex.h>
-#include <linux/pm_runtime.h>
-
-static struct mutex power_mutex;	/* Serialize power ops */
-static spinlock_t power_ctrl_lock;	/* Serialize power claim */
-
-/**
- *	gma_power_init		-	initialise power manager
- *	@dev: our device
- *
- *	Set up for power management tracking of our hardware.
- */
-void gma_power_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	/* FIXME: Move APM/OSPM base into relevant device code */
-	dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
-	dev_priv->ospm_base &= 0xffff;
-
-	dev_priv->display_power = true;	/* We start active */
-	dev_priv->display_count = 0;	/* Currently no users */
-	dev_priv->suspended = false;	/* And not suspended */
-	spin_lock_init(&power_ctrl_lock);
-	mutex_init(&power_mutex);
-
-	dev_priv->ops->init_pm(dev);
-}
-
-/**
- *	gma_power_uninit	-	end power manager
- *	@dev: device to end for
- *
- *	Undo the effects of gma_power_init
- */
-void gma_power_uninit(struct drm_device *dev)
-{
-	pm_runtime_disable(&dev->pdev->dev);
-	pm_runtime_set_suspended(&dev->pdev->dev);
-}
-
-/**
- *	gma_suspend_display	-	suspend the display logic
- *	@dev: our DRM device
- *
- *	Suspend the display logic of the graphics interface
- */
-static void gma_suspend_display(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (!dev_priv->display_power)
-		return;
-	dev_priv->ops->save_regs(dev);
-	dev_priv->ops->power_down(dev);
-	dev_priv->display_power = false;
-}
-
-/**
- *	gma_resume_display	-	resume display side logic
- *
- *	Resume the display hardware restoring state and enabling
- *	as necessary.
- */
-static void gma_resume_display(struct pci_dev *pdev)
-{
-	struct drm_device *dev = pci_get_drvdata(pdev);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (dev_priv->display_power)
-		return;
-
-	/* turn on the display power island */
-	dev_priv->ops->power_up(dev);
-	dev_priv->suspended = false;
-	dev_priv->display_power = true;
-
-	PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
-	pci_write_config_word(pdev, PSB_GMCH_CTRL,
-			dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
-	dev_priv->ops->restore_regs(dev);
-}
-
-/**
- *	gma_suspend_pci		-	suspend PCI side
- *	@pdev: PCI device
- *
- *	Perform the suspend processing on our PCI device state
- */
-static void gma_suspend_pci(struct pci_dev *pdev)
-{
-	struct drm_device *dev = pci_get_drvdata(pdev);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int bsm, vbt;
-
-	if (dev_priv->suspended)
-		return;
-
-	pci_save_state(pdev);
-	pci_read_config_dword(pdev, 0x5C, &bsm);
-	dev_priv->saveBSM = bsm;
-	pci_read_config_dword(pdev, 0xFC, &vbt);
-	dev_priv->saveVBT = vbt;
-	pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
-	pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
-
-	pci_disable_device(pdev);
-	pci_set_power_state(pdev, PCI_D3hot);
-
-	dev_priv->suspended = true;
-}
-
-/**
- *	gma_resume_pci		-	resume helper
- *	@dev: our PCI device
- *
- *	Perform the resume processing on our PCI device state - rewrite
- *	register state and re-enable the PCI device
- */
-static bool gma_resume_pci(struct pci_dev *pdev)
-{
-	struct drm_device *dev = pci_get_drvdata(pdev);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int ret;
-
-	if (!dev_priv->suspended)
-		return true;
-
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
-	pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
-	pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT);
-	/* restoring MSI address and data in PCIx space */
-	pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
-	pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
-	ret = pci_enable_device(pdev);
-
-	if (ret != 0)
-		dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
-	else
-		dev_priv->suspended = false;
-	return !dev_priv->suspended;
-}
-
-/**
- *	gma_power_suspend		-	bus callback for suspend
- *	@pdev: our PCI device
- *	@state: suspend type
- *
- *	Called back by the PCI layer during a suspend of the system. We
- *	perform the necessary shut down steps and save enough state that
- *	we can undo this when resume is called.
- */
-int gma_power_suspend(struct device *_dev)
-{
-	struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev);
-	struct drm_device *dev = pci_get_drvdata(pdev);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	mutex_lock(&power_mutex);
-	if (!dev_priv->suspended) {
-		if (dev_priv->display_count) {
-			mutex_unlock(&power_mutex);
-			return -EBUSY;
-		}
-		psb_irq_uninstall(dev);
-		gma_suspend_display(dev);
-		gma_suspend_pci(pdev);
-	}
-	mutex_unlock(&power_mutex);
-	return 0;
-}
-
-/**
- *	gma_power_resume		-	resume power
- *	@pdev: PCI device
- *
- *	Resume the PCI side of the graphics and then the displays
- */
-int gma_power_resume(struct device *_dev)
-{
-	struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev);
-	struct drm_device *dev = pci_get_drvdata(pdev);
-
-	mutex_lock(&power_mutex);
-	gma_resume_pci(pdev);
-	gma_resume_display(pdev);
-	psb_irq_preinstall(dev);
-	psb_irq_postinstall(dev);
-	mutex_unlock(&power_mutex);
-	return 0;
-}
-
-/**
- *	gma_power_is_on		-	returne true if power is on
- *	@dev: our DRM device
- *
- *	Returns true if the display island power is on at this moment
- */
-bool gma_power_is_on(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	return dev_priv->display_power;
-}
-
-/**
- *	gma_power_begin		-	begin requiring power
- *	@dev: our DRM device
- *	@force_on: true to force power on
- *
- *	Begin an action that requires the display power island is enabled.
- *	We refcount the islands.
- */
-bool gma_power_begin(struct drm_device *dev, bool force_on)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&power_ctrl_lock, flags);
-	/* Power already on ? */
-	if (dev_priv->display_power) {
-		dev_priv->display_count++;
-		pm_runtime_get(&dev->pdev->dev);
-		spin_unlock_irqrestore(&power_ctrl_lock, flags);
-		return true;
-	}
-	if (force_on == false)
-		goto out_false;
-
-	/* Ok power up needed */
-	ret = gma_resume_pci(dev->pdev);
-	if (ret == 0) {
-		/* FIXME: we want to defer this for Medfield/Oaktrail */
-		gma_resume_display(dev->pdev);
-		psb_irq_preinstall(dev);
-		psb_irq_postinstall(dev);
-		pm_runtime_get(&dev->pdev->dev);
-		dev_priv->display_count++;
-		spin_unlock_irqrestore(&power_ctrl_lock, flags);
-		return true;
-	}
-out_false:
-	spin_unlock_irqrestore(&power_ctrl_lock, flags);
-	return false;
-}
-
-/**
- *	gma_power_end		-	end use of power
- *	@dev: Our DRM device
- *
- *	Indicate that one of our gma_power_begin() requested periods when
- *	the diplay island power is needed has completed.
- */
-void gma_power_end(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long flags;
-	spin_lock_irqsave(&power_ctrl_lock, flags);
-	dev_priv->display_count--;
-	WARN_ON(dev_priv->display_count < 0);
-	spin_unlock_irqrestore(&power_ctrl_lock, flags);
-	pm_runtime_put(&dev->pdev->dev);
-}
-
-int psb_runtime_suspend(struct device *dev)
-{
-	return gma_power_suspend(dev);
-}
-
-int psb_runtime_resume(struct device *dev)
-{
-	return gma_power_resume(dev);;
-}
-
-int psb_runtime_idle(struct device *dev)
-{
-	struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
-	struct drm_psb_private *dev_priv = drmdev->dev_private;
-	if (dev_priv->display_count)
-		return 0;
-	else
-		return 1;
-}
diff --git a/drivers/staging/gma500/power.h b/drivers/staging/gma500/power.h
deleted file mode 100644
index 1969d2e..0000000
--- a/drivers/staging/gma500/power.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2009-2011, Intel Corporation.
- * All Rights Reserved.
-
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Benjamin Defnet <benjamin.r.defnet@intel.com>
- *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- * Massively reworked
- *    Alan Cox <alan@linux.intel.com>
- */
-#ifndef _PSB_POWERMGMT_H_
-#define _PSB_POWERMGMT_H_
-
-#include <linux/pci.h>
-#include <drm/drmP.h>
-
-void gma_power_init(struct drm_device *dev);
-void gma_power_uninit(struct drm_device *dev);
-
-/*
- * The kernel bus power management  will call these functions
- */
-int gma_power_suspend(struct device *dev);
-int gma_power_resume(struct device *dev);
-
-/*
- * These are the functions the driver should use to wrap all hw access
- * (i.e. register reads and writes)
- */
-bool gma_power_begin(struct drm_device *dev, bool force);
-void gma_power_end(struct drm_device *dev);
-
-/*
- * Use this function to do an instantaneous check for if the hw is on.
- * Only use this in cases where you know the mutex is already held such
- * as in irq install/uninstall and you need to
- * prevent a deadlock situation.  Otherwise use gma_power_begin().
- */
-bool gma_power_is_on(struct drm_device *dev);
-
-/*
- * GFX-Runtime PM callbacks
- */
-int psb_runtime_suspend(struct device *dev);
-int psb_runtime_resume(struct device *dev);
-int psb_runtime_idle(struct device *dev);
-
-#endif /*_PSB_POWERMGMT_H_*/
diff --git a/drivers/staging/gma500/psb_device.c b/drivers/staging/gma500/psb_device.c
deleted file mode 100644
index b97aa78..0000000
--- a/drivers/staging/gma500/psb_device.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <linux/backlight.h>
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-
-
-static int psb_output_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	psb_intel_lvds_init(dev, &dev_priv->mode_dev);
-	psb_intel_sdvo_init(dev, SDVOB);
-	return 0;
-}
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-
-/*
- *	Poulsbo Backlight Interfaces
- */
-
-#define BLC_PWM_PRECISION_FACTOR 100	/* 10000000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 1000000
-
-#define PSB_BLC_PWM_PRECISION_FACTOR    10
-#define PSB_BLC_MAX_PWM_REG_FREQ        0xFFFE
-#define PSB_BLC_MIN_PWM_REG_FREQ        0x2
-
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)
-
-static int psb_brightness;
-static struct backlight_device *psb_backlight_device;
-
-static int psb_get_brightness(struct backlight_device *bd)
-{
-	/* return locally cached var instead of HW read (due to DPST etc.) */
-	/* FIXME: ideally return actual value in case firmware fiddled with
-	   it */
-	return psb_brightness;
-}
-
-
-static int psb_backlight_setup(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long core_clock;
-	/* u32 bl_max_freq; */
-	/* unsigned long value; */
-	u16 bl_max_freq;
-	uint32_t value;
-	uint32_t blc_pwm_precision_factor;
-
-	/* get bl_max_freq and pol from dev_priv*/
-	if (!dev_priv->lvds_bl) {
-		dev_err(dev->dev, "Has no valid LVDS backlight info\n");
-		return -ENOENT;
-	}
-	bl_max_freq = dev_priv->lvds_bl->freq;
-	blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
-
-	core_clock = dev_priv->core_freq;
-
-	value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
-	value *= blc_pwm_precision_factor;
-	value /= bl_max_freq;
-	value /= blc_pwm_precision_factor;
-
-	if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
-		 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
-				return -ERANGE;
-	else {
-		value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
-		REG_WRITE(BLC_PWM_CTL,
-			(value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value));
-	}
-	return 0;
-}
-
-static int psb_set_brightness(struct backlight_device *bd)
-{
-	struct drm_device *dev = bl_get_data(psb_backlight_device);
-	int level = bd->props.brightness;
-
-	/* Percentage 1-100% being valid */
-	if (level < 1)
-		level = 1;
-
-	psb_intel_lvds_set_brightness(dev, level);
-	psb_brightness = level;
-	return 0;
-}
-
-static const struct backlight_ops psb_ops = {
-	.get_brightness = psb_get_brightness,
-	.update_status  = psb_set_brightness,
-};
-
-static int psb_backlight_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	int ret;
-	struct backlight_properties props;
-
-	memset(&props, 0, sizeof(struct backlight_properties));
-	props.max_brightness = 100;
-	props.type = BACKLIGHT_PLATFORM;
-
-	psb_backlight_device = backlight_device_register("psb-bl",
-					NULL, (void *)dev, &psb_ops, &props);
-	if (IS_ERR(psb_backlight_device))
-		return PTR_ERR(psb_backlight_device);
-
-	ret = psb_backlight_setup(dev);
-	if (ret < 0) {
-		backlight_device_unregister(psb_backlight_device);
-		psb_backlight_device = NULL;
-		return ret;
-	}
-	psb_backlight_device->props.brightness = 100;
-	psb_backlight_device->props.max_brightness = 100;
-	backlight_update_status(psb_backlight_device);
-	dev_priv->backlight_device = psb_backlight_device;
-	return 0;
-}
-
-#endif
-
-/*
- *	Provide the Poulsbo specific chip logic and low level methods
- *	for power management
- */
-
-static void psb_init_pm(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
-	gating &= ~3;	/* Disable 2D clock gating */
-	gating |= 1;
-	PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
-	PSB_RSGX32(PSB_CR_CLKGATECTL);
-}
-
-/**
- *	psb_save_display_registers	-	save registers lost on suspend
- *	@dev: our DRM device
- *
- *	Save the state we need in order to be able to restore the interface
- *	upon resume from suspend
- */
-static int psb_save_display_registers(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_crtc *crtc;
-	struct drm_connector *connector;
-
-	/* Display arbitration control + watermarks */
-	dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
-	dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
-	dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
-	dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
-	dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
-	dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
-	dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
-	dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
-
-	/* Save crtc and output state */
-	mutex_lock(&dev->mode_config.mutex);
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		if (drm_helper_crtc_in_use(crtc))
-			crtc->funcs->save(crtc);
-	}
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-		connector->funcs->save(connector);
-
-	mutex_unlock(&dev->mode_config.mutex);
-	return 0;
-}
-
-/**
- *	psb_restore_display_registers	-	restore lost register state
- *	@dev: our DRM device
- *
- *	Restore register state that was lost during suspend and resume.
- */
-static int psb_restore_display_registers(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_crtc *crtc;
-	struct drm_connector *connector;
-
-	/* Display arbitration + watermarks */
-	PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
-	PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
-	PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
-	PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
-	PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
-	PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
-	PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
-	PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
-
-	/*make sure VGA plane is off. it initializes to on after reset!*/
-	PSB_WVDC32(0x80000000, VGACNTRL);
-
-	mutex_lock(&dev->mode_config.mutex);
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-		if (drm_helper_crtc_in_use(crtc))
-			crtc->funcs->restore(crtc);
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-		connector->funcs->restore(connector);
-
-	mutex_unlock(&dev->mode_config.mutex);
-	return 0;
-}
-
-static int psb_power_down(struct drm_device *dev)
-{
-	return 0;
-}
-
-static int psb_power_up(struct drm_device *dev)
-{
-	return 0;
-}
-
-static void psb_get_core_freq(struct drm_device *dev)
-{
-	uint32_t clock;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	/*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/
-	/*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/
-
-	pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
-	pci_read_config_dword(pci_root, 0xD4, &clock);
-	pci_dev_put(pci_root);
-
-	switch (clock & 0x07) {
-	case 0:
-		dev_priv->core_freq = 100;
-		break;
-	case 1:
-		dev_priv->core_freq = 133;
-		break;
-	case 2:
-		dev_priv->core_freq = 150;
-		break;
-	case 3:
-		dev_priv->core_freq = 178;
-		break;
-	case 4:
-		dev_priv->core_freq = 200;
-		break;
-	case 5:
-	case 6:
-	case 7:
-		dev_priv->core_freq = 266;
-	default:
-		dev_priv->core_freq = 0;
-	}
-}
-
-static int psb_chip_setup(struct drm_device *dev)
-{
-	psb_get_core_freq(dev);
-	gma_intel_opregion_init(dev);
-	psb_intel_init_bios(dev);
-	return 0;
-}
-
-const struct psb_ops psb_chip_ops = {
-	.name = "Poulsbo",
-	.accel_2d = 1,
-	.pipes = 2,
-	.crtcs = 2,
-	.sgx_offset = PSB_SGX_OFFSET,
-	.chip_setup = psb_chip_setup,
-
-	.crtc_helper = &psb_intel_helper_funcs,
-	.crtc_funcs = &psb_intel_crtc_funcs,
-
-	.output_init = psb_output_init,
-
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	.backlight_init = psb_backlight_init,
-#endif
-
-	.init_pm = psb_init_pm,
-	.save_regs = psb_save_display_registers,
-	.restore_regs = psb_restore_display_registers,
-	.power_down = psb_power_down,
-	.power_up = psb_power_up,
-};
-
diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
deleted file mode 100644
index 0da8468..0000000
--- a/drivers/staging/gma500/psb_drm.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics Inc.  Cedar Park, TX., USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#ifndef _PSB_DRM_H_
-#define _PSB_DRM_H_
-
-#define PSB_NUM_PIPE 3
-
-#define PSB_GPU_ACCESS_READ         (1ULL << 32)
-#define PSB_GPU_ACCESS_WRITE        (1ULL << 33)
-#define PSB_GPU_ACCESS_MASK         (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)
-
-#define PSB_BO_FLAG_COMMAND         (1ULL << 52)
-
-/*
- * Feedback components:
- */
-
-struct drm_psb_sizes_arg {
-	u32 ta_mem_size;
-	u32 mmu_size;
-	u32 pds_size;
-	u32 rastgeom_size;
-	u32 tt_size;
-	u32 vram_size;
-};
-
-struct drm_psb_dpst_lut_arg {
-	uint8_t lut[256];
-	int output_id;
-};
-
-#define PSB_DC_CRTC_SAVE 0x01
-#define PSB_DC_CRTC_RESTORE 0x02
-#define PSB_DC_OUTPUT_SAVE 0x04
-#define PSB_DC_OUTPUT_RESTORE 0x08
-#define PSB_DC_CRTC_MASK 0x03
-#define PSB_DC_OUTPUT_MASK 0x0C
-
-struct drm_psb_dc_state_arg {
-	u32 flags;
-	u32 obj_id;
-};
-
-struct drm_psb_mode_operation_arg {
-	u32 obj_id;
-	u16 operation;
-	struct drm_mode_modeinfo mode;
-	void *data;
-};
-
-struct drm_psb_stolen_memory_arg {
-	u32 base;
-	u32 size;
-};
-
-/*Display Register Bits*/
-#define REGRWBITS_PFIT_CONTROLS			(1 << 0)
-#define REGRWBITS_PFIT_AUTOSCALE_RATIOS		(1 << 1)
-#define REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS	(1 << 2)
-#define REGRWBITS_PIPEASRC			(1 << 3)
-#define REGRWBITS_PIPEBSRC			(1 << 4)
-#define REGRWBITS_VTOTAL_A			(1 << 5)
-#define REGRWBITS_VTOTAL_B			(1 << 6)
-#define REGRWBITS_DSPACNTR	(1 << 8)
-#define REGRWBITS_DSPBCNTR	(1 << 9)
-#define REGRWBITS_DSPCCNTR	(1 << 10)
-
-/*Overlay Register Bits*/
-#define OV_REGRWBITS_OVADD			(1 << 0)
-#define OV_REGRWBITS_OGAM_ALL			(1 << 1)
-
-#define OVC_REGRWBITS_OVADD                  (1 << 2)
-#define OVC_REGRWBITS_OGAM_ALL			(1 << 3)
-
-struct drm_psb_register_rw_arg {
-	u32 b_force_hw_on;
-
-	u32 display_read_mask;
-	u32 display_write_mask;
-
-	struct {
-		u32 pfit_controls;
-		u32 pfit_autoscale_ratios;
-		u32 pfit_programmed_scale_ratios;
-		u32 pipeasrc;
-		u32 pipebsrc;
-		u32 vtotal_a;
-		u32 vtotal_b;
-	} display;
-
-	u32 overlay_read_mask;
-	u32 overlay_write_mask;
-
-	struct {
-		u32 OVADD;
-		u32 OGAMC0;
-		u32 OGAMC1;
-		u32 OGAMC2;
-		u32 OGAMC3;
-		u32 OGAMC4;
-		u32 OGAMC5;
-		u32 IEP_ENABLED;
-		u32 IEP_BLE_MINMAX;
-		u32 IEP_BSSCC_CONTROL;
-		u32 b_wait_vblank;
-	} overlay;
-
-	u32 sprite_enable_mask;
-	u32 sprite_disable_mask;
-
-	struct {
-		u32 dspa_control;
-		u32 dspa_key_value;
-		u32 dspa_key_mask;
-		u32 dspc_control;
-		u32 dspc_stride;
-		u32 dspc_position;
-		u32 dspc_linear_offset;
-		u32 dspc_size;
-		u32 dspc_surface;
-	} sprite;
-
-	u32 subpicture_enable_mask;
-	u32 subpicture_disable_mask;
-};
-
-/* Controlling the kernel modesetting buffers */
-
-#define DRM_PSB_SIZES           0x07
-#define DRM_PSB_FUSE_REG	0x08
-#define DRM_PSB_DC_STATE	0x0A
-#define DRM_PSB_ADB		0x0B
-#define DRM_PSB_MODE_OPERATION	0x0C
-#define DRM_PSB_STOLEN_MEMORY	0x0D
-#define DRM_PSB_REGISTER_RW	0x0E
-
-/*
- * NOTE: Add new commands here, but increment
- * the values below and increment their
- * corresponding defines where they're
- * defined elsewhere.
- */
-
-#define DRM_PSB_GEM_CREATE	0x10
-#define DRM_PSB_2D_OP		0x11
-#define DRM_PSB_GEM_MMAP	0x12
-#define DRM_PSB_DPST		0x1B
-#define DRM_PSB_GAMMA		0x1C
-#define DRM_PSB_DPST_BL		0x1D
-#define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F
-
-#define PSB_MODE_OPERATION_MODE_VALID	0x01
-#define PSB_MODE_OPERATION_SET_DC_BASE  0x02
-
-struct drm_psb_get_pipe_from_crtc_id_arg {
-	/** ID of CRTC being requested **/
-	u32 crtc_id;
-
-	/** pipe of requested CRTC **/
-	u32 pipe;
-};
-
-/* FIXME: move this into a medfield header once we are sure it isn't needed for an
-   ioctl  */
-struct psb_drm_dpu_rect {  
-	int x, y;             
-	int width, height;    
-};  
-
-struct drm_psb_gem_create {
-	__u64 size;
-	__u32 handle;
-	__u32 flags;
-#define PSB_GEM_CREATE_STOLEN		1	/* Stolen memory can be used */
-};
-
-#define PSB_2D_OP_BUFLEN		16
-
-struct drm_psb_2d_op {
-	__u32 src;		/* Handles, only src supported right now */
-	__u32 dst;
-	__u32 mask;
-	__u32 pat;
-	__u32 size;		/* In dwords of command */
-	__u32 spare;		/* And bumps array to u64 align */
-	__u32 cmd[PSB_2D_OP_BUFLEN];
-};
-
-struct drm_psb_gem_mmap {
-	__u32 handle;
-	__u32 pad;
-	/**
-	 * Fake offset to use for subsequent mmap call
-	 *
-	 * This is a fixed-size type for 32/64 compatibility.
-	 */
-	__u64 offset;
-};
-
-#endif
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
deleted file mode 100644
index 9581680..0000000
--- a/drivers/staging/gma500/psb_drv.c
+++ /dev/null
@@ -1,1230 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include <drm/drm.h>
-#include "psb_drm.h"
-#include "psb_drv.h"
-#include "framebuffer.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "intel_bios.h"
-#include "mid_bios.h"
-#include "mdfld_dsi_dbi.h"
-#include <drm/drm_pciids.h>
-#include "power.h"
-#include <linux/cpu.h>
-#include <linux/notifier.h>
-#include <linux/spinlock.h>
-#include <linux/pm_runtime.h>
-#include <linux/module.h>
-#include <acpi/video.h>
-
-static int drm_psb_trap_pagefaults;
-
-int drm_psb_no_fb;
-
-static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-
-MODULE_PARM_DESC(no_fb, "Disable FBdev");
-MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
-module_param_named(no_fb, drm_psb_no_fb, int, 0600);
-module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
-
-
-static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
-	{ 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
-	{ 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
-#if defined(CONFIG_DRM_PSB_MRST)
-	{ 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-	{ 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-	{ 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-	{ 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-	{ 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-	{ 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-	{ 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-	{ 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
-#endif
-#if defined(CONFIG_DRM_PSB_MFLD)
-	{ 0x8086, 0x0130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-	{ 0x8086, 0x0131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-	{ 0x8086, 0x0132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-	{ 0x8086, 0x0133, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-	{ 0x8086, 0x0134, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-	{ 0x8086, 0x0135, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-	{ 0x8086, 0x0136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-	{ 0x8086, 0x0137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
-#endif
-#if defined(CONFIG_DRM_PSB_CDV)
-	{ 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-	{ 0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-	{ 0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-	{ 0x8086, 0x0be3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-	{ 0x8086, 0x0be4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-	{ 0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-	{ 0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-	{ 0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops},
-#endif
-	{ 0, 0, 0}
-};
-MODULE_DEVICE_TABLE(pci, pciidlist);
-
-/*
- * Standard IOCTLs.
- */
-
-#define DRM_IOCTL_PSB_SIZES	\
-		DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
-			struct drm_psb_sizes_arg)
-#define DRM_IOCTL_PSB_FUSE_REG	\
-		DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t)
-#define DRM_IOCTL_PSB_DC_STATE	\
-		DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \
-			struct drm_psb_dc_state_arg)
-#define DRM_IOCTL_PSB_ADB	\
-		DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t)
-#define DRM_IOCTL_PSB_MODE_OPERATION	\
-		DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \
-			 struct drm_psb_mode_operation_arg)
-#define DRM_IOCTL_PSB_STOLEN_MEMORY	\
-		DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \
-			 struct drm_psb_stolen_memory_arg)
-#define DRM_IOCTL_PSB_REGISTER_RW	\
-		DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
-			 struct drm_psb_register_rw_arg)
-#define DRM_IOCTL_PSB_DPST	\
-		DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
-			 uint32_t)
-#define DRM_IOCTL_PSB_GAMMA	\
-		DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \
-			 struct drm_psb_dpst_lut_arg)
-#define DRM_IOCTL_PSB_DPST_BL	\
-		DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \
-			 uint32_t)
-#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID	\
-		DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
-			 struct drm_psb_get_pipe_from_crtc_id_arg)
-#define DRM_IOCTL_PSB_GEM_CREATE	\
-		DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \
-			 struct drm_psb_gem_create)
-#define DRM_IOCTL_PSB_2D_OP	\
-		DRM_IOW(DRM_PSB_2D_OP + DRM_COMMAND_BASE, \
-			 struct drm_psb_2d_op)
-#define DRM_IOCTL_PSB_GEM_MMAP	\
-		DRM_IOWR(DRM_PSB_GEM_MMAP + DRM_COMMAND_BASE, \
-			 struct drm_psb_gem_mmap)
-
-static int psb_sizes_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv);
-static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
-			      struct drm_file *file_priv);
-static int psb_adb_ioctl(struct drm_device *dev, void *data,
-			 struct drm_file *file_priv);
-static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
-				    struct drm_file *file_priv);
-static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
-				   struct drm_file *file_priv);
-static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
-				 struct drm_file *file_priv);
-static int psb_dpst_ioctl(struct drm_device *dev, void *data,
-			  struct drm_file *file_priv);
-static int psb_gamma_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv);
-static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
-			     struct drm_file *file_priv);
-
-#define PSB_IOCTL_DEF(ioctl, func, flags) \
-	[DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
-
-static struct drm_ioctl_desc psb_ioctls[] = {
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
-					psb_intel_get_pipe_from_crtc_id, 0),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl,
-						DRM_UNLOCKED | DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_2D_OP, psb_accel_ioctl,
-						DRM_UNLOCKED| DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_MMAP, psb_gem_mmap_ioctl,
-						DRM_UNLOCKED | DRM_AUTH),
-};
-
-static void psb_lastclose(struct drm_device *dev)
-{
-	return;
-}
-
-static void psb_do_takedown(struct drm_device *dev)
-{
-}
-
-static int psb_do_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_gtt *pg = &dev_priv->gtt;
-
-	uint32_t stolen_gtt;
-
-	int ret = -ENOMEM;
-
-	if (pg->mmu_gatt_start & 0x0FFFFFFF) {
-		dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n");
-		ret = -EINVAL;
-		goto out_err;
-	}
-
-
-	stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4;
-	stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	stolen_gtt =
-	    (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages;
-
-	dev_priv->gatt_free_offset = pg->mmu_gatt_start +
-	    (stolen_gtt << PAGE_SHIFT) * 1024;
-
-	if (1 || drm_debug) {
-		uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID);
-		uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION);
-		DRM_INFO("SGX core id = 0x%08x\n", core_id);
-		DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n",
-			 (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >>
-			 _PSB_CC_REVISION_MAJOR_SHIFT,
-			 (core_rev & _PSB_CC_REVISION_MINOR_MASK) >>
-			 _PSB_CC_REVISION_MINOR_SHIFT);
-		DRM_INFO
-		    ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n",
-		     (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >>
-		     _PSB_CC_REVISION_MAINTENANCE_SHIFT,
-		     (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >>
-		     _PSB_CC_REVISION_DESIGNER_SHIFT);
-	}
-
-
-	spin_lock_init(&dev_priv->irqmask_lock);
-	spin_lock_init(&dev_priv->lock_2d);
-
-	PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
-	PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
-	PSB_RSGX32(PSB_CR_BIF_BANK1);
-	PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
-							PSB_CR_BIF_CTRL);
-	psb_spank(dev_priv);
-
-	/* mmu_gatt ?? */
-	PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
-	return 0;
-out_err:
-	psb_do_takedown(dev);
-	return ret;
-}
-
-static int psb_driver_unload(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	/* Kill vblank etc here */
-
-	gma_backlight_exit(dev);
-
-	if (drm_psb_no_fb == 0)
-		psb_modeset_cleanup(dev);
-
-	if (dev_priv) {
-		psb_lid_timer_takedown(dev_priv);
-		gma_intel_opregion_exit(dev);
-
-		if (dev_priv->ops->chip_teardown)
-			dev_priv->ops->chip_teardown(dev);
-		psb_do_takedown(dev);
-
-
-		if (dev_priv->pf_pd) {
-			psb_mmu_free_pagedir(dev_priv->pf_pd);
-			dev_priv->pf_pd = NULL;
-		}
-		if (dev_priv->mmu) {
-			struct psb_gtt *pg = &dev_priv->gtt;
-
-			down_read(&pg->sem);
-			psb_mmu_remove_pfn_sequence(
-				psb_mmu_get_default_pd
-				(dev_priv->mmu),
-				pg->mmu_gatt_start,
-				dev_priv->vram_stolen_size >> PAGE_SHIFT);
-			up_read(&pg->sem);
-			psb_mmu_driver_takedown(dev_priv->mmu);
-			dev_priv->mmu = NULL;
-		}
-		psb_gtt_takedown(dev);
-		if (dev_priv->scratch_page) {
-			__free_page(dev_priv->scratch_page);
-			dev_priv->scratch_page = NULL;
-		}
-		if (dev_priv->vdc_reg) {
-			iounmap(dev_priv->vdc_reg);
-			dev_priv->vdc_reg = NULL;
-		}
-		if (dev_priv->sgx_reg) {
-			iounmap(dev_priv->sgx_reg);
-			dev_priv->sgx_reg = NULL;
-		}
-
-		kfree(dev_priv);
-		dev->dev_private = NULL;
-
-		/*destroy VBT data*/
-		psb_intel_destroy_bios(dev);
-	}
-
-	gma_power_uninit(dev);
-
-	return 0;
-}
-
-
-static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
-{
-	struct drm_psb_private *dev_priv;
-	unsigned long resource_start;
-	struct psb_gtt *pg;
-	unsigned long irqflags;
-	int ret = -ENOMEM;
-	uint32_t tt_pages;
-	struct drm_connector *connector;
-	struct psb_intel_output *psb_intel_output;
-
-	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
-	if (dev_priv == NULL)
-		return -ENOMEM;
-
-	dev_priv->ops = (struct psb_ops *)chipset;
-	dev_priv->dev = dev;
-	dev->dev_private = (void *) dev_priv;
-
-	if (!IS_PSB(dev)) {
-		if (pci_enable_msi(dev->pdev))
-			dev_warn(dev->dev, "Enabling MSI failed!\n");
-	}
-
-	dev_priv->num_pipe = dev_priv->ops->pipes;
-
-	resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
-
-	dev_priv->vdc_reg =
-	    ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE);
-	if (!dev_priv->vdc_reg)
-		goto out_err;
-
-	dev_priv->sgx_reg = ioremap(resource_start + dev_priv->ops->sgx_offset,
-							PSB_SGX_SIZE);
-	if (!dev_priv->sgx_reg)
-		goto out_err;
-
-	ret = dev_priv->ops->chip_setup(dev);
-	if (ret)
-		goto out_err;
-
-	/* Init OSPM support */
-	gma_power_init(dev);
-
-	ret = -ENOMEM;
-
-	dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO);
-	if (!dev_priv->scratch_page)
-		goto out_err;
-
-	set_pages_uc(dev_priv->scratch_page, 1);
-
-	ret = psb_gtt_init(dev, 0);
-	if (ret)
-		goto out_err;
-
-	dev_priv->mmu = psb_mmu_driver_init((void *)0,
-					drm_psb_trap_pagefaults, 0,
-					dev_priv);
-	if (!dev_priv->mmu)
-		goto out_err;
-
-	pg = &dev_priv->gtt;
-
-	tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
-		(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
-
-
-	dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
-	if (!dev_priv->pf_pd)
-		goto out_err;
-
-	psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
-	psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
-
-	ret = psb_do_init(dev);
-	if (ret)
-		return ret;
-
-	PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE);
-	PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE);
-
-/*	igd_opregion_init(&dev_priv->opregion_dev); */
-	acpi_video_register();
-	if (dev_priv->lid_state)
-		psb_lid_timer_init(dev_priv);
-
-	ret = drm_vblank_init(dev, dev_priv->num_pipe);
-	if (ret)
-		goto out_err;
-
-	/*
-	 * Install interrupt handlers prior to powering off SGX or else we will
-	 * crash.
-	 */
-	dev_priv->vdc_irq_mask = 0;
-	dev_priv->pipestat[0] = 0;
-	dev_priv->pipestat[1] = 0;
-	dev_priv->pipestat[2] = 0;
-	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-	PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
-	PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-	if (IS_PSB(dev) && drm_core_check_feature(dev, DRIVER_MODESET))
-		drm_irq_install(dev);
-
-	dev->vblank_disable_allowed = 1;
-
-	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-
-	dev->driver->get_vblank_counter = psb_get_vblank_counter;
-
-#if defined(CONFIG_DRM_PSB_MFLD)
-	/* FIXME: this is not the right place for this stuff ! */
-	mdfld_output_setup(dev);
-#endif
-	if (drm_psb_no_fb == 0) {
-		psb_modeset_init(dev);
-		psb_fbdev_init(dev);
-		drm_kms_helper_poll_init(dev);
-	}
-
-	/* Only add backlight support if we have LVDS output */
-	list_for_each_entry(connector, &dev->mode_config.connector_list,
-			    head) {
-		psb_intel_output = to_psb_intel_output(connector);
-
-		switch (psb_intel_output->type) {
-		case INTEL_OUTPUT_LVDS:
-		case INTEL_OUTPUT_MIPI:
-			ret = gma_backlight_init(dev);
-			break;
-		}
-	}
-
-	if (ret)
-		return ret;
-
-	/* Enable runtime pm at last */
-	pm_runtime_set_active(&dev->pdev->dev);
-	return 0;
-out_err:
-	psb_driver_unload(dev);
-	return ret;
-}
-
-int psb_driver_device_is_agp(struct drm_device *dev)
-{
-	return 0;
-}
-
-
-static int psb_sizes_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	struct drm_psb_sizes_arg *arg = data;
-
-	*arg = dev_priv->sizes;
-	return 0;
-}
-
-static int psb_dc_state_ioctl(struct drm_device *dev, void *data,
-				struct drm_file *file_priv)
-{
-	uint32_t flags;
-	uint32_t obj_id;
-	struct drm_mode_object *obj;
-	struct drm_connector *connector;
-	struct drm_crtc *crtc;
-	struct drm_psb_dc_state_arg *arg = data;
-
-
-	/* Double check MRST case */
-	if (IS_MRST(dev) || IS_MFLD(dev))
-		return -EOPNOTSUPP;
-
-	flags = arg->flags;
-	obj_id = arg->obj_id;
-
-	if (flags & PSB_DC_CRTC_MASK) {
-		obj = drm_mode_object_find(dev, obj_id,
-				DRM_MODE_OBJECT_CRTC);
-		if (!obj) {
-			dev_dbg(dev->dev, "Invalid CRTC object.\n");
-			return -EINVAL;
-		}
-
-		crtc = obj_to_crtc(obj);
-
-		mutex_lock(&dev->mode_config.mutex);
-		if (drm_helper_crtc_in_use(crtc)) {
-			if (flags & PSB_DC_CRTC_SAVE)
-				crtc->funcs->save(crtc);
-			else
-				crtc->funcs->restore(crtc);
-		}
-		mutex_unlock(&dev->mode_config.mutex);
-
-		return 0;
-	} else if (flags & PSB_DC_OUTPUT_MASK) {
-		obj = drm_mode_object_find(dev, obj_id,
-				DRM_MODE_OBJECT_CONNECTOR);
-		if (!obj) {
-			dev_dbg(dev->dev, "Invalid connector id.\n");
-			return -EINVAL;
-		}
-
-		connector = obj_to_connector(obj);
-		if (flags & PSB_DC_OUTPUT_SAVE)
-			connector->funcs->save(connector);
-		else
-			connector->funcs->restore(connector);
-
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static inline void get_brightness(struct backlight_device *bd)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	if (bd) {
-		bd->props.brightness = bd->ops->get_brightness(bd);
-		backlight_update_status(bd);
-	}
-#endif
-}
-
-static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
-		       struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	uint32_t *arg = data;
-
-	dev_priv->blc_adj2 = *arg;
-	get_brightness(dev_priv->backlight_device);
-	return 0;
-}
-
-static int psb_adb_ioctl(struct drm_device *dev, void *data,
-			struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	uint32_t *arg = data;
-
-	dev_priv->blc_adj1 = *arg;
-	get_brightness(dev_priv->backlight_device);
-	return 0;
-}
-
-/* return the current mode to the dpst module */
-static int psb_dpst_ioctl(struct drm_device *dev, void *data,
-			  struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	uint32_t *arg = data;
-	uint32_t x;
-	uint32_t y;
-	uint32_t reg;
-
-	if (!gma_power_begin(dev, 0))
-		return -EIO;
-
-	reg = PSB_RVDC32(PIPEASRC);
-
-	gma_power_end(dev);
-
-	/* horizontal is the left 16 bits */
-	x = reg >> 16;
-	/* vertical is the right 16 bits */
-	y = reg & 0x0000ffff;
-
-	/* the values are the image size minus one */
-	x++;
-	y++;
-
-	*arg = (x << 16) | y;
-
-	return 0;
-}
-static int psb_gamma_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv)
-{
-	struct drm_psb_dpst_lut_arg *lut_arg = data;
-	struct drm_mode_object *obj;
-	struct drm_crtc *crtc;
-	struct drm_connector *connector;
-	struct psb_intel_crtc *psb_intel_crtc;
-	int i = 0;
-	int32_t obj_id;
-
-	obj_id = lut_arg->output_id;
-	obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
-	if (!obj) {
-		dev_dbg(dev->dev, "Invalid Connector object.\n");
-		return -EINVAL;
-	}
-
-	connector = obj_to_connector(obj);
-	crtc = connector->encoder->crtc;
-	psb_intel_crtc = to_psb_intel_crtc(crtc);
-
-	for (i = 0; i < 256; i++)
-		psb_intel_crtc->lut_adj[i] = lut_arg->lut[i];
-
-	psb_intel_crtc_load_lut(crtc);
-
-	return 0;
-}
-
-static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
-				struct drm_file *file_priv)
-{
-	uint32_t obj_id;
-	uint16_t op;
-	struct drm_mode_modeinfo *umode;
-	struct drm_display_mode *mode = NULL;
-	struct drm_psb_mode_operation_arg *arg;
-	struct drm_mode_object *obj;
-	struct drm_connector *connector;
-	struct drm_framebuffer *drm_fb;
-	struct psb_framebuffer *psb_fb;
-	struct drm_connector_helper_funcs *connector_funcs;
-	int ret = 0;
-	int resp = MODE_OK;
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-
-	arg = (struct drm_psb_mode_operation_arg *)data;
-	obj_id = arg->obj_id;
-	op = arg->operation;
-
-	switch (op) {
-	case PSB_MODE_OPERATION_SET_DC_BASE:
-		obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB);
-		if (!obj) {
-			dev_dbg(dev->dev, "Invalid FB id %d\n", obj_id);
-			return -EINVAL;
-		}
-
-		drm_fb = obj_to_fb(obj);
-		psb_fb = to_psb_fb(drm_fb);
-
-		if (gma_power_begin(dev, 0)) {
-			REG_WRITE(DSPASURF, psb_fb->gtt->offset);
-			REG_READ(DSPASURF);
-			gma_power_end(dev);
-		} else {
-			dev_priv->saveDSPASURF = psb_fb->gtt->offset;
-		}
-
-		return 0;
-	case PSB_MODE_OPERATION_MODE_VALID:
-		umode = &arg->mode;
-
-		mutex_lock(&dev->mode_config.mutex);
-
-		obj = drm_mode_object_find(dev, obj_id,
-					DRM_MODE_OBJECT_CONNECTOR);
-		if (!obj) {
-			ret = -EINVAL;
-			goto mode_op_out;
-		}
-
-		connector = obj_to_connector(obj);
-
-		mode = drm_mode_create(dev);
-		if (!mode) {
-			ret = -ENOMEM;
-			goto mode_op_out;
-		}
-
-		/* drm_crtc_convert_umode(mode, umode); */
-		{
-			mode->clock = umode->clock;
-			mode->hdisplay = umode->hdisplay;
-			mode->hsync_start = umode->hsync_start;
-			mode->hsync_end = umode->hsync_end;
-			mode->htotal = umode->htotal;
-			mode->hskew = umode->hskew;
-			mode->vdisplay = umode->vdisplay;
-			mode->vsync_start = umode->vsync_start;
-			mode->vsync_end = umode->vsync_end;
-			mode->vtotal = umode->vtotal;
-			mode->vscan = umode->vscan;
-			mode->vrefresh = umode->vrefresh;
-			mode->flags = umode->flags;
-			mode->type = umode->type;
-			strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN);
-			mode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
-		}
-
-		connector_funcs = (struct drm_connector_helper_funcs *)
-				   connector->helper_private;
-
-		if (connector_funcs->mode_valid) {
-			resp = connector_funcs->mode_valid(connector, mode);
-			arg->data = (void *)resp;
-		}
-
-		/*do some clean up work*/
-		if (mode)
-			drm_mode_destroy(dev, mode);
-mode_op_out:
-		mutex_unlock(&dev->mode_config.mutex);
-		return ret;
-
-	default:
-		dev_dbg(dev->dev, "Unsupported psb mode operation\n");
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
-static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
-				   struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	struct drm_psb_stolen_memory_arg *arg = data;
-
-	arg->base = dev_priv->stolen_base;
-	arg->size = dev_priv->vram_stolen_size;
-
-	return 0;
-}
-
-/* FIXME: needs Medfield changes */
-static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
-				 struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	struct drm_psb_register_rw_arg *arg = data;
-	bool usage = arg->b_force_hw_on ? true : false;
-
-	if (arg->display_write_mask != 0) {
-		if (gma_power_begin(dev, usage)) {
-			if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
-				PSB_WVDC32(arg->display.pfit_controls,
-					   PFIT_CONTROL);
-			if (arg->display_write_mask &
-			    REGRWBITS_PFIT_AUTOSCALE_RATIOS)
-				PSB_WVDC32(arg->display.pfit_autoscale_ratios,
-					   PFIT_AUTO_RATIOS);
-			if (arg->display_write_mask &
-			    REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
-				PSB_WVDC32(
-				   arg->display.pfit_programmed_scale_ratios,
-				   PFIT_PGM_RATIOS);
-			if (arg->display_write_mask & REGRWBITS_PIPEASRC)
-				PSB_WVDC32(arg->display.pipeasrc,
-					   PIPEASRC);
-			if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
-				PSB_WVDC32(arg->display.pipebsrc,
-					   PIPEBSRC);
-			if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
-				PSB_WVDC32(arg->display.vtotal_a,
-					   VTOTAL_A);
-			if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
-				PSB_WVDC32(arg->display.vtotal_b,
-					   VTOTAL_B);
-			gma_power_end(dev);
-		} else {
-			if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
-				dev_priv->savePFIT_CONTROL =
-						arg->display.pfit_controls;
-			if (arg->display_write_mask &
-			    REGRWBITS_PFIT_AUTOSCALE_RATIOS)
-				dev_priv->savePFIT_AUTO_RATIOS =
-					arg->display.pfit_autoscale_ratios;
-			if (arg->display_write_mask &
-			    REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
-				dev_priv->savePFIT_PGM_RATIOS =
-				   arg->display.pfit_programmed_scale_ratios;
-			if (arg->display_write_mask & REGRWBITS_PIPEASRC)
-				dev_priv->savePIPEASRC = arg->display.pipeasrc;
-			if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
-				dev_priv->savePIPEBSRC = arg->display.pipebsrc;
-			if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
-				dev_priv->saveVTOTAL_A = arg->display.vtotal_a;
-			if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
-				dev_priv->saveVTOTAL_B = arg->display.vtotal_b;
-		}
-	}
-
-	if (arg->display_read_mask != 0) {
-		if (gma_power_begin(dev, usage)) {
-			if (arg->display_read_mask &
-			    REGRWBITS_PFIT_CONTROLS)
-				arg->display.pfit_controls =
-						PSB_RVDC32(PFIT_CONTROL);
-			if (arg->display_read_mask &
-			    REGRWBITS_PFIT_AUTOSCALE_RATIOS)
-				arg->display.pfit_autoscale_ratios =
-						PSB_RVDC32(PFIT_AUTO_RATIOS);
-			if (arg->display_read_mask &
-			    REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
-				arg->display.pfit_programmed_scale_ratios =
-						PSB_RVDC32(PFIT_PGM_RATIOS);
-			if (arg->display_read_mask & REGRWBITS_PIPEASRC)
-				arg->display.pipeasrc = PSB_RVDC32(PIPEASRC);
-			if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
-				arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC);
-			if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
-				arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A);
-			if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
-				arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B);
-			gma_power_end(dev);
-		} else {
-			if (arg->display_read_mask &
-			    REGRWBITS_PFIT_CONTROLS)
-				arg->display.pfit_controls =
-						dev_priv->savePFIT_CONTROL;
-			if (arg->display_read_mask &
-			    REGRWBITS_PFIT_AUTOSCALE_RATIOS)
-				arg->display.pfit_autoscale_ratios =
-						dev_priv->savePFIT_AUTO_RATIOS;
-			if (arg->display_read_mask &
-			    REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
-				arg->display.pfit_programmed_scale_ratios =
-						dev_priv->savePFIT_PGM_RATIOS;
-			if (arg->display_read_mask & REGRWBITS_PIPEASRC)
-				arg->display.pipeasrc = dev_priv->savePIPEASRC;
-			if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
-				arg->display.pipebsrc = dev_priv->savePIPEBSRC;
-			if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
-				arg->display.vtotal_a = dev_priv->saveVTOTAL_A;
-			if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
-				arg->display.vtotal_b = dev_priv->saveVTOTAL_B;
-		}
-	}
-
-	if (arg->overlay_write_mask != 0) {
-		if (gma_power_begin(dev, usage)) {
-			if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
-				PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5);
-				PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4);
-				PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3);
-				PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2);
-				PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1);
-				PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0);
-			}
-			if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
-				PSB_WVDC32(arg->overlay.OGAMC5, OVC_OGAMC5);
-				PSB_WVDC32(arg->overlay.OGAMC4, OVC_OGAMC4);
-				PSB_WVDC32(arg->overlay.OGAMC3, OVC_OGAMC3);
-				PSB_WVDC32(arg->overlay.OGAMC2, OVC_OGAMC2);
-				PSB_WVDC32(arg->overlay.OGAMC1, OVC_OGAMC1);
-				PSB_WVDC32(arg->overlay.OGAMC0, OVC_OGAMC0);
-			}
-
-			if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) {
-				PSB_WVDC32(arg->overlay.OVADD, OV_OVADD);
-
-				if (arg->overlay.b_wait_vblank) {
-					/* Wait for 20ms.*/
-					unsigned long vblank_timeout = jiffies
-								+ HZ/50;
-					uint32_t temp;
-					while (time_before_eq(jiffies,
-							vblank_timeout)) {
-						temp = PSB_RVDC32(OV_DOVASTA);
-						if ((temp & (0x1 << 31)) != 0)
-							break;
-						cpu_relax();
-					}
-				}
-			}
-			if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) {
-				PSB_WVDC32(arg->overlay.OVADD, OVC_OVADD);
-				if (arg->overlay.b_wait_vblank) {
-					/* Wait for 20ms.*/
-					unsigned long vblank_timeout =
-							jiffies + HZ/50;
-					uint32_t temp;
-					while (time_before_eq(jiffies,
-							vblank_timeout)) {
-						temp = PSB_RVDC32(OVC_DOVCSTA);
-						if ((temp & (0x1 << 31)) != 0)
-							break;
-						cpu_relax();
-					}
-				}
-			}
-			gma_power_end(dev);
-		} else {
-			if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
-				dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5;
-				dev_priv->saveOV_OGAMC4 = arg->overlay.OGAMC4;
-				dev_priv->saveOV_OGAMC3 = arg->overlay.OGAMC3;
-				dev_priv->saveOV_OGAMC2 = arg->overlay.OGAMC2;
-				dev_priv->saveOV_OGAMC1 = arg->overlay.OGAMC1;
-				dev_priv->saveOV_OGAMC0 = arg->overlay.OGAMC0;
-			}
-			if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
-				dev_priv->saveOVC_OGAMC5 = arg->overlay.OGAMC5;
-				dev_priv->saveOVC_OGAMC4 = arg->overlay.OGAMC4;
-				dev_priv->saveOVC_OGAMC3 = arg->overlay.OGAMC3;
-				dev_priv->saveOVC_OGAMC2 = arg->overlay.OGAMC2;
-				dev_priv->saveOVC_OGAMC1 = arg->overlay.OGAMC1;
-				dev_priv->saveOVC_OGAMC0 = arg->overlay.OGAMC0;
-			}
-			if (arg->overlay_write_mask & OV_REGRWBITS_OVADD)
-				dev_priv->saveOV_OVADD = arg->overlay.OVADD;
-			if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD)
-				dev_priv->saveOVC_OVADD = arg->overlay.OVADD;
-		}
-	}
-
-	if (arg->overlay_read_mask != 0) {
-		if (gma_power_begin(dev, usage)) {
-			if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
-				arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5);
-				arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4);
-				arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3);
-				arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2);
-				arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1);
-				arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0);
-			}
-			if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
-				arg->overlay.OGAMC5 = PSB_RVDC32(OVC_OGAMC5);
-				arg->overlay.OGAMC4 = PSB_RVDC32(OVC_OGAMC4);
-				arg->overlay.OGAMC3 = PSB_RVDC32(OVC_OGAMC3);
-				arg->overlay.OGAMC2 = PSB_RVDC32(OVC_OGAMC2);
-				arg->overlay.OGAMC1 = PSB_RVDC32(OVC_OGAMC1);
-				arg->overlay.OGAMC0 = PSB_RVDC32(OVC_OGAMC0);
-			}
-			if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
-				arg->overlay.OVADD = PSB_RVDC32(OV_OVADD);
-			if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
-				arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD);
-			gma_power_end(dev);
-		} else {
-			if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
-				arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5;
-				arg->overlay.OGAMC4 = dev_priv->saveOV_OGAMC4;
-				arg->overlay.OGAMC3 = dev_priv->saveOV_OGAMC3;
-				arg->overlay.OGAMC2 = dev_priv->saveOV_OGAMC2;
-				arg->overlay.OGAMC1 = dev_priv->saveOV_OGAMC1;
-				arg->overlay.OGAMC0 = dev_priv->saveOV_OGAMC0;
-			}
-			if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
-				arg->overlay.OGAMC5 = dev_priv->saveOVC_OGAMC5;
-				arg->overlay.OGAMC4 = dev_priv->saveOVC_OGAMC4;
-				arg->overlay.OGAMC3 = dev_priv->saveOVC_OGAMC3;
-				arg->overlay.OGAMC2 = dev_priv->saveOVC_OGAMC2;
-				arg->overlay.OGAMC1 = dev_priv->saveOVC_OGAMC1;
-				arg->overlay.OGAMC0 = dev_priv->saveOVC_OGAMC0;
-			}
-			if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
-				arg->overlay.OVADD = dev_priv->saveOV_OVADD;
-			if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
-				arg->overlay.OVADD = dev_priv->saveOVC_OVADD;
-		}
-	}
-
-	if (arg->sprite_enable_mask != 0) {
-		if (gma_power_begin(dev, usage)) {
-			PSB_WVDC32(0x1F3E, DSPARB);
-			PSB_WVDC32(arg->sprite.dspa_control
-					| PSB_RVDC32(DSPACNTR), DSPACNTR);
-			PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL);
-			PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK);
-			PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF);
-			PSB_RVDC32(DSPASURF);
-			PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR);
-			PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE);
-			PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS);
-			PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF);
-			PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE);
-			PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
-			PSB_RVDC32(DSPCSURF);
-			gma_power_end(dev);
-		}
-	}
-
-	if (arg->sprite_disable_mask != 0) {
-		if (gma_power_begin(dev, usage)) {
-			PSB_WVDC32(0x3F3E, DSPARB);
-			PSB_WVDC32(0x0, DSPCCNTR);
-			PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
-			PSB_RVDC32(DSPCSURF);
-			gma_power_end(dev);
-		}
-	}
-
-	if (arg->subpicture_enable_mask != 0) {
-		if (gma_power_begin(dev, usage)) {
-			uint32_t temp;
-			if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) {
-				temp =  PSB_RVDC32(DSPACNTR);
-				temp &= ~DISPPLANE_PIXFORMAT_MASK;
-				temp &= ~DISPPLANE_BOTTOM;
-				temp |= DISPPLANE_32BPP;
-				PSB_WVDC32(temp, DSPACNTR);
-
-				temp =  PSB_RVDC32(DSPABASE);
-				PSB_WVDC32(temp, DSPABASE);
-				PSB_RVDC32(DSPABASE);
-				temp =  PSB_RVDC32(DSPASURF);
-				PSB_WVDC32(temp, DSPASURF);
-				PSB_RVDC32(DSPASURF);
-			}
-			if (arg->subpicture_enable_mask & REGRWBITS_DSPBCNTR) {
-				temp =  PSB_RVDC32(DSPBCNTR);
-				temp &= ~DISPPLANE_PIXFORMAT_MASK;
-				temp &= ~DISPPLANE_BOTTOM;
-				temp |= DISPPLANE_32BPP;
-				PSB_WVDC32(temp, DSPBCNTR);
-
-				temp =  PSB_RVDC32(DSPBBASE);
-				PSB_WVDC32(temp, DSPBBASE);
-				PSB_RVDC32(DSPBBASE);
-				temp =  PSB_RVDC32(DSPBSURF);
-				PSB_WVDC32(temp, DSPBSURF);
-				PSB_RVDC32(DSPBSURF);
-			}
-			if (arg->subpicture_enable_mask & REGRWBITS_DSPCCNTR) {
-				temp =  PSB_RVDC32(DSPCCNTR);
-				temp &= ~DISPPLANE_PIXFORMAT_MASK;
-				temp &= ~DISPPLANE_BOTTOM;
-				temp |= DISPPLANE_32BPP;
-				PSB_WVDC32(temp, DSPCCNTR);
-
-				temp =  PSB_RVDC32(DSPCBASE);
-				PSB_WVDC32(temp, DSPCBASE);
-				PSB_RVDC32(DSPCBASE);
-				temp =  PSB_RVDC32(DSPCSURF);
-				PSB_WVDC32(temp, DSPCSURF);
-				PSB_RVDC32(DSPCSURF);
-			}
-			gma_power_end(dev);
-		}
-	}
-
-	if (arg->subpicture_disable_mask != 0) {
-		if (gma_power_begin(dev, usage)) {
-			uint32_t temp;
-			if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) {
-				temp =  PSB_RVDC32(DSPACNTR);
-				temp &= ~DISPPLANE_PIXFORMAT_MASK;
-				temp |= DISPPLANE_32BPP_NO_ALPHA;
-				PSB_WVDC32(temp, DSPACNTR);
-
-				temp =  PSB_RVDC32(DSPABASE);
-				PSB_WVDC32(temp, DSPABASE);
-				PSB_RVDC32(DSPABASE);
-				temp =  PSB_RVDC32(DSPASURF);
-				PSB_WVDC32(temp, DSPASURF);
-				PSB_RVDC32(DSPASURF);
-			}
-			if (arg->subpicture_disable_mask & REGRWBITS_DSPBCNTR) {
-				temp =  PSB_RVDC32(DSPBCNTR);
-				temp &= ~DISPPLANE_PIXFORMAT_MASK;
-				temp |= DISPPLANE_32BPP_NO_ALPHA;
-				PSB_WVDC32(temp, DSPBCNTR);
-
-				temp =  PSB_RVDC32(DSPBBASE);
-				PSB_WVDC32(temp, DSPBBASE);
-				PSB_RVDC32(DSPBBASE);
-				temp =  PSB_RVDC32(DSPBSURF);
-				PSB_WVDC32(temp, DSPBSURF);
-				PSB_RVDC32(DSPBSURF);
-			}
-			if (arg->subpicture_disable_mask & REGRWBITS_DSPCCNTR) {
-				temp =  PSB_RVDC32(DSPCCNTR);
-				temp &= ~DISPPLANE_PIXFORMAT_MASK;
-				temp |= DISPPLANE_32BPP_NO_ALPHA;
-				PSB_WVDC32(temp, DSPCCNTR);
-
-				temp =  PSB_RVDC32(DSPCBASE);
-				PSB_WVDC32(temp, DSPCBASE);
-				PSB_RVDC32(DSPCBASE);
-				temp =  PSB_RVDC32(DSPCSURF);
-				PSB_WVDC32(temp, DSPCSURF);
-				PSB_RVDC32(DSPCSURF);
-			}
-			gma_power_end(dev);
-		}
-	}
-
-	return 0;
-}
-
-static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
-{
-	return 0;
-}
-
-static void psb_driver_close(struct drm_device *dev, struct drm_file *priv)
-{
-}
-
-static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
-			       unsigned long arg)
-{
-	struct drm_file *file_priv = filp->private_data;
-	struct drm_device *dev = file_priv->minor->dev;
-	int ret;
-	
-	pm_runtime_forbid(dev->dev);
-	ret = drm_ioctl(filp, cmd, arg);
-	pm_runtime_allow(dev->dev);
-	return ret;
-	/* FIXME: do we need to wrap the other side of this */
-}
-
-
-/* When a client dies:
- *    - Check for and clean up flipped page state
- */
-void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv)
-{
-}
-
-static void psb_remove(struct pci_dev *pdev)
-{
-	struct drm_device *dev = pci_get_drvdata(pdev);
-	drm_put_dev(dev);
-}
-
-static const struct dev_pm_ops psb_pm_ops = {
-	.suspend = gma_power_suspend,
-	.resume = gma_power_resume,
-	.freeze = gma_power_suspend,
-	.thaw = gma_power_resume,
-	.poweroff = gma_power_suspend,
-	.restore = gma_power_resume,
-	.runtime_suspend = psb_runtime_suspend,
-	.runtime_resume = psb_runtime_resume,
-	.runtime_idle = psb_runtime_idle,
-};
-
-static struct vm_operations_struct psb_gem_vm_ops = {
-	.fault = psb_gem_fault,
-	.open = drm_gem_vm_open,
-	.close = drm_gem_vm_close,
-};
-
-static const struct file_operations gma500_driver_fops = {
-	.owner = THIS_MODULE,
-	.open = drm_open,
-	.release = drm_release,
-	.unlocked_ioctl = psb_unlocked_ioctl,
-	.mmap = drm_gem_mmap,
-	.poll = drm_poll,
-	.fasync = drm_fasync,
-	.read = drm_read,
-};
-
-static struct drm_driver driver = {
-	.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
-			   DRIVER_IRQ_VBL | DRIVER_MODESET | DRIVER_GEM ,
-	.load = psb_driver_load,
-	.unload = psb_driver_unload,
-
-	.ioctls = psb_ioctls,
-	.num_ioctls = DRM_ARRAY_SIZE(psb_ioctls),
-	.device_is_agp = psb_driver_device_is_agp,
-	.irq_preinstall = psb_irq_preinstall,
-	.irq_postinstall = psb_irq_postinstall,
-	.irq_uninstall = psb_irq_uninstall,
-	.irq_handler = psb_irq_handler,
-	.enable_vblank = psb_enable_vblank,
-	.disable_vblank = psb_disable_vblank,
-	.get_vblank_counter = psb_get_vblank_counter,
-	.lastclose = psb_lastclose,
-	.open = psb_driver_open,
-	.preclose = psb_driver_preclose,
-	.postclose = psb_driver_close,
-	.reclaim_buffers = drm_core_reclaim_buffers,
-
-	.gem_init_object = psb_gem_init_object,
-	.gem_free_object = psb_gem_free_object,
-	.gem_vm_ops = &psb_gem_vm_ops,
-	.dumb_create = psb_gem_dumb_create,
-	.dumb_map_offset = psb_gem_dumb_map_gtt,
-	.dumb_destroy = psb_gem_dumb_destroy,
-	.fops = &gma500_driver_fops,
-	.name = DRIVER_NAME,
-	.desc = DRIVER_DESC,
-	.date = PSB_DRM_DRIVER_DATE,
-	.major = PSB_DRM_DRIVER_MAJOR,
-	.minor = PSB_DRM_DRIVER_MINOR,
-	.patchlevel = PSB_DRM_DRIVER_PATCHLEVEL
-};
-
-static struct pci_driver psb_pci_driver = {
-	.name = DRIVER_NAME,
-	.id_table = pciidlist,
-	.probe = psb_probe,
-	.remove = psb_remove,
-	.driver.pm = &psb_pm_ops,
-};
-
-static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	return drm_get_pci_dev(pdev, ent, &driver);
-}
-
-static int __init psb_init(void)
-{
-	return drm_pci_init(&driver, &psb_pci_driver);
-}
-
-static void __exit psb_exit(void)
-{
-	drm_pci_exit(&driver, &psb_pci_driver);
-}
-
-late_initcall(psb_init);
-module_exit(psb_exit);
-
-MODULE_AUTHOR("Alan Cox <alan@linux.intel.com> and others");
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
deleted file mode 100644
index 11d963a..0000000
--- a/drivers/staging/gma500/psb_drv.h
+++ /dev/null
@@ -1,952 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#ifndef _PSB_DRV_H_
-#define _PSB_DRV_H_
-
-#include <linux/kref.h>
-
-#include <drm/drmP.h>
-#include "drm_global.h"
-#include "gem_glue.h"
-#include "psb_drm.h"
-#include "psb_reg.h"
-#include "psb_intel_drv.h"
-#include "gtt.h"
-#include "power.h"
-#include "mrst.h"
-#include "medfield.h"
-
-/* Append new drm mode definition here, align with libdrm definition */
-#define DRM_MODE_SCALE_NO_SCALE   	2
-
-enum {
-	CHIP_PSB_8108 = 0,		/* Poulsbo */
-	CHIP_PSB_8109 = 1,		/* Poulsbo */
-	CHIP_MRST_4100 = 2,		/* Moorestown/Oaktrail */
-	CHIP_MFLD_0130 = 3,		/* Medfield */
-};
-
-#define IS_PSB(dev) (((dev)->pci_device & 0xfffe) == 0x8108)
-#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
-#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130)
-
-/*
- * Driver definitions
- */
-
-#define DRIVER_NAME "gma500"
-#define DRIVER_DESC "DRM driver for the Intel GMA500"
-
-#define PSB_DRM_DRIVER_DATE "2011-06-06"
-#define PSB_DRM_DRIVER_MAJOR 1
-#define PSB_DRM_DRIVER_MINOR 0
-#define PSB_DRM_DRIVER_PATCHLEVEL 0
-
-/*
- *	Hardware offsets
- */
-#define PSB_VDC_OFFSET		 0x00000000
-#define PSB_VDC_SIZE		 0x000080000
-#define MRST_MMIO_SIZE		 0x0000C0000
-#define MDFLD_MMIO_SIZE          0x000100000
-#define PSB_SGX_SIZE		 0x8000
-#define PSB_SGX_OFFSET		 0x00040000
-#define MRST_SGX_OFFSET		 0x00080000
-/*
- *	PCI resource identifiers
- */
-#define PSB_MMIO_RESOURCE	 0
-#define PSB_GATT_RESOURCE	 2
-#define PSB_GTT_RESOURCE	 3
-/*
- *	PCI configuration
- */
-#define PSB_GMCH_CTRL		 0x52
-#define PSB_BSM			 0x5C
-#define _PSB_GMCH_ENABLED	 0x4
-#define PSB_PGETBL_CTL		 0x2020
-#define _PSB_PGETBL_ENABLED	 0x00000001
-#define PSB_SGX_2D_SLAVE_PORT	 0x4000
-
-/* To get rid of */
-#define PSB_TT_PRIV0_LIMIT	 (256*1024*1024)
-#define PSB_TT_PRIV0_PLIMIT	 (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
-
-/*
- *	SGX side MMU definitions (these can probably go)
- */
-
-/*
- *	Flags for external memory type field.
- */
-#define PSB_MMU_CACHED_MEMORY	  0x0001	/* Bind to MMU only */
-#define PSB_MMU_RO_MEMORY	  0x0002	/* MMU RO memory */
-#define PSB_MMU_WO_MEMORY	  0x0004	/* MMU WO memory */
-/*
- *	PTE's and PDE's
- */
-#define PSB_PDE_MASK		  0x003FFFFF
-#define PSB_PDE_SHIFT		  22
-#define PSB_PTE_SHIFT		  12
-/*
- *	Cache control
- */
-#define PSB_PTE_VALID		  0x0001	/* PTE / PDE valid */
-#define PSB_PTE_WO		  0x0002	/* Write only */
-#define PSB_PTE_RO		  0x0004	/* Read only */
-#define PSB_PTE_CACHED		  0x0008	/* CPU cache coherent */
-
-/*
- *	VDC registers and bits
- */
-#define PSB_MSVDX_CLOCKGATING	  0x2064
-#define PSB_TOPAZ_CLOCKGATING	  0x2068
-#define PSB_HWSTAM		  0x2098
-#define PSB_INSTPM		  0x20C0
-#define PSB_INT_IDENTITY_R        0x20A4
-#define _MDFLD_PIPEC_EVENT_FLAG   (1<<2)
-#define _MDFLD_PIPEC_VBLANK_FLAG  (1<<3)
-#define _PSB_DPST_PIPEB_FLAG      (1<<4)
-#define _MDFLD_PIPEB_EVENT_FLAG   (1<<4)
-#define _PSB_VSYNC_PIPEB_FLAG	  (1<<5)
-#define _PSB_DPST_PIPEA_FLAG      (1<<6)
-#define _PSB_PIPEA_EVENT_FLAG     (1<<6)
-#define _PSB_VSYNC_PIPEA_FLAG	  (1<<7)
-#define _MDFLD_MIPIA_FLAG	  (1<<16)
-#define _MDFLD_MIPIC_FLAG	  (1<<17)
-#define _PSB_IRQ_SGX_FLAG	  (1<<18)
-#define _PSB_IRQ_MSVDX_FLAG	  (1<<19)
-#define _LNC_IRQ_TOPAZ_FLAG	  (1<<20)
-
-#define _PSB_PIPE_EVENT_FLAG	(_PSB_VSYNC_PIPEA_FLAG | \
-				 _PSB_VSYNC_PIPEB_FLAG)
-
-/* This flag includes all the display IRQ bits excepts the vblank irqs. */
-#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \
-				  _MDFLD_PIPEB_EVENT_FLAG | \
-				  _PSB_PIPEA_EVENT_FLAG | \
-				  _PSB_VSYNC_PIPEA_FLAG | \
-				  _MDFLD_MIPIA_FLAG | \
-				  _MDFLD_MIPIC_FLAG)
-#define PSB_INT_IDENTITY_R	  0x20A4
-#define PSB_INT_MASK_R		  0x20A8
-#define PSB_INT_ENABLE_R	  0x20A0
-
-#define _PSB_MMU_ER_MASK      0x0001FF00
-#define _PSB_MMU_ER_HOST      (1 << 16)
-#define GPIOA			0x5010
-#define GPIOB			0x5014
-#define GPIOC			0x5018
-#define GPIOD			0x501c
-#define GPIOE			0x5020
-#define GPIOF			0x5024
-#define GPIOG			0x5028
-#define GPIOH			0x502c
-#define GPIO_CLOCK_DIR_MASK		(1 << 0)
-#define GPIO_CLOCK_DIR_IN		(0 << 1)
-#define GPIO_CLOCK_DIR_OUT		(1 << 1)
-#define GPIO_CLOCK_VAL_MASK		(1 << 2)
-#define GPIO_CLOCK_VAL_OUT		(1 << 3)
-#define GPIO_CLOCK_VAL_IN		(1 << 4)
-#define GPIO_CLOCK_PULLUP_DISABLE	(1 << 5)
-#define GPIO_DATA_DIR_MASK		(1 << 8)
-#define GPIO_DATA_DIR_IN		(0 << 9)
-#define GPIO_DATA_DIR_OUT		(1 << 9)
-#define GPIO_DATA_VAL_MASK		(1 << 10)
-#define GPIO_DATA_VAL_OUT		(1 << 11)
-#define GPIO_DATA_VAL_IN		(1 << 12)
-#define GPIO_DATA_PULLUP_DISABLE	(1 << 13)
-
-#define VCLK_DIVISOR_VGA0   0x6000
-#define VCLK_DIVISOR_VGA1   0x6004
-#define VCLK_POST_DIV	    0x6010
-
-#define PSB_COMM_2D (PSB_ENGINE_2D << 4)
-#define PSB_COMM_3D (PSB_ENGINE_3D << 4)
-#define PSB_COMM_TA (PSB_ENGINE_TA << 4)
-#define PSB_COMM_HP (PSB_ENGINE_HP << 4)
-#define PSB_COMM_USER_IRQ (1024 >> 2)
-#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1)
-#define PSB_COMM_FW (2048 >> 2)
-
-#define PSB_UIRQ_VISTEST	       1
-#define PSB_UIRQ_OOM_REPLY	       2
-#define PSB_UIRQ_FIRE_TA_REPLY	       3
-#define PSB_UIRQ_FIRE_RASTER_REPLY     4
-
-#define PSB_2D_SIZE (256*1024*1024)
-#define PSB_MAX_RELOC_PAGES 1024
-
-#define PSB_LOW_REG_OFFS 0x0204
-#define PSB_HIGH_REG_OFFS 0x0600
-
-#define PSB_NUM_VBLANKS 2
-
-
-#define PSB_2D_SIZE (256*1024*1024)
-#define PSB_MAX_RELOC_PAGES 1024
-
-#define PSB_LOW_REG_OFFS 0x0204
-#define PSB_HIGH_REG_OFFS 0x0600
-
-#define PSB_NUM_VBLANKS 2
-#define PSB_WATCHDOG_DELAY (DRM_HZ * 2)
-#define PSB_LID_DELAY (DRM_HZ / 10)
-
-#define MDFLD_PNW_B0 0x04
-#define MDFLD_PNW_C0 0x08
-
-#define MDFLD_DSR_2D_3D_0 	(1 << 0)
-#define MDFLD_DSR_2D_3D_2 	(1 << 1)
-#define MDFLD_DSR_CURSOR_0 	(1 << 2)
-#define MDFLD_DSR_CURSOR_2	(1 << 3)
-#define MDFLD_DSR_OVERLAY_0 	(1 << 4)
-#define MDFLD_DSR_OVERLAY_2 	(1 << 5)
-#define MDFLD_DSR_MIPI_CONTROL	(1 << 6)
-#define MDFLD_DSR_DAMAGE_MASK_0	((1 << 0) | (1 << 2) | (1 << 4))
-#define MDFLD_DSR_DAMAGE_MASK_2	((1 << 1) | (1 << 3) | (1 << 5))
-#define MDFLD_DSR_2D_3D 	(MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2)
-
-#define MDFLD_DSR_RR		45
-#define MDFLD_DPU_ENABLE 	(1 << 31)
-#define MDFLD_DSR_FULLSCREEN 	(1 << 30)
-#define MDFLD_DSR_DELAY		(DRM_HZ / MDFLD_DSR_RR)
-
-#define PSB_PWR_STATE_ON		1
-#define PSB_PWR_STATE_OFF		2
-
-#define PSB_PMPOLICY_NOPM		0
-#define PSB_PMPOLICY_CLOCKGATING	1
-#define PSB_PMPOLICY_POWERDOWN		2
-
-#define PSB_PMSTATE_POWERUP		0
-#define PSB_PMSTATE_CLOCKGATED		1
-#define PSB_PMSTATE_POWERDOWN		2
-#define PSB_PCIx_MSI_ADDR_LOC		0x94
-#define PSB_PCIx_MSI_DATA_LOC		0x98
-
-/* Medfield crystal settings */
-#define KSEL_CRYSTAL_19 1
-#define KSEL_BYPASS_19 5
-#define KSEL_BYPASS_25 6
-#define KSEL_BYPASS_83_100 7
-
-struct opregion_header;
-struct opregion_acpi;
-struct opregion_swsci;
-struct opregion_asle;
-
-struct psb_intel_opregion {
-	struct opregion_header *header;
-	struct opregion_acpi *acpi;
-	struct opregion_swsci *swsci;
-	struct opregion_asle *asle;
-	int enabled;
-};
-
-struct psb_ops;
-
-struct drm_psb_private {
-	struct drm_device *dev;
-	const struct psb_ops *ops;
-
-	struct psb_gtt gtt;
-
-	/* GTT Memory manager */
-	struct psb_gtt_mm *gtt_mm;
-	struct page *scratch_page;
-	u32 *gtt_map;
-	uint32_t stolen_base;
-	void *vram_addr;
-	unsigned long vram_stolen_size;
-	int gtt_initialized;
-	u16 gmch_ctrl;		/* Saved GTT setup */
-	u32 pge_ctl;
-
-	struct mutex gtt_mutex;
-	struct resource *gtt_mem;	/* Our PCI resource */
-
-	struct psb_mmu_driver *mmu;
-	struct psb_mmu_pd *pf_pd;
-
-	/*
-	 * Register base
-	 */
-
-	uint8_t *sgx_reg;
-	uint8_t *vdc_reg;
-	uint32_t gatt_free_offset;
-
-	/*
-	 * Fencing / irq.
-	 */
-
-	uint32_t vdc_irq_mask;
-	uint32_t pipestat[PSB_NUM_PIPE];
-
-	spinlock_t irqmask_lock;
-
-	/*
-	 * Power
-	 */
-
-	bool suspended;
-	bool display_power;
-	int display_count;
-
-	/*
-	 * Modesetting
-	 */
-	struct psb_intel_mode_device mode_dev;
-
-	struct drm_crtc *plane_to_crtc_mapping[PSB_NUM_PIPE];
-	struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE];
-	uint32_t num_pipe;
-
-	/*
-	 * OSPM info (Power management base) (can go ?)
-	 */
-	uint32_t ospm_base;
-
-	/*
-	 * Sizes info
-	 */
-
-	struct drm_psb_sizes_arg sizes;
-
-	u32 fuse_reg_value;
-	u32 video_device_fuse;
-
-	/* PCI revision ID for B0:D2:F0 */
-	uint8_t platform_rev_id;
-
-	/*
-	 * LVDS info
-	 */
-	int backlight_duty_cycle;	/* restore backlight to this value */
-	bool panel_wants_dither;
-	struct drm_display_mode *panel_fixed_mode;
-	struct drm_display_mode *lfp_lvds_vbt_mode;
-	struct drm_display_mode *sdvo_lvds_vbt_mode;
-
-	struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */
-	struct psb_intel_i2c_chan *lvds_i2c_bus;
-
-	/* Feature bits from the VBIOS */
-	unsigned int int_tv_support:1;
-	unsigned int lvds_dither:1;
-	unsigned int lvds_vbt:1;
-	unsigned int int_crt_support:1;
-	unsigned int lvds_use_ssc:1;
-	int lvds_ssc_freq;
-	bool is_lvds_on;
-	bool is_mipi_on;
-	u32 mipi_ctrl_display;
-
-	unsigned int core_freq;
-	uint32_t iLVDS_enable;
-
-	/* Runtime PM state */
-	int rpm_enabled;
-
-	/* MID specific */
-	struct mrst_vbt vbt_data;
-	struct mrst_gct_data gct_data;
-
-	/* MIPI Panel type etc */
-	int panel_id;
-	bool dual_mipi;		/* dual display - DPI & DBI */
-	bool dpi_panel_on;	/* The DPI panel power is on */
-	bool dpi_panel_on2;	/* The DPI panel power is on */
-	bool dbi_panel_on;	/* The DBI panel power is on */
-	bool dbi_panel_on2;	/* The DBI panel power is on */
-	u32 dsr_fb_update;	/* DSR FB update counter */
-
-	/* Moorestown HDMI state */
-	struct mrst_hdmi_dev *hdmi_priv;
-
-	/* Moorestown pipe config register value cache */
-	uint32_t pipeconf;
-	uint32_t pipeconf1;
-	uint32_t pipeconf2;
-
-	/* Moorestown plane control register value cache */
-	uint32_t dspcntr;
-	uint32_t dspcntr1;
-	uint32_t dspcntr2;
-
-	/* Moorestown MM backlight cache */
-	uint8_t saveBKLTCNT;
-	uint8_t saveBKLTREQ;
-	uint8_t saveBKLTBRTL;
-
-	/*
-	 * Register state
-	 */
-	uint32_t saveDSPACNTR;
-	uint32_t saveDSPBCNTR;
-	uint32_t savePIPEACONF;
-	uint32_t savePIPEBCONF;
-	uint32_t savePIPEASRC;
-	uint32_t savePIPEBSRC;
-	uint32_t saveFPA0;
-	uint32_t saveFPA1;
-	uint32_t saveDPLL_A;
-	uint32_t saveDPLL_A_MD;
-	uint32_t saveHTOTAL_A;
-	uint32_t saveHBLANK_A;
-	uint32_t saveHSYNC_A;
-	uint32_t saveVTOTAL_A;
-	uint32_t saveVBLANK_A;
-	uint32_t saveVSYNC_A;
-	uint32_t saveDSPASTRIDE;
-	uint32_t saveDSPASIZE;
-	uint32_t saveDSPAPOS;
-	uint32_t saveDSPABASE;
-	uint32_t saveDSPASURF;
-	uint32_t saveDSPASTATUS;
-	uint32_t saveFPB0;
-	uint32_t saveFPB1;
-	uint32_t saveDPLL_B;
-	uint32_t saveDPLL_B_MD;
-	uint32_t saveHTOTAL_B;
-	uint32_t saveHBLANK_B;
-	uint32_t saveHSYNC_B;
-	uint32_t saveVTOTAL_B;
-	uint32_t saveVBLANK_B;
-	uint32_t saveVSYNC_B;
-	uint32_t saveDSPBSTRIDE;
-	uint32_t saveDSPBSIZE;
-	uint32_t saveDSPBPOS;
-	uint32_t saveDSPBBASE;
-	uint32_t saveDSPBSURF;
-	uint32_t saveDSPBSTATUS;
-	uint32_t saveVCLK_DIVISOR_VGA0;
-	uint32_t saveVCLK_DIVISOR_VGA1;
-	uint32_t saveVCLK_POST_DIV;
-	uint32_t saveVGACNTRL;
-	uint32_t saveADPA;
-	uint32_t saveLVDS;
-	uint32_t saveDVOA;
-	uint32_t saveDVOB;
-	uint32_t saveDVOC;
-	uint32_t savePP_ON;
-	uint32_t savePP_OFF;
-	uint32_t savePP_CONTROL;
-	uint32_t savePP_CYCLE;
-	uint32_t savePFIT_CONTROL;
-	uint32_t savePaletteA[256];
-	uint32_t savePaletteB[256];
-	uint32_t saveBLC_PWM_CTL2;
-	uint32_t saveBLC_PWM_CTL;
-	uint32_t saveCLOCKGATING;
-	uint32_t saveDSPARB;
-	uint32_t saveDSPATILEOFF;
-	uint32_t saveDSPBTILEOFF;
-	uint32_t saveDSPAADDR;
-	uint32_t saveDSPBADDR;
-	uint32_t savePFIT_AUTO_RATIOS;
-	uint32_t savePFIT_PGM_RATIOS;
-	uint32_t savePP_ON_DELAYS;
-	uint32_t savePP_OFF_DELAYS;
-	uint32_t savePP_DIVISOR;
-	uint32_t saveBSM;
-	uint32_t saveVBT;
-	uint32_t saveBCLRPAT_A;
-	uint32_t saveBCLRPAT_B;
-	uint32_t saveDSPALINOFF;
-	uint32_t saveDSPBLINOFF;
-	uint32_t savePERF_MODE;
-	uint32_t saveDSPFW1;
-	uint32_t saveDSPFW2;
-	uint32_t saveDSPFW3;
-	uint32_t saveDSPFW4;
-	uint32_t saveDSPFW5;
-	uint32_t saveDSPFW6;
-	uint32_t saveCHICKENBIT;
-	uint32_t saveDSPACURSOR_CTRL;
-	uint32_t saveDSPBCURSOR_CTRL;
-	uint32_t saveDSPACURSOR_BASE;
-	uint32_t saveDSPBCURSOR_BASE;
-	uint32_t saveDSPACURSOR_POS;
-	uint32_t saveDSPBCURSOR_POS;
-	uint32_t save_palette_a[256];
-	uint32_t save_palette_b[256];
-	uint32_t saveOV_OVADD;
-	uint32_t saveOV_OGAMC0;
-	uint32_t saveOV_OGAMC1;
-	uint32_t saveOV_OGAMC2;
-	uint32_t saveOV_OGAMC3;
-	uint32_t saveOV_OGAMC4;
-	uint32_t saveOV_OGAMC5;
-	uint32_t saveOVC_OVADD;
-	uint32_t saveOVC_OGAMC0;
-	uint32_t saveOVC_OGAMC1;
-	uint32_t saveOVC_OGAMC2;
-	uint32_t saveOVC_OGAMC3;
-	uint32_t saveOVC_OGAMC4;
-	uint32_t saveOVC_OGAMC5;
-
-	/* MSI reg save */
-	uint32_t msi_addr;
-	uint32_t msi_data;
-
-	/* Medfield specific register save state */
-	uint32_t saveHDMIPHYMISCCTL;
-	uint32_t saveHDMIB_CONTROL;
-	uint32_t saveDSPCCNTR;
-	uint32_t savePIPECCONF;
-	uint32_t savePIPECSRC;
-	uint32_t saveHTOTAL_C;
-	uint32_t saveHBLANK_C;
-	uint32_t saveHSYNC_C;
-	uint32_t saveVTOTAL_C;
-	uint32_t saveVBLANK_C;
-	uint32_t saveVSYNC_C;
-	uint32_t saveDSPCSTRIDE;
-	uint32_t saveDSPCSIZE;
-	uint32_t saveDSPCPOS;
-	uint32_t saveDSPCSURF;
-	uint32_t saveDSPCSTATUS;
-	uint32_t saveDSPCLINOFF;
-	uint32_t saveDSPCTILEOFF;
-	uint32_t saveDSPCCURSOR_CTRL;
-	uint32_t saveDSPCCURSOR_BASE;
-	uint32_t saveDSPCCURSOR_POS;
-	uint32_t save_palette_c[256];
-	uint32_t saveOV_OVADD_C;
-	uint32_t saveOV_OGAMC0_C;
-	uint32_t saveOV_OGAMC1_C;
-	uint32_t saveOV_OGAMC2_C;
-	uint32_t saveOV_OGAMC3_C;
-	uint32_t saveOV_OGAMC4_C;
-	uint32_t saveOV_OGAMC5_C;
-
-	/* DSI register save */
-	uint32_t saveDEVICE_READY_REG;
-	uint32_t saveINTR_EN_REG;
-	uint32_t saveDSI_FUNC_PRG_REG;
-	uint32_t saveHS_TX_TIMEOUT_REG;
-	uint32_t saveLP_RX_TIMEOUT_REG;
-	uint32_t saveTURN_AROUND_TIMEOUT_REG;
-	uint32_t saveDEVICE_RESET_REG;
-	uint32_t saveDPI_RESOLUTION_REG;
-	uint32_t saveHORIZ_SYNC_PAD_COUNT_REG;
-	uint32_t saveHORIZ_BACK_PORCH_COUNT_REG;
-	uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG;
-	uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG;
-	uint32_t saveVERT_SYNC_PAD_COUNT_REG;
-	uint32_t saveVERT_BACK_PORCH_COUNT_REG;
-	uint32_t saveVERT_FRONT_PORCH_COUNT_REG;
-	uint32_t saveHIGH_LOW_SWITCH_COUNT_REG;
-	uint32_t saveINIT_COUNT_REG;
-	uint32_t saveMAX_RET_PAK_REG;
-	uint32_t saveVIDEO_FMT_REG;
-	uint32_t saveEOT_DISABLE_REG;
-	uint32_t saveLP_BYTECLK_REG;
-	uint32_t saveHS_LS_DBI_ENABLE_REG;
-	uint32_t saveTXCLKESC_REG;
-	uint32_t saveDPHY_PARAM_REG;
-	uint32_t saveMIPI_CONTROL_REG;
-	uint32_t saveMIPI;
-	uint32_t saveMIPI_C;
-
-	/* DPST register save */
-	uint32_t saveHISTOGRAM_INT_CONTROL_REG;
-	uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
-	uint32_t savePWM_CONTROL_LOGIC;
-
-	/*
-	 * DSI info. 
-	 */
-	void * dbi_dsr_info;	
-	void * dbi_dpu_info;
-	void * dsi_configs[2];
-	/*
-	 * LID-Switch
-	 */
-	spinlock_t lid_lock;
-	struct timer_list lid_timer;
-	struct psb_intel_opregion opregion;
-	u32 *lid_state;
-	u32 lid_last_state;
-
-	/*
-	 * Watchdog
-	 */
-
-	uint32_t apm_reg;
-	uint16_t apm_base;
-
-	/*
-	 * Used for modifying backlight from
-	 * xrandr -- consider removing and using HAL instead
-	 */
-	struct backlight_device *backlight_device;
-	struct drm_property *backlight_property;
-	uint32_t blc_adj1;
-	uint32_t blc_adj2;
-
-	void *fbdev;
-	/* DPST state */
-	uint32_t dsr_idle_count;
-	bool is_in_idle;
-	bool dsr_enable;
-	void (*exit_idle)(struct drm_device *dev, u32 update_src);
-
-	/* 2D acceleration */
-	spinlock_t lock_2d;
-
-	/* FIXME: Arrays anyone ? */
-	struct mdfld_dsi_encoder *encoder0;	
-	struct mdfld_dsi_encoder *encoder2;	
-	struct mdfld_dsi_dbi_output * dbi_output;
-	struct mdfld_dsi_dbi_output * dbi_output2;
-	u32 bpp;
-	u32 bpp2;
-	
-	bool dispstatus;
-};
-
-
-/*
- *	Operations for each board type
- */
- 
-struct psb_ops {
-	const char *name;
-	unsigned int accel_2d:1;
-	int pipes;		/* Number of output pipes */
-	int crtcs;		/* Number of CRTCs */
-	int sgx_offset;		/* Base offset of SGX device */
-
-	/* Sub functions */
-	struct drm_crtc_helper_funcs const *crtc_helper;
-	struct drm_crtc_funcs const *crtc_funcs;
-
-	/* Setup hooks */
-	int (*chip_setup)(struct drm_device *dev);
-	void (*chip_teardown)(struct drm_device *dev);
-
-	/* Display management hooks */
-	int (*output_init)(struct drm_device *dev);
-	/* Power management hooks */
-	void (*init_pm)(struct drm_device *dev);
-	int (*save_regs)(struct drm_device *dev);
-	int (*restore_regs)(struct drm_device *dev);
-	int (*power_up)(struct drm_device *dev);
-	int (*power_down)(struct drm_device *dev);
-
-	void (*lvds_bl_power)(struct drm_device *dev, bool on);
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	/* Backlight */
-	int (*backlight_init)(struct drm_device *dev);
-#endif
-	int i2c_bus;		/* I2C bus identifier for Moorestown */
-};
-
-
-
-struct psb_mmu_driver;
-
-extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int);
-extern int drm_pick_crtcs(struct drm_device *dev);
-
-static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
-{
-	return (struct drm_psb_private *) dev->dev_private;
-}
-
-/*
- * MMU stuff.
- */
-
-extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
-					int trap_pagefaults,
-					int invalid_type,
-					struct drm_psb_private *dev_priv);
-extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver);
-extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver
-						 *driver);
-extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset,
-			       uint32_t gtt_start, uint32_t gtt_pages);
-extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver,
-					   int trap_pagefaults,
-					   int invalid_type);
-extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd);
-extern void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot);
-extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd,
-					unsigned long address,
-					uint32_t num_pages);
-extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd,
-				       uint32_t start_pfn,
-				       unsigned long address,
-				       uint32_t num_pages, int type);
-extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
-				  unsigned long *pfn);
-
-/*
- * Enable / disable MMU for different requestors.
- */
-
-
-extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context);
-extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages,
-				unsigned long address, uint32_t num_pages,
-				uint32_t desired_tile_stride,
-				uint32_t hw_tile_stride, int type);
-extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd,
-				 unsigned long address, uint32_t num_pages,
-				 uint32_t desired_tile_stride,
-				 uint32_t hw_tile_stride);
-/*
- *psb_irq.c
- */
-
-extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
-extern int psb_irq_enable_dpst(struct drm_device *dev);
-extern int psb_irq_disable_dpst(struct drm_device *dev);
-extern void psb_irq_preinstall(struct drm_device *dev);
-extern int psb_irq_postinstall(struct drm_device *dev);
-extern void psb_irq_uninstall(struct drm_device *dev);
-extern void psb_irq_turn_on_dpst(struct drm_device *dev);
-extern void psb_irq_turn_off_dpst(struct drm_device *dev);
-
-extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
-extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
-extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
-extern int psb_enable_vblank(struct drm_device *dev, int crtc);
-extern void psb_disable_vblank(struct drm_device *dev, int crtc);
-void
-psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
-
-void
-psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);
-
-extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc);
-
-extern int mdfld_enable_te(struct drm_device *dev, int pipe);
-extern void mdfld_disable_te(struct drm_device *dev, int pipe);
-
-/*
- * intel_opregion.c
- */
-extern int gma_intel_opregion_init(struct drm_device *dev);
-extern int gma_intel_opregion_exit(struct drm_device *dev);
-
-/*
- * framebuffer.c
- */
-extern int psbfb_probed(struct drm_device *dev);
-extern int psbfb_remove(struct drm_device *dev,
-			struct drm_framebuffer *fb);
-/*
- * accel_2d.c
- */
-extern void psbfb_copyarea(struct fb_info *info,
-					const struct fb_copyarea *region);
-extern int psbfb_sync(struct fb_info *info);
-extern void psb_spank(struct drm_psb_private *dev_priv);
-extern int psb_accel_ioctl(struct drm_device *dev, void *data,
-							struct drm_file *file);
-
-/*
- * psb_reset.c
- */
-
-extern void psb_lid_timer_init(struct drm_psb_private *dev_priv);
-extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv);
-extern void psb_print_pagefault(struct drm_psb_private *dev_priv);
-
-/* modesetting */
-extern void psb_modeset_init(struct drm_device *dev);
-extern void psb_modeset_cleanup(struct drm_device *dev);
-extern int psb_fbdev_init(struct drm_device *dev);
-
-/* backlight.c */
-int gma_backlight_init(struct drm_device *dev);
-void gma_backlight_exit(struct drm_device *dev);
-
-/* mrst_crtc.c */
-extern const struct drm_crtc_helper_funcs mrst_helper_funcs;
-
-/* mrst_lvds.c */
-extern void mrst_lvds_init(struct drm_device *dev,
-		    struct psb_intel_mode_device *mode_dev);
-
-/* psb_intel_display.c */
-extern const struct drm_crtc_helper_funcs psb_intel_helper_funcs;
-extern const struct drm_crtc_funcs psb_intel_crtc_funcs;
-
-/* psb_intel_lvds.c */
-extern const struct drm_connector_helper_funcs
-					psb_intel_lvds_connector_helper_funcs;
-extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs;
-
-/* gem.c */
-extern int psb_gem_init_object(struct drm_gem_object *obj);
-extern void psb_gem_free_object(struct drm_gem_object *obj);
-extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
-			struct drm_file *file);
-extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
-			struct drm_mode_create_dumb *args);
-extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
-			uint32_t handle);
-extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
-			uint32_t handle, uint64_t *offset);
-extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
-extern int psb_gem_create_ioctl(struct drm_device *dev, void *data,
-			struct drm_file *file);
-extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
-					struct drm_file *file);
-
-/* psb_device.c */
-extern const struct psb_ops psb_chip_ops;
-
-/* mrst_device.c */
-extern const struct psb_ops mrst_chip_ops;
-
-/* mdfld_device.c */
-extern const struct psb_ops mdfld_chip_ops;
-
-/* cdv_device.c */
-extern const struct psb_ops cdv_chip_ops;
-
-/*
- * Debug print bits setting
- */
-#define PSB_D_GENERAL (1 << 0)
-#define PSB_D_INIT    (1 << 1)
-#define PSB_D_IRQ     (1 << 2)
-#define PSB_D_ENTRY   (1 << 3)
-/* debug the get H/V BP/FP count */
-#define PSB_D_HV      (1 << 4)
-#define PSB_D_DBI_BF  (1 << 5)
-#define PSB_D_PM      (1 << 6)
-#define PSB_D_RENDER  (1 << 7)
-#define PSB_D_REG     (1 << 8)
-#define PSB_D_MSVDX   (1 << 9)
-#define PSB_D_TOPAZ   (1 << 10)
-
-extern int drm_psb_no_fb;
-extern int drm_idle_check_interval;
-
-/*
- *	Utilities
- */
-
-static inline u32 MRST_MSG_READ32(uint port, uint offset)
-{
-	int mcr = (0xD0<<24) | (port << 16) | (offset << 8);
-	uint32_t ret_val = 0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	pci_write_config_dword(pci_root, 0xD0, mcr);
-	pci_read_config_dword(pci_root, 0xD4, &ret_val);
-	pci_dev_put(pci_root);
-	return ret_val;
-}
-static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value)
-{
-	int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	pci_write_config_dword(pci_root, 0xD4, value);
-	pci_write_config_dword(pci_root, 0xD0, mcr);
-	pci_dev_put(pci_root);
-}
-static inline u32 MDFLD_MSG_READ32(uint port, uint offset)
-{
-	int mcr = (0x10<<24) | (port << 16) | (offset << 8);
-	uint32_t ret_val = 0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	pci_write_config_dword(pci_root, 0xD0, mcr);
-	pci_read_config_dword(pci_root, 0xD4, &ret_val);
-	pci_dev_put(pci_root);
-	return ret_val;
-}
-static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)
-{
-	int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
-	pci_write_config_dword(pci_root, 0xD4, value);
-	pci_write_config_dword(pci_root, 0xD0, mcr);
-	pci_dev_put(pci_root);
-}
-
-static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	return ioread32(dev_priv->vdc_reg + reg);
-}
-
-#define REG_READ(reg)	       REGISTER_READ(dev, (reg))
-
-static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
-				      uint32_t val)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	iowrite32((val), dev_priv->vdc_reg + (reg));
-}
-
-#define REG_WRITE(reg, val)	REGISTER_WRITE(dev, (reg), (val))
-
-static inline void REGISTER_WRITE16(struct drm_device *dev,
-					uint32_t reg, uint32_t val)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	iowrite16((val), dev_priv->vdc_reg + (reg));
-}
-
-#define REG_WRITE16(reg, val)	  REGISTER_WRITE16(dev, (reg), (val))
-
-static inline void REGISTER_WRITE8(struct drm_device *dev,
-				       uint32_t reg, uint32_t val)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	iowrite8((val), dev_priv->vdc_reg + (reg));
-}
-
-#define REG_WRITE8(reg, val)		REGISTER_WRITE8(dev, (reg), (val))
-
-#define PSB_WVDC32(_val, _offs)		iowrite32(_val, dev_priv->vdc_reg + (_offs))
-#define PSB_RVDC32(_offs)		ioread32(dev_priv->vdc_reg + (_offs))
-
-/* #define TRAP_SGX_PM_FAULT 1 */
-#ifdef TRAP_SGX_PM_FAULT
-#define PSB_RSGX32(_offs)						\
-({									\
-	if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) {		\
-		printk(KERN_ERR						\
-			"access sgx when it's off!! (READ) %s, %d\n",	\
-	       __FILE__, __LINE__);					\
-		melay(1000);						\
-	}								\
-	ioread32(dev_priv->sgx_reg + (_offs));				\
-})
-#else
-#define PSB_RSGX32(_offs)		ioread32(dev_priv->sgx_reg + (_offs))
-#endif
-#define PSB_WSGX32(_val, _offs)		iowrite32(_val, dev_priv->sgx_reg + (_offs))
-
-#define MSVDX_REG_DUMP 0
-
-#define PSB_WMSVDX32(_val, _offs)	iowrite32(_val, dev_priv->msvdx_reg + (_offs))
-#define PSB_RMSVDX32(_offs)		ioread32(dev_priv->msvdx_reg + (_offs))
-
-#endif
diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
deleted file mode 100644
index 8565961..0000000
--- a/drivers/staging/gma500/psb_intel_display.c
+++ /dev/null
@@ -1,1429 +0,0 @@
-/*
- * Copyright © 2006-2011 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-
-#include <drm/drmP.h>
-#include "framebuffer.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_display.h"
-#include "power.h"
-
-#include "mdfld_output.h"
-
-struct psb_intel_clock_t {
-	/* given values */
-	int n;
-	int m1, m2;
-	int p1, p2;
-	/* derived values */
-	int dot;
-	int vco;
-	int m;
-	int p;
-};
-
-struct psb_intel_range_t {
-	int min, max;
-};
-
-struct psb_intel_p2_t {
-	int dot_limit;
-	int p2_slow, p2_fast;
-};
-
-#define INTEL_P2_NUM		      2
-
-struct psb_intel_limit_t {
-	struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1;
-	struct psb_intel_p2_t p2;
-};
-
-#define I8XX_DOT_MIN		  25000
-#define I8XX_DOT_MAX		 350000
-#define I8XX_VCO_MIN		 930000
-#define I8XX_VCO_MAX		1400000
-#define I8XX_N_MIN		      3
-#define I8XX_N_MAX		     16
-#define I8XX_M_MIN		     96
-#define I8XX_M_MAX		    140
-#define I8XX_M1_MIN		     18
-#define I8XX_M1_MAX		     26
-#define I8XX_M2_MIN		      6
-#define I8XX_M2_MAX		     16
-#define I8XX_P_MIN		      4
-#define I8XX_P_MAX		    128
-#define I8XX_P1_MIN		      2
-#define I8XX_P1_MAX		     33
-#define I8XX_P1_LVDS_MIN	      1
-#define I8XX_P1_LVDS_MAX	      6
-#define I8XX_P2_SLOW		      4
-#define I8XX_P2_FAST		      2
-#define I8XX_P2_LVDS_SLOW	      14
-#define I8XX_P2_LVDS_FAST	      14	/* No fast option */
-#define I8XX_P2_SLOW_LIMIT	 165000
-
-#define I9XX_DOT_MIN		  20000
-#define I9XX_DOT_MAX		 400000
-#define I9XX_VCO_MIN		1400000
-#define I9XX_VCO_MAX		2800000
-#define I9XX_N_MIN		      3
-#define I9XX_N_MAX		      8
-#define I9XX_M_MIN		     70
-#define I9XX_M_MAX		    120
-#define I9XX_M1_MIN		     10
-#define I9XX_M1_MAX		     20
-#define I9XX_M2_MIN		      5
-#define I9XX_M2_MAX		      9
-#define I9XX_P_SDVO_DAC_MIN	      5
-#define I9XX_P_SDVO_DAC_MAX	     80
-#define I9XX_P_LVDS_MIN		      7
-#define I9XX_P_LVDS_MAX		     98
-#define I9XX_P1_MIN		      1
-#define I9XX_P1_MAX		      8
-#define I9XX_P2_SDVO_DAC_SLOW		     10
-#define I9XX_P2_SDVO_DAC_FAST		      5
-#define I9XX_P2_SDVO_DAC_SLOW_LIMIT	 200000
-#define I9XX_P2_LVDS_SLOW		     14
-#define I9XX_P2_LVDS_FAST		      7
-#define I9XX_P2_LVDS_SLOW_LIMIT		 112000
-
-#define INTEL_LIMIT_I8XX_DVO_DAC    0
-#define INTEL_LIMIT_I8XX_LVDS	    1
-#define INTEL_LIMIT_I9XX_SDVO_DAC   2
-#define INTEL_LIMIT_I9XX_LVDS	    3
-
-static const struct psb_intel_limit_t psb_intel_limits[] = {
-	{			/* INTEL_LIMIT_I8XX_DVO_DAC */
-	 .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
-	 .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
-	 .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
-	 .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
-	 .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
-	 .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
-	 .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
-	 .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX},
-	 .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
-		.p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST},
-	 },
-	{			/* INTEL_LIMIT_I8XX_LVDS */
-	 .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
-	 .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
-	 .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
-	 .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
-	 .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
-	 .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
-	 .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
-	 .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX},
-	 .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
-		.p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST},
-	 },
-	{			/* INTEL_LIMIT_I9XX_SDVO_DAC */
-	 .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
-	 .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
-	 .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
-	 .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
-	 .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
-	 .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
-	 .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX},
-	 .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
-	 .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
-		.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast =
-		I9XX_P2_SDVO_DAC_FAST},
-	 },
-	{			/* INTEL_LIMIT_I9XX_LVDS */
-	 .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
-	 .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
-	 .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
-	 .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
-	 .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
-	 .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
-	 .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX},
-	 .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
-	 /* The single-channel range is 25-112Mhz, and dual-channel
-	  * is 80-224Mhz.  Prefer single channel as much as possible.
-	  */
-	 .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
-		.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST},
-	 },
-};
-
-static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc)
-{
-	const struct psb_intel_limit_t *limit;
-
-	if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
-		limit = &psb_intel_limits[INTEL_LIMIT_I9XX_LVDS];
-	else
-		limit = &psb_intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
-	return limit;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-
-static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
-{
-	clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
-	clock->p = clock->p1 * clock->p2;
-	clock->vco = refclk * clock->m / (clock->n + 2);
-	clock->dot = clock->vco / clock->p;
-}
-
-/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
-
-static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock)
-{
-	clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
-	clock->p = clock->p1 * clock->p2;
-	clock->vco = refclk * clock->m / (clock->n + 2);
-	clock->dot = clock->vco / clock->p;
-}
-
-static void psb_intel_clock(struct drm_device *dev, int refclk,
-			struct psb_intel_clock_t *clock)
-{
-	return i9xx_clock(refclk, clock);
-}
-
-/**
- * Returns whether any output on the specified pipe is of the specified type
- */
-bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_mode_config *mode_config = &dev->mode_config;
-	struct drm_connector *l_entry;
-
-	list_for_each_entry(l_entry, &mode_config->connector_list, head) {
-		if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
-			struct psb_intel_output *psb_intel_output =
-			    to_psb_intel_output(l_entry);
-			if (psb_intel_output->type == type)
-				return true;
-		}
-	}
-	return false;
-}
-
-#define INTELPllInvalid(s)   { /* ErrorF (s) */; return false; }
-/**
- * Returns whether the given set of divisors are valid for a given refclk with
- * the given connectors.
- */
-
-static bool psb_intel_PLL_is_valid(struct drm_crtc *crtc,
-			       struct psb_intel_clock_t *clock)
-{
-	const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
-
-	if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
-		INTELPllInvalid("p1 out of range\n");
-	if (clock->p < limit->p.min || limit->p.max < clock->p)
-		INTELPllInvalid("p out of range\n");
-	if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
-		INTELPllInvalid("m2 out of range\n");
-	if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
-		INTELPllInvalid("m1 out of range\n");
-	if (clock->m1 <= clock->m2)
-		INTELPllInvalid("m1 <= m2\n");
-	if (clock->m < limit->m.min || limit->m.max < clock->m)
-		INTELPllInvalid("m out of range\n");
-	if (clock->n < limit->n.min || limit->n.max < clock->n)
-		INTELPllInvalid("n out of range\n");
-	if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
-		INTELPllInvalid("vco out of range\n");
-	/* XXX: We may need to be checking "Dot clock"
-	 * depending on the multiplier, connector, etc.,
-	 * rather than just a single range.
-	 */
-	if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
-		INTELPllInvalid("dot out of range\n");
-
-	return true;
-}
-
-/**
- * Returns a set of divisors for the desired target clock with the given
- * refclk, or FALSE.  The returned values represent the clock equation:
- * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
- */
-static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target,
-				int refclk,
-				struct psb_intel_clock_t *best_clock)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_clock_t clock;
-	const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
-	int err = target;
-
-	if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
-	    (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
-		/*
-		 * For LVDS, if the panel is on, just rely on its current
-		 * settings for dual-channel.  We haven't figured out how to
-		 * reliably set up different single/dual channel state, if we
-		 * even can.
-		 */
-		if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
-		    LVDS_CLKB_POWER_UP)
-			clock.p2 = limit->p2.p2_fast;
-		else
-			clock.p2 = limit->p2.p2_slow;
-	} else {
-		if (target < limit->p2.dot_limit)
-			clock.p2 = limit->p2.p2_slow;
-		else
-			clock.p2 = limit->p2.p2_fast;
-	}
-
-	memset(best_clock, 0, sizeof(*best_clock));
-
-	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
-	     clock.m1++) {
-		for (clock.m2 = limit->m2.min;
-		     clock.m2 < clock.m1 && clock.m2 <= limit->m2.max;
-		     clock.m2++) {
-			for (clock.n = limit->n.min;
-			     clock.n <= limit->n.max; clock.n++) {
-				for (clock.p1 = limit->p1.min;
-				     clock.p1 <= limit->p1.max;
-				     clock.p1++) {
-					int this_err;
-
-					psb_intel_clock(dev, refclk, &clock);
-
-					if (!psb_intel_PLL_is_valid
-					    (crtc, &clock))
-						continue;
-
-					this_err = abs(clock.dot - target);
-					if (this_err < err) {
-						*best_clock = clock;
-						err = this_err;
-					}
-				}
-			}
-		}
-	}
-
-	return err != target;
-}
-
-void psb_intel_wait_for_vblank(struct drm_device *dev)
-{
-	/* Wait for 20ms, i.e. one cycle at 50hz. */
-	mdelay(20);
-}
-
-int psb_intel_pipe_set_base(struct drm_crtc *crtc,
-			    int x, int y, struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	/* struct drm_i915_master_private *master_priv; */
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-	int pipe = psb_intel_crtc->pipe;
-	unsigned long start, offset;
-	int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
-	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
-	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	u32 dspcntr;
-	int ret = 0;
-
-	if (!gma_power_begin(dev, true))
-		return 0;
-
-	/* no fb bound */
-	if (!crtc->fb) {
-		dev_dbg(dev->dev, "No FB bound\n");
-		goto psb_intel_pipe_cleaner;
-	}
-
-	/* We are displaying this buffer, make sure it is actually loaded
-	   into the GTT */
-	ret = psb_gtt_pin(psbfb->gtt);
-	if (ret < 0)
-		goto psb_intel_pipe_set_base_exit;
-	start = psbfb->gtt->offset;
-
-	offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
-
-	REG_WRITE(dspstride, crtc->fb->pitches[0]);
-
-	dspcntr = REG_READ(dspcntr_reg);
-	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
-
-	switch (crtc->fb->bits_per_pixel) {
-	case 8:
-		dspcntr |= DISPPLANE_8BPP;
-		break;
-	case 16:
-		if (crtc->fb->depth == 15)
-			dspcntr |= DISPPLANE_15_16BPP;
-		else
-			dspcntr |= DISPPLANE_16BPP;
-		break;
-	case 24:
-	case 32:
-		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-		break;
-	default:
-		dev_err(dev->dev, "Unknown color depth\n");
-		ret = -EINVAL;
-		psb_gtt_unpin(psbfb->gtt);
-		goto psb_intel_pipe_set_base_exit;
-	}
-	REG_WRITE(dspcntr_reg, dspcntr);
-
-
-	if (0 /* FIXMEAC - check what PSB needs */) {
-		REG_WRITE(dspbase, offset);
-		REG_READ(dspbase);
-		REG_WRITE(dspsurf, start);
-		REG_READ(dspsurf);
-	} else {
-		REG_WRITE(dspbase, start + offset);
-		REG_READ(dspbase);
-	}
-
-psb_intel_pipe_cleaner:
-	/* If there was a previous display we can now unpin it */
-	if (old_fb)
-		psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
-
-psb_intel_pipe_set_base_exit:
-	gma_power_end(dev);
-	return ret;
-}
-
-/**
- * Sets the power management mode of the pipe and plane.
- *
- * This code should probably grow support for turning the cursor off and back
- * on appropriately at the same time as we're turning the pipe off/on.
- */
-static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-	struct drm_device *dev = crtc->dev;
-	/* struct drm_i915_master_private *master_priv; */
-	/* struct drm_i915_private *dev_priv = dev->dev_private; */
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
-	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-	u32 temp;
-	bool enabled;
-
-	/* XXX: When our outputs are all unaware of DPMS modes other than off
-	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-	 */
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-		/* Enable the DPLL */
-		temp = REG_READ(dpll_reg);
-		if ((temp & DPLL_VCO_ENABLE) == 0) {
-			REG_WRITE(dpll_reg, temp);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-			/* Wait for the clocks to stabilize. */
-			udelay(150);
-		}
-
-		/* Enable the pipe */
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_ENABLE) == 0)
-			REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
-
-		/* Enable the plane */
-		temp = REG_READ(dspcntr_reg);
-		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-			REG_WRITE(dspcntr_reg,
-				  temp | DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-		}
-
-		psb_intel_crtc_load_lut(crtc);
-
-		/* Give the overlay scaler a chance to enable
-		 * if it's on this pipe */
-		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
-		break;
-	case DRM_MODE_DPMS_OFF:
-		/* Give the overlay scaler a chance to disable
-		 * if it's on this pipe */
-		/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
-
-		/* Disable the VGA plane that we never use */
-		REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
-
-		/* Disable display plane */
-		temp = REG_READ(dspcntr_reg);
-		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-			REG_WRITE(dspcntr_reg,
-				  temp & ~DISPLAY_PLANE_ENABLE);
-			/* Flush the plane changes */
-			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
-			REG_READ(dspbase_reg);
-		}
-
-		/* Next, disable display pipes */
-		temp = REG_READ(pipeconf_reg);
-		if ((temp & PIPEACONF_ENABLE) != 0) {
-			REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
-			REG_READ(pipeconf_reg);
-		}
-
-		/* Wait for vblank for the disable to take effect. */
-		psb_intel_wait_for_vblank(dev);
-
-		temp = REG_READ(dpll_reg);
-		if ((temp & DPLL_VCO_ENABLE) != 0) {
-			REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
-			REG_READ(dpll_reg);
-		}
-
-		/* Wait for the clocks to turn off. */
-		udelay(150);
-		break;
-	}
-
-	enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-
-	/*Set FIFO Watermarks*/
-	REG_WRITE(DSPARB, 0x3F3E);
-}
-
-static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
-{
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
-static void psb_intel_crtc_commit(struct drm_crtc *crtc)
-{
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-void psb_intel_encoder_prepare(struct drm_encoder *encoder)
-{
-	struct drm_encoder_helper_funcs *encoder_funcs =
-	    encoder->helper_private;
-	/* lvds has its own version of prepare see psb_intel_lvds_prepare */
-	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-void psb_intel_encoder_commit(struct drm_encoder *encoder)
-{
-	struct drm_encoder_helper_funcs *encoder_funcs =
-	    encoder->helper_private;
-	/* lvds has its own version of commit see psb_intel_lvds_commit */
-	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-
-/**
- * Return the pipe currently connected to the panel fitter,
- * or -1 if the panel fitter is not present or not in use
- */
-static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
-{
-	u32 pfit_control;
-
-	pfit_control = REG_READ(PFIT_CONTROL);
-
-	/* See if the panel fitter is in use */
-	if ((pfit_control & PFIT_ENABLE) == 0)
-		return -1;
-	/* Must be on PIPE 1 for PSB */
-	return 1;
-}
-
-static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode,
-			       int x, int y,
-			       struct drm_framebuffer *old_fb)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-	int pipe = psb_intel_crtc->pipe;
-	int fp_reg = (pipe == 0) ? FPA0 : FPB0;
-	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
-	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
-	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-	int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
-	int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
-	int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
-	int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
-	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
-	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
-	int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
-	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
-	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-	int refclk;
-	struct psb_intel_clock_t clock;
-	u32 dpll = 0, fp = 0, dspcntr, pipeconf;
-	bool ok, is_sdvo = false, is_dvo = false;
-	bool is_crt = false, is_lvds = false, is_tv = false;
-	struct drm_mode_config *mode_config = &dev->mode_config;
-	struct drm_connector *connector;
-
-	/* No scan out no play */
-	if (crtc->fb == NULL) {
-		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-		return 0;
-	}
-
-	list_for_each_entry(connector, &mode_config->connector_list, head) {
-		struct psb_intel_output *psb_intel_output =
-		    to_psb_intel_output(connector);
-
-		if (!connector->encoder
-		    || connector->encoder->crtc != crtc)
-			continue;
-
-		switch (psb_intel_output->type) {
-		case INTEL_OUTPUT_LVDS:
-			is_lvds = true;
-			break;
-		case INTEL_OUTPUT_SDVO:
-			is_sdvo = true;
-			break;
-		case INTEL_OUTPUT_DVO:
-			is_dvo = true;
-			break;
-		case INTEL_OUTPUT_TVOUT:
-			is_tv = true;
-			break;
-		case INTEL_OUTPUT_ANALOG:
-			is_crt = true;
-			break;
-		}
-	}
-
-	refclk = 96000;
-
-	ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
-				 &clock);
-	if (!ok) {
-		dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
-		return 0;
-	}
-
-	fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
-
-	dpll = DPLL_VGA_MODE_DIS;
-	if (is_lvds) {
-		dpll |= DPLLB_MODE_LVDS;
-		dpll |= DPLL_DVO_HIGH_SPEED;
-	} else
-		dpll |= DPLLB_MODE_DAC_SERIAL;
-	if (is_sdvo) {
-		int sdvo_pixel_multiply =
-			    adjusted_mode->clock / mode->clock;
-		dpll |= DPLL_DVO_HIGH_SPEED;
-		dpll |=
-		    (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-	}
-
-	/* compute bitmask from p1 value */
-	dpll |= (1 << (clock.p1 - 1)) << 16;
-	switch (clock.p2) {
-	case 5:
-		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
-		break;
-	case 7:
-		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
-		break;
-	case 10:
-		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
-		break;
-	case 14:
-		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
-		break;
-	}
-
-	if (is_tv) {
-		/* XXX: just matching BIOS for now */
-/*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
-		dpll |= 3;
-	}
-	dpll |= PLL_REF_INPUT_DREFCLK;
-
-	/* setup pipeconf */
-	pipeconf = REG_READ(pipeconf_reg);
-
-	/* Set up the display plane register */
-	dspcntr = DISPPLANE_GAMMA_ENABLE;
-
-	if (pipe == 0)
-		dspcntr |= DISPPLANE_SEL_PIPE_A;
-	else
-		dspcntr |= DISPPLANE_SEL_PIPE_B;
-
-	dspcntr |= DISPLAY_PLANE_ENABLE;
-	pipeconf |= PIPEACONF_ENABLE;
-	dpll |= DPLL_VCO_ENABLE;
-
-
-	/* Disable the panel fitter if it was on our pipe */
-	if (psb_intel_panel_fitter_pipe(dev) == pipe)
-		REG_WRITE(PFIT_CONTROL, 0);
-
-	drm_mode_debug_printmodeline(mode);
-
-	if (dpll & DPLL_VCO_ENABLE) {
-		REG_WRITE(fp_reg, fp);
-		REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
-		REG_READ(dpll_reg);
-		udelay(150);
-	}
-
-	/* The LVDS pin pair needs to be on before the DPLLs are enabled.
-	 * This is an exception to the general rule that mode_set doesn't turn
-	 * things on.
-	 */
-	if (is_lvds) {
-		u32 lvds = REG_READ(LVDS);
-
-		lvds &= ~LVDS_PIPEB_SELECT;
-		if (pipe == 1)
-			lvds |= LVDS_PIPEB_SELECT;
-
-		lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
-		/* Set the B0-B3 data pairs corresponding to
-		 * whether we're going to
-		 * set the DPLLs for dual-channel mode or not.
-		 */
-		lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
-		if (clock.p2 == 7)
-			lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
-
-		/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
-		 * appropriately here, but we need to look more
-		 * thoroughly into how panels behave in the two modes.
-		 */
-
-		REG_WRITE(LVDS, lvds);
-		REG_READ(LVDS);
-	}
-
-	REG_WRITE(fp_reg, fp);
-	REG_WRITE(dpll_reg, dpll);
-	REG_READ(dpll_reg);
-	/* Wait for the clocks to stabilize. */
-	udelay(150);
-
-	/* write it again -- the BIOS does, after all */
-	REG_WRITE(dpll_reg, dpll);
-
-	REG_READ(dpll_reg);
-	/* Wait for the clocks to stabilize. */
-	udelay(150);
-
-	REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
-		  ((adjusted_mode->crtc_htotal - 1) << 16));
-	REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
-		  ((adjusted_mode->crtc_hblank_end - 1) << 16));
-	REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
-		  ((adjusted_mode->crtc_hsync_end - 1) << 16));
-	REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
-		  ((adjusted_mode->crtc_vtotal - 1) << 16));
-	REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
-		  ((adjusted_mode->crtc_vblank_end - 1) << 16));
-	REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
-		  ((adjusted_mode->crtc_vsync_end - 1) << 16));
-	/* pipesrc and dspsize control the size that is scaled from,
-	 * which should always be the user's requested size.
-	 */
-	REG_WRITE(dspsize_reg,
-		  ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
-	REG_WRITE(dsppos_reg, 0);
-	REG_WRITE(pipesrc_reg,
-		  ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
-	REG_WRITE(pipeconf_reg, pipeconf);
-	REG_READ(pipeconf_reg);
-
-	psb_intel_wait_for_vblank(dev);
-
-	REG_WRITE(dspcntr_reg, dspcntr);
-
-	/* Flush the plane changes */
-	crtc_funcs->mode_set_base(crtc, x, y, old_fb);
-
-	psb_intel_wait_for_vblank(dev);
-
-	return 0;
-}
-
-/** Loads the palette/gamma unit for the CRTC with the prepared values */
-void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private *dev_priv =
-				(struct drm_psb_private *)dev->dev_private;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int palreg = PALETTE_A;
-	int i;
-
-	/* The clocks have to be on to load the palette. */
-	if (!crtc->enabled)
-		return;
-
-	switch (psb_intel_crtc->pipe) {
-	case 0:
-		break;
-	case 1:
-		palreg = PALETTE_B;
-		break;
-	case 2:
-		palreg = PALETTE_C;
-		break;
-	default:
-		dev_err(dev->dev, "Illegal Pipe Number.\n");
-		return;
-	}
-
-	if (gma_power_begin(dev, false)) {
-		for (i = 0; i < 256; i++) {
-			REG_WRITE(palreg + 4 * i,
-				  ((psb_intel_crtc->lut_r[i] +
-				  psb_intel_crtc->lut_adj[i]) << 16) |
-				  ((psb_intel_crtc->lut_g[i] +
-				  psb_intel_crtc->lut_adj[i]) << 8) |
-				  (psb_intel_crtc->lut_b[i] +
-				  psb_intel_crtc->lut_adj[i]));
-		}
-		gma_power_end(dev);
-	} else {
-		for (i = 0; i < 256; i++) {
-			dev_priv->save_palette_a[i] =
-				  ((psb_intel_crtc->lut_r[i] +
-				  psb_intel_crtc->lut_adj[i]) << 16) |
-				  ((psb_intel_crtc->lut_g[i] +
-				  psb_intel_crtc->lut_adj[i]) << 8) |
-				  (psb_intel_crtc->lut_b[i] +
-				  psb_intel_crtc->lut_adj[i]);
-		}
-
-	}
-}
-
-/**
- * Save HW states of giving crtc
- */
-static void psb_intel_crtc_save(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	/* struct drm_psb_private *dev_priv =
-			(struct drm_psb_private *)dev->dev_private; */
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
-	int pipeA = (psb_intel_crtc->pipe == 0);
-	uint32_t paletteReg;
-	int i;
-
-	if (!crtc_state) {
-		dev_err(dev->dev, "No CRTC state found\n");
-		return;
-	}
-
-	crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
-	crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
-	crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
-	crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
-	crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
-	crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
-	crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
-	crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
-	crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
-	crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
-	crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
-	crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
-	crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
-
-	/*NOTE: DSPSIZE DSPPOS only for psb*/
-	crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
-	crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
-
-	crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
-
-	paletteReg = pipeA ? PALETTE_A : PALETTE_B;
-	for (i = 0; i < 256; ++i)
-		crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
-}
-
-/**
- * Restore HW states of giving crtc
- */
-static void psb_intel_crtc_restore(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	/* struct drm_psb_private * dev_priv =
-				(struct drm_psb_private *)dev->dev_private; */
-	struct psb_intel_crtc *psb_intel_crtc =  to_psb_intel_crtc(crtc);
-	struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
-	/* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
-	int pipeA = (psb_intel_crtc->pipe == 0);
-	uint32_t paletteReg;
-	int i;
-
-	if (!crtc_state) {
-		dev_err(dev->dev, "No crtc state\n");
-		return;
-	}
-
-	if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
-		REG_WRITE(pipeA ? DPLL_A : DPLL_B,
-			crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
-		REG_READ(pipeA ? DPLL_A : DPLL_B);
-		udelay(150);
-	}
-
-	REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
-	REG_READ(pipeA ? FPA0 : FPB0);
-
-	REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
-	REG_READ(pipeA ? FPA1 : FPB1);
-
-	REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
-	REG_READ(pipeA ? DPLL_A : DPLL_B);
-	udelay(150);
-
-	REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
-	REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
-	REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
-	REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
-	REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
-	REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
-	REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
-
-	REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
-	REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
-
-	REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
-	REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-	REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
-
-	psb_intel_wait_for_vblank(dev);
-
-	REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
-	REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
-
-	psb_intel_wait_for_vblank(dev);
-
-	paletteReg = pipeA ? PALETTE_A : PALETTE_B;
-	for (i = 0; i < 256; ++i)
-		REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
-}
-
-static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
-				 struct drm_file *file_priv,
-				 uint32_t handle,
-				 uint32_t width, uint32_t height)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
-	uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
-	uint32_t temp;
-	size_t addr = 0;
-	struct gtt_range *gt;
-	struct drm_gem_object *obj;
-	int ret;
-
-	/* if we want to turn of the cursor ignore width and height */
-	if (!handle) {
-		/* turn off the cursor */
-		temp = CURSOR_MODE_DISABLE;
-
-		if (gma_power_begin(dev, false)) {
-			REG_WRITE(control, temp);
-			REG_WRITE(base, 0);
-			gma_power_end(dev);
-		}
-
-		/* Unpin the old GEM object */
-		if (psb_intel_crtc->cursor_obj) {
-			gt = container_of(psb_intel_crtc->cursor_obj,
-							struct gtt_range, gem);
-			psb_gtt_unpin(gt);
-			drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-			psb_intel_crtc->cursor_obj = NULL;
-		}
-
-		return 0;
-	}
-
-	/* Currently we only support 64x64 cursors */
-	if (width != 64 || height != 64) {
-		dev_dbg(dev->dev, "we currently only support 64x64 cursors\n");
-		return -EINVAL;
-	}
-
-	obj = drm_gem_object_lookup(dev, file_priv, handle);
-	if (!obj)
-		return -ENOENT;
-
-	if (obj->size < width * height * 4) {
-		dev_dbg(dev->dev, "buffer is to small\n");
-		return -ENOMEM;
-	}
-
-	gt = container_of(obj, struct gtt_range, gem);
-
-	/* Pin the memory into the GTT */
-	ret = psb_gtt_pin(gt);
-	if (ret) {
-		dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-		return ret;
-	}
-
-
-	addr = gt->offset;	/* Or resource.start ??? */
-
-	psb_intel_crtc->cursor_addr = addr;
-
-	temp = 0;
-	/* set the pipe for the cursor */
-	temp |= (pipe << 28);
-	temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-
-	if (gma_power_begin(dev, false)) {
-		REG_WRITE(control, temp);
-		REG_WRITE(base, addr);
-		gma_power_end(dev);
-	}
-
-	/* unpin the old bo */
-	if (psb_intel_crtc->cursor_obj) {
-		gt = container_of(psb_intel_crtc->cursor_obj,
-							struct gtt_range, gem);
-		psb_gtt_unpin(gt);
-		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-		psb_intel_crtc->cursor_obj = obj;
-	}
-	return 0;
-}
-
-static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
-	struct drm_device *dev = crtc->dev;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	uint32_t temp = 0;
-	uint32_t addr;
-
-
-	if (x < 0) {
-		temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
-		x = -x;
-	}
-	if (y < 0) {
-		temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
-		y = -y;
-	}
-
-	temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
-	temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
-
-	addr = psb_intel_crtc->cursor_addr;
-
-	if (gma_power_begin(dev, false)) {
-		REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
-		REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr);
-		gma_power_end(dev);
-	}
-	return 0;
-}
-
-void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
-			 u16 *green, u16 *blue, uint32_t type, uint32_t size)
-{
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int i;
-
-	if (size != 256)
-		return;
-
-	for (i = 0; i < 256; i++) {
-		psb_intel_crtc->lut_r[i] = red[i] >> 8;
-		psb_intel_crtc->lut_g[i] = green[i] >> 8;
-		psb_intel_crtc->lut_b[i] = blue[i] >> 8;
-	}
-
-	psb_intel_crtc_load_lut(crtc);
-}
-
-static int psb_crtc_set_config(struct drm_mode_set *set)
-{
-	int ret;
-	struct drm_device *dev = set->crtc->dev;
-
-	pm_runtime_forbid(&dev->pdev->dev);
-	ret = drm_crtc_helper_set_config(set);
-	pm_runtime_allow(&dev->pdev->dev);
-	return ret;
-}
-
-/* Returns the clock of the currently programmed mode of the given pipe. */
-static int psb_intel_crtc_clock_get(struct drm_device *dev,
-				struct drm_crtc *crtc)
-{
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	u32 dpll;
-	u32 fp;
-	struct psb_intel_clock_t clock;
-	bool is_lvds;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (gma_power_begin(dev, false)) {
-		dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
-		if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-			fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
-		else
-			fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
-		is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
-		gma_power_end(dev);
-	} else {
-		dpll = (pipe == 0) ?
-			dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
-
-		if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-			fp = (pipe == 0) ?
-				dev_priv->saveFPA0 :
-				dev_priv->saveFPB0;
-		else
-			fp = (pipe == 0) ?
-				dev_priv->saveFPA1 :
-				dev_priv->saveFPB1;
-
-		is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
-	}
-
-	clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
-	clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
-	clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
-
-	if (is_lvds) {
-		clock.p1 =
-		    ffs((dpll &
-			 DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
-			DPLL_FPA01_P1_POST_DIV_SHIFT);
-		clock.p2 = 14;
-
-		if ((dpll & PLL_REF_INPUT_MASK) ==
-		    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
-			/* XXX: might not be 66MHz */
-			i8xx_clock(66000, &clock);
-		} else
-			i8xx_clock(48000, &clock);
-	} else {
-		if (dpll & PLL_P1_DIVIDE_BY_TWO)
-			clock.p1 = 2;
-		else {
-			clock.p1 =
-			    ((dpll &
-			      DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
-			     DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
-		}
-		if (dpll & PLL_P2_DIVIDE_BY_4)
-			clock.p2 = 4;
-		else
-			clock.p2 = 2;
-
-		i8xx_clock(48000, &clock);
-	}
-
-	/* XXX: It would be nice to validate the clocks, but we can't reuse
-	 * i830PllIsValid() because it relies on the xf86_config connector
-	 * configuration being accurate, which it isn't necessarily.
-	 */
-
-	return clock.dot;
-}
-
-/** Returns the currently programmed mode of the given pipe. */
-struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
-					     struct drm_crtc *crtc)
-{
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	int pipe = psb_intel_crtc->pipe;
-	struct drm_display_mode *mode;
-	int htot;
-	int hsync;
-	int vtot;
-	int vsync;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	if (gma_power_begin(dev, false)) {
-		htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
-		hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
-		vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
-		vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
-		gma_power_end(dev);
-	} else {
-		htot = (pipe == 0) ?
-			dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
-		hsync = (pipe == 0) ?
-			dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
-		vtot = (pipe == 0) ?
-			dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
-		vsync = (pipe == 0) ?
-			dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
-	}
-
-	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
-	if (!mode)
-		return NULL;
-
-	mode->clock = psb_intel_crtc_clock_get(dev, crtc);
-	mode->hdisplay = (htot & 0xffff) + 1;
-	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
-	mode->hsync_start = (hsync & 0xffff) + 1;
-	mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
-	mode->vdisplay = (vtot & 0xffff) + 1;
-	mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
-	mode->vsync_start = (vsync & 0xffff) + 1;
-	mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
-
-	drm_mode_set_name(mode);
-	drm_mode_set_crtcinfo(mode, 0);
-
-	return mode;
-}
-
-void psb_intel_crtc_destroy(struct drm_crtc *crtc)
-{
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct gtt_range *gt;
-
-	/* Unpin the old GEM object */
-	if (psb_intel_crtc->cursor_obj) {
-		gt = container_of(psb_intel_crtc->cursor_obj,
-						struct gtt_range, gem);
-		psb_gtt_unpin(gt);
-		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-		psb_intel_crtc->cursor_obj = NULL;
-	}
-	kfree(psb_intel_crtc->crtc_state);
-	drm_crtc_cleanup(crtc);
-	kfree(psb_intel_crtc);
-}
-
-const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
-	.dpms = psb_intel_crtc_dpms,
-	.mode_fixup = psb_intel_crtc_mode_fixup,
-	.mode_set = psb_intel_crtc_mode_set,
-	.mode_set_base = psb_intel_pipe_set_base,
-	.prepare = psb_intel_crtc_prepare,
-	.commit = psb_intel_crtc_commit,
-};
-
-const struct drm_crtc_funcs psb_intel_crtc_funcs = {
-	.save = psb_intel_crtc_save,
-	.restore = psb_intel_crtc_restore,
-	.cursor_set = psb_intel_crtc_cursor_set,
-	.cursor_move = psb_intel_crtc_cursor_move,
-	.gamma_set = psb_intel_crtc_gamma_set,
-	.set_config = psb_crtc_set_config,
-	.destroy = psb_intel_crtc_destroy,
-};
-
-/*
- * Set the default value of cursor control and base register
- * to zero. This is a workaround for h/w defect on Oaktrail
- */
-static void psb_intel_cursor_init(struct drm_device *dev, int pipe)
-{
-	u32 control[3] = { CURACNTR, CURBCNTR, CURCCNTR };
-	u32 base[3] = { CURABASE, CURBBASE, CURCBASE };
-
-	REG_WRITE(control[pipe], 0);
-	REG_WRITE(base[pipe], 0);
-}
-
-void psb_intel_crtc_init(struct drm_device *dev, int pipe,
-		     struct psb_intel_mode_device *mode_dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_intel_crtc *psb_intel_crtc;
-	int i;
-	uint16_t *r_base, *g_base, *b_base;
-
-	/* We allocate a extra array of drm_connector pointers
-	 * for fbdev after the crtc */
-	psb_intel_crtc =
-	    kzalloc(sizeof(struct psb_intel_crtc) +
-		    (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)),
-		    GFP_KERNEL);
-	if (psb_intel_crtc == NULL)
-		return;
-
-	psb_intel_crtc->crtc_state =
-		kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL);
-	if (!psb_intel_crtc->crtc_state) {
-		dev_err(dev->dev, "Crtc state error: No memory\n");
-		kfree(psb_intel_crtc);
-		return;
-	}
-
-	/* Set the CRTC operations from the chip specific data */
-	drm_crtc_init(dev, &psb_intel_crtc->base, dev_priv->ops->crtc_funcs);
-
-	drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256);
-	psb_intel_crtc->pipe = pipe;
-	psb_intel_crtc->plane = pipe;
-
-	r_base = psb_intel_crtc->base.gamma_store;
-	g_base = r_base + 256;
-	b_base = g_base + 256;
-	for (i = 0; i < 256; i++) {
-		psb_intel_crtc->lut_r[i] = i;
-		psb_intel_crtc->lut_g[i] = i;
-		psb_intel_crtc->lut_b[i] = i;
-		r_base[i] = i << 8;
-		g_base[i] = i << 8;
-		b_base[i] = i << 8;
-
-		psb_intel_crtc->lut_adj[i] = 0;
-	}
-
-	psb_intel_crtc->mode_dev = mode_dev;
-	psb_intel_crtc->cursor_addr = 0;
-
-	drm_crtc_helper_add(&psb_intel_crtc->base,
-						dev_priv->ops->crtc_helper);
-
-	/* Setup the array of drm_connector pointer array */
-	psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base;
-	BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
-	       dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL);
-	dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] =
-							&psb_intel_crtc->base;
-	dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] =
-							&psb_intel_crtc->base;
-	psb_intel_crtc->mode_set.connectors =
-	    (struct drm_connector **) (psb_intel_crtc + 1);
-	psb_intel_crtc->mode_set.num_connectors = 0;
-	psb_intel_cursor_init(dev, pipe);
-}
-
-int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
-				struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data;
-	struct drm_mode_object *drmmode_obj;
-	struct psb_intel_crtc *crtc;
-
-	if (!dev_priv) {
-		dev_err(dev->dev, "called with no initialization\n");
-		return -EINVAL;
-	}
-
-	drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
-			DRM_MODE_OBJECT_CRTC);
-
-	if (!drmmode_obj) {
-		dev_err(dev->dev, "no such CRTC id\n");
-		return -EINVAL;
-	}
-
-	crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj));
-	pipe_from_crtc_id->pipe = crtc->pipe;
-
-	return 0;
-}
-
-struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
-{
-	struct drm_crtc *crtc = NULL;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-		if (psb_intel_crtc->pipe == pipe)
-			break;
-	}
-	return crtc;
-}
-
-int psb_intel_connector_clones(struct drm_device *dev, int type_mask)
-{
-	int index_mask = 0;
-	struct drm_connector *connector;
-	int entry = 0;
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list,
-			    head) {
-		struct psb_intel_output *psb_intel_output =
-		    to_psb_intel_output(connector);
-		if (type_mask & (1 << psb_intel_output->type))
-			index_mask |= (1 << entry);
-		entry++;
-	}
-	return index_mask;
-}
-
-
-void psb_intel_modeset_cleanup(struct drm_device *dev)
-{
-	drm_mode_config_cleanup(dev);
-}
-
-
-/* current intel driver doesn't take advantage of encoders
-   always give back the encoder for the connector
-*/
-struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector)
-{
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-
-	return &psb_intel_output->enc;
-}
-
diff --git a/drivers/staging/gma500/psb_intel_display.h b/drivers/staging/gma500/psb_intel_display.h
deleted file mode 100644
index 535b49a..0000000
--- a/drivers/staging/gma500/psb_intel_display.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* copyright (c) 2008, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- */
-
-#ifndef _INTEL_DISPLAY_H_
-#define _INTEL_DISPLAY_H_
-
-bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type);
-void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
-			 u16 *green, u16 *blue, uint32_t type, uint32_t size);
-void psb_intel_crtc_destroy(struct drm_crtc *crtc);
-
-#endif
diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h
deleted file mode 100644
index 36b554b..0000000
--- a/drivers/staging/gma500/psb_intel_drv.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __INTEL_DRV_H__
-#define __INTEL_DRV_H__
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
-#include <linux/gpio.h>
-
-/*
- * Display related stuff
- */
-
-/* store information about an Ixxx DVO */
-/* The i830->i865 use multiple DVOs with multiple i2cs */
-/* the i915, i945 have a single sDVO i2c bus - which is different */
-#define MAX_OUTPUTS 6
-/* maximum connectors per crtcs in the mode set */
-#define INTELFB_CONN_LIMIT 4
-
-#define INTEL_I2C_BUS_DVO 1
-#define INTEL_I2C_BUS_SDVO 2
-
-/* these are outputs from the chip - integrated only
- * external chips are via DVO or SDVO output */
-#define INTEL_OUTPUT_UNUSED 0
-#define INTEL_OUTPUT_ANALOG 1
-#define INTEL_OUTPUT_DVO 2
-#define INTEL_OUTPUT_SDVO 3
-#define INTEL_OUTPUT_LVDS 4
-#define INTEL_OUTPUT_TVOUT 5
-#define INTEL_OUTPUT_HDMI 6
-#define INTEL_OUTPUT_MIPI 7
-#define INTEL_OUTPUT_MIPI2 8
-
-#define INTEL_DVO_CHIP_NONE 0
-#define INTEL_DVO_CHIP_LVDS 1
-#define INTEL_DVO_CHIP_TMDS 2
-#define INTEL_DVO_CHIP_TVOUT 4
-
-/*
- * Hold information useally put on the device driver privates here,
- * since it needs to be shared across multiple of devices drivers privates.
- */
-struct psb_intel_mode_device {
-
-	/*
-	 * Abstracted memory manager operations
-	 */
-	 size_t(*bo_offset) (struct drm_device *dev, void *bo);
-
-	/*
-	 * Cursor (Can go ?)
-	 */
-	int cursor_needs_physical;
-
-	/*
-	 * LVDS info
-	 */
-	int backlight_duty_cycle;	/* restore backlight to this value */
-	bool panel_wants_dither;
-	struct drm_display_mode *panel_fixed_mode;
-	struct drm_display_mode *panel_fixed_mode2;
-	struct drm_display_mode *vbt_mode;	/* if any */
-
-	uint32_t saveBLC_PWM_CTL;
-};
-
-struct psb_intel_i2c_chan {
-	/* for getting at dev. private (mmio etc.) */
-	struct drm_device *drm_dev;
-	u32 reg;		/* GPIO reg */
-	struct i2c_adapter adapter;
-	struct i2c_algo_bit_data algo;
-	u8 slave_addr;
-};
-
-struct psb_intel_output {
-	struct drm_connector base;
-
-	struct drm_encoder enc;
-	int type;
-
-	struct psb_intel_i2c_chan *i2c_bus;	/* for control functions */
-	struct psb_intel_i2c_chan *ddc_bus;	/* for DDC only stuff */
-	bool load_detect_temp;
-	void *dev_priv;
-
-	struct psb_intel_mode_device *mode_dev;
-	struct i2c_adapter *hdmi_i2c_adapter;	/* for control functions */
-};
-
-struct psb_intel_crtc_state {
-	uint32_t saveDSPCNTR;
-	uint32_t savePIPECONF;
-	uint32_t savePIPESRC;
-	uint32_t saveDPLL;
-	uint32_t saveFP0;
-	uint32_t saveFP1;
-	uint32_t saveHTOTAL;
-	uint32_t saveHBLANK;
-	uint32_t saveHSYNC;
-	uint32_t saveVTOTAL;
-	uint32_t saveVBLANK;
-	uint32_t saveVSYNC;
-	uint32_t saveDSPSTRIDE;
-	uint32_t saveDSPSIZE;
-	uint32_t saveDSPPOS;
-	uint32_t saveDSPBASE;
-	uint32_t savePalette[256];
-};
-
-struct psb_intel_crtc {
-	struct drm_crtc base;
-	int pipe;
-	int plane;
-	uint32_t cursor_addr;
-	u8 lut_r[256], lut_g[256], lut_b[256];
-	u8 lut_adj[256];
-	struct psb_intel_framebuffer *fbdev_fb;
-	/* a mode_set for fbdev users on this crtc */
-	struct drm_mode_set mode_set;
-
-	/* GEM object that holds our cursor */
-	struct drm_gem_object *cursor_obj;
-
-	struct drm_display_mode saved_mode;
-	struct drm_display_mode saved_adjusted_mode;
-
-	struct psb_intel_mode_device *mode_dev;
-
-	/*crtc mode setting flags*/
-	u32 mode_flags;
-
-	/* Saved Crtc HW states */
-	struct psb_intel_crtc_state *crtc_state;
-};
-
-#define to_psb_intel_crtc(x)	\
-		container_of(x, struct psb_intel_crtc, base)
-#define to_psb_intel_output(x)	\
-		container_of(x, struct psb_intel_output, base)
-#define enc_to_psb_intel_output(x)	\
-		container_of(x, struct psb_intel_output, enc)
-#define to_psb_intel_framebuffer(x)	\
-		container_of(x, struct psb_intel_framebuffer, base)
-
-struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev,
-					const u32 reg, const char *name);
-void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan);
-int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output);
-extern bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output);
-
-extern void psb_intel_crtc_init(struct drm_device *dev, int pipe,
-			    struct psb_intel_mode_device *mode_dev);
-extern void psb_intel_crt_init(struct drm_device *dev);
-extern void psb_intel_sdvo_init(struct drm_device *dev, int output_device);
-extern void psb_intel_dvo_init(struct drm_device *dev);
-extern void psb_intel_tv_init(struct drm_device *dev);
-extern void psb_intel_lvds_init(struct drm_device *dev,
-			    struct psb_intel_mode_device *mode_dev);
-extern void psb_intel_lvds_set_brightness(struct drm_device *dev, int level);
-extern void mrst_lvds_init(struct drm_device *dev,
-			   struct psb_intel_mode_device *mode_dev);
-extern void mrst_wait_for_INTR_PKT_SENT(struct drm_device *dev);
-extern void mrst_dsi_init(struct drm_device *dev,
-			   struct psb_intel_mode_device *mode_dev);
-extern void mid_dsi_init(struct drm_device *dev,
-		    struct psb_intel_mode_device *mode_dev, int dsi_num);
-
-extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc);
-extern void psb_intel_encoder_prepare(struct drm_encoder *encoder);
-extern void psb_intel_encoder_commit(struct drm_encoder *encoder);
-
-extern struct drm_encoder *psb_intel_best_encoder(struct drm_connector
-					      *connector);
-
-extern struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
-						    struct drm_crtc *crtc);
-extern void psb_intel_wait_for_vblank(struct drm_device *dev);
-extern int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
-				struct drm_file *file_priv);
-extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev,
-						 int pipe);
-extern struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev,
-					     int sdvoB);
-extern int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector);
-extern void psb_intel_sdvo_set_hotplug(struct drm_connector *connector,
-				   int enable);
-extern int intelfb_probe(struct drm_device *dev);
-extern int intelfb_remove(struct drm_device *dev,
-			  struct drm_framebuffer *fb);
-extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device
-							*dev, struct
-							drm_mode_fb_cmd
-							*mode_cmd,
-							void *mm_private);
-extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
-				      struct drm_display_mode *mode,
-				      struct drm_display_mode *adjusted_mode);
-extern int psb_intel_lvds_mode_valid(struct drm_connector *connector,
-				     struct drm_display_mode *mode);
-extern int psb_intel_lvds_set_property(struct drm_connector *connector,
-					struct drm_property *property,
-					uint64_t value);
-extern void psb_intel_lvds_destroy(struct drm_connector *connector);
-extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs;
-
-extern void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe);
-extern void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe);
-
-#endif				/* __INTEL_DRV_H__ */
diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c
deleted file mode 100644
index 21022e1..0000000
--- a/drivers/staging/gma500/psb_intel_lvds.c
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Copyright © 2006-2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- *	Dave Airlie <airlied@linux.ie>
- *	Jesse Barnes <jesse.barnes@intel.com>
- */
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-
-#include "intel_bios.h"
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include <linux/pm_runtime.h>
-
-/*
- * LVDS I2C backlight control macros
- */
-#define BRIGHTNESS_MAX_LEVEL 100
-#define BRIGHTNESS_MASK 0xFF
-#define BLC_I2C_TYPE	0x01
-#define BLC_PWM_TYPT	0x02
-
-#define BLC_POLARITY_NORMAL 0
-#define BLC_POLARITY_INVERSE 1
-
-#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
-#define PSB_BLC_MIN_PWM_REG_FREQ	(0x2)
-#define PSB_BLC_PWM_PRECISION_FACTOR	(10)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-
-struct psb_intel_lvds_priv {
-	/*
-	 * Saved LVDO output states
-	 */
-	uint32_t savePP_ON;
-	uint32_t savePP_OFF;
-	uint32_t saveLVDS;
-	uint32_t savePP_CONTROL;
-	uint32_t savePP_CYCLE;
-	uint32_t savePFIT_CONTROL;
-	uint32_t savePFIT_PGM_RATIOS;
-	uint32_t saveBLC_PWM_CTL;
-};
-
-
-/*
- * Returns the maximum level of the backlight duty cycle field.
- */
-static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 ret;
-
-	if (gma_power_begin(dev, false)) {
-		ret = REG_READ(BLC_PWM_CTL);
-		gma_power_end(dev);
-	} else /* Powered off, use the saved value */
-		ret = dev_priv->saveBLC_PWM_CTL;
-
-	/* Top 15bits hold the frequency mask */
-	ret = (ret &  BACKLIGHT_MODULATION_FREQ_MASK) >>
-					BACKLIGHT_MODULATION_FREQ_SHIFT;
-
-        ret *= 2;	/* Return a 16bit range as needed for setting */
-        if (ret == 0)
-                dev_err(dev->dev, "BL bug: Reg %08x save %08X\n",
-                        REG_READ(BLC_PWM_CTL), dev_priv->saveBLC_PWM_CTL);
-	return ret;
-}
-
-/*
- * Set LVDS backlight level by I2C command
- *
- * FIXME: at some point we need to both track this for PM and also
- * disable runtime pm on MRST if the brightness is nil (ie blanked)
- */
-static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
-					unsigned int level)
-{
-	struct drm_psb_private *dev_priv =
-		(struct drm_psb_private *)dev->dev_private;
-
-	struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
-	u8 out_buf[2];
-	unsigned int blc_i2c_brightness;
-
-	struct i2c_msg msgs[] = {
-		{
-			.addr = lvds_i2c_bus->slave_addr,
-			.flags = 0,
-			.len = 2,
-			.buf = out_buf,
-		}
-	};
-
-	blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
-			     BRIGHTNESS_MASK /
-			     BRIGHTNESS_MAX_LEVEL);
-
-	if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
-		blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
-
-	out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
-	out_buf[1] = (u8)blc_i2c_brightness;
-
-	if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
-		dev_dbg(dev->dev, "I2C set brightness.(command, value) (%d, %d)\n",
-			dev_priv->lvds_bl->brightnesscmd,
-			blc_i2c_brightness);
-		return 0;
-	}
-
-	dev_err(dev->dev, "I2C transfer error\n");
-	return -1;
-}
-
-
-static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level)
-{
-	struct drm_psb_private *dev_priv =
-			(struct drm_psb_private *)dev->dev_private;
-
-	u32 max_pwm_blc;
-	u32 blc_pwm_duty_cycle;
-
-	max_pwm_blc = psb_intel_lvds_get_max_backlight(dev);
-
-	/*BLC_PWM_CTL Should be initiated while backlight device init*/
-	BUG_ON(max_pwm_blc == 0);
-
-	blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
-
-	if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
-		blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
-
-	blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
-	REG_WRITE(BLC_PWM_CTL,
-		  (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
-		  (blc_pwm_duty_cycle));
-
-        dev_info(dev->dev, "Backlight lvds set brightness %08x\n",
-		  (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
-		  (blc_pwm_duty_cycle));
-
-	return 0;
-}
-
-/*
- * Set LVDS backlight level either by I2C or PWM
- */
-void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-
-	dev_dbg(dev->dev, "backlight level is %d\n", level);
-
-	if (!dev_priv->lvds_bl) {
-		dev_err(dev->dev, "NO LVDS backlight info\n");
-		return;
-	}
-
-	if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
-		psb_lvds_i2c_set_brightness(dev, level);
-	else
-		psb_lvds_pwm_set_brightness(dev, level);
-}
-
-/*
- * Sets the backlight level.
- *
- * level: backlight level, from 0 to psb_intel_lvds_get_max_backlight().
- */
-static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 blc_pwm_ctl;
-
-	if (gma_power_begin(dev, false)) {
-		blc_pwm_ctl = REG_READ(BLC_PWM_CTL);
-		blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
-		REG_WRITE(BLC_PWM_CTL,
-				(blc_pwm_ctl |
-				(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
-		dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
-					(level << BACKLIGHT_DUTY_CYCLE_SHIFT));
-		gma_power_end(dev);
-	} else {
-		blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
-				~BACKLIGHT_DUTY_CYCLE_MASK;
-		dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
-					(level << BACKLIGHT_DUTY_CYCLE_SHIFT));
-	}
-}
-
-/*
- * Sets the power state for the panel.
- */
-static void psb_intel_lvds_set_power(struct drm_device *dev,
-				 struct psb_intel_output *output, bool on)
-{
-	u32 pp_status;
-
-	if (!gma_power_begin(dev, true)) {
-	        dev_err(dev->dev, "set power, chip off!\n");
-		return;
-        }
-        
-	if (on) {
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
-			  POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while ((pp_status & PP_ON) == 0);
-
-		psb_intel_lvds_set_backlight(dev,
-					 output->
-					 mode_dev->backlight_duty_cycle);
-	} else {
-		psb_intel_lvds_set_backlight(dev, 0);
-
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
-			  ~POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while (pp_status & PP_ON);
-	}
-
-	gma_power_end(dev);
-}
-
-static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-
-	if (mode == DRM_MODE_DPMS_ON)
-		psb_intel_lvds_set_power(dev, output, true);
-	else
-		psb_intel_lvds_set_power(dev, output, false);
-
-	/* XXX: We never power down the LVDS pairs. */
-}
-
-static void psb_intel_lvds_save(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct drm_psb_private *dev_priv =
-		(struct drm_psb_private *)dev->dev_private;
-	struct psb_intel_output *psb_intel_output =
-		to_psb_intel_output(connector);
-	struct psb_intel_lvds_priv *lvds_priv =
-		(struct psb_intel_lvds_priv *)psb_intel_output->dev_priv;
-
-	lvds_priv->savePP_ON = REG_READ(LVDSPP_ON);
-	lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF);
-	lvds_priv->saveLVDS = REG_READ(LVDS);
-	lvds_priv->savePP_CONTROL = REG_READ(PP_CONTROL);
-	lvds_priv->savePP_CYCLE = REG_READ(PP_CYCLE);
-	/*lvds_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);*/
-	lvds_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
-	lvds_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL);
-	lvds_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS);
-
-	/*TODO: move backlight_duty_cycle to psb_intel_lvds_priv*/
-	dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
-						BACKLIGHT_DUTY_CYCLE_MASK);
-
-	/*
-	 * If the light is off at server startup,
-	 * just make it full brightness
-	 */
-	if (dev_priv->backlight_duty_cycle == 0)
-		dev_priv->backlight_duty_cycle =
-		psb_intel_lvds_get_max_backlight(dev);
-
-	dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
-			lvds_priv->savePP_ON,
-			lvds_priv->savePP_OFF,
-			lvds_priv->saveLVDS,
-			lvds_priv->savePP_CONTROL,
-			lvds_priv->savePP_CYCLE,
-			lvds_priv->saveBLC_PWM_CTL);
-}
-
-static void psb_intel_lvds_restore(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	u32 pp_status;
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-	struct psb_intel_lvds_priv *lvds_priv =
-		(struct psb_intel_lvds_priv *)psb_intel_output->dev_priv;
-
-	dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
-			lvds_priv->savePP_ON,
-			lvds_priv->savePP_OFF,
-			lvds_priv->saveLVDS,
-			lvds_priv->savePP_CONTROL,
-			lvds_priv->savePP_CYCLE,
-			lvds_priv->saveBLC_PWM_CTL);
-
-	REG_WRITE(BLC_PWM_CTL, lvds_priv->saveBLC_PWM_CTL);
-	REG_WRITE(PFIT_CONTROL, lvds_priv->savePFIT_CONTROL);
-	REG_WRITE(PFIT_PGM_RATIOS, lvds_priv->savePFIT_PGM_RATIOS);
-	REG_WRITE(LVDSPP_ON, lvds_priv->savePP_ON);
-	REG_WRITE(LVDSPP_OFF, lvds_priv->savePP_OFF);
-	/*REG_WRITE(PP_DIVISOR, lvds_priv->savePP_DIVISOR);*/
-	REG_WRITE(PP_CYCLE, lvds_priv->savePP_CYCLE);
-	REG_WRITE(PP_CONTROL, lvds_priv->savePP_CONTROL);
-	REG_WRITE(LVDS, lvds_priv->saveLVDS);
-
-	if (lvds_priv->savePP_CONTROL & POWER_TARGET_ON) {
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
-			POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while ((pp_status & PP_ON) == 0);
-	} else {
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
-			~POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while (pp_status & PP_ON);
-	}
-}
-
-int psb_intel_lvds_mode_valid(struct drm_connector *connector,
-				 struct drm_display_mode *mode)
-{
-	struct psb_intel_output *psb_intel_output =
-				to_psb_intel_output(connector);
-	struct drm_display_mode *fixed_mode =
-	    psb_intel_output->mode_dev->panel_fixed_mode;
-
-	if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
-		fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode2;
-
-	/* just in case */
-	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-		return MODE_NO_DBLESCAN;
-
-	/* just in case */
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-		return MODE_NO_INTERLACE;
-
-	if (fixed_mode) {
-		if (mode->hdisplay > fixed_mode->hdisplay)
-			return MODE_PANEL;
-		if (mode->vdisplay > fixed_mode->vdisplay)
-			return MODE_PANEL;
-	}
-	return MODE_OK;
-}
-
-bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
-{
-	struct psb_intel_mode_device *mode_dev =
-	    enc_to_psb_intel_output(encoder)->mode_dev;
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_crtc *psb_intel_crtc =
-				to_psb_intel_crtc(encoder->crtc);
-	struct drm_encoder *tmp_encoder;
-	struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
-	struct psb_intel_output *psb_intel_output =
-					enc_to_psb_intel_output(encoder);
-
-	if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
-		panel_fixed_mode = mode_dev->panel_fixed_mode2;
-
-	/* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
-	if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) {
-		printk(KERN_ERR "Can't support LVDS on pipe A\n");
-		return false;
-	}
-	if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) {
-		printk(KERN_ERR "Must use PIPE A\n");
-		return false;
-	}
-	/* Should never happen!! */
-	list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
-			    head) {
-		if (tmp_encoder != encoder
-		    && tmp_encoder->crtc == encoder->crtc) {
-			printk(KERN_ERR "Can't enable LVDS and another "
-			       "encoder on the same pipe\n");
-			return false;
-		}
-	}
-
-	/*
-	 * If we have timings from the BIOS for the panel, put them in
-	 * to the adjusted mode.  The CRTC will be set up for this mode,
-	 * with the panel scaling set up to source from the H/VDisplay
-	 * of the original mode.
-	 */
-	if (panel_fixed_mode != NULL) {
-		adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
-		adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
-		adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
-		adjusted_mode->htotal = panel_fixed_mode->htotal;
-		adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
-		adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
-		adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
-		adjusted_mode->vtotal = panel_fixed_mode->vtotal;
-		adjusted_mode->clock = panel_fixed_mode->clock;
-		drm_mode_set_crtcinfo(adjusted_mode,
-				      CRTC_INTERLACE_HALVE_V);
-	}
-
-	/*
-	 * XXX: It would be nice to support lower refresh rates on the
-	 * panels to reduce power consumption, and perhaps match the
-	 * user's requested refresh rate.
-	 */
-
-	return true;
-}
-
-static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-	if (!gma_power_begin(dev, true))
-		return;
-
-	mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
-	mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
-					  BACKLIGHT_DUTY_CYCLE_MASK);
-
-	psb_intel_lvds_set_power(dev, output, false);
-
-	gma_power_end(dev);
-}
-
-static void psb_intel_lvds_commit(struct drm_encoder *encoder)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
-	struct psb_intel_mode_device *mode_dev = output->mode_dev;
-
-	if (mode_dev->backlight_duty_cycle == 0)
-		mode_dev->backlight_duty_cycle =
-		    psb_intel_lvds_get_max_backlight(dev);
-
-	psb_intel_lvds_set_power(dev, output, true);
-}
-
-static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 pfit_control;
-
-	/*
-	 * The LVDS pin pair will already have been turned on in the
-	 * psb_intel_crtc_mode_set since it has a large impact on the DPLL
-	 * settings.
-	 */
-
-	/*
-	 * Enable automatic panel scaling so that non-native modes fill the
-	 * screen.  Should be enabled before the pipe is enabled, according to
-	 * register description and PRM.
-	 */
-	if (mode->hdisplay != adjusted_mode->hdisplay ||
-	    mode->vdisplay != adjusted_mode->vdisplay)
-		pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
-				HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
-				HORIZ_INTERP_BILINEAR);
-	else
-		pfit_control = 0;
-
-	if (dev_priv->lvds_dither)
-		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-
-	REG_WRITE(PFIT_CONTROL, pfit_control);
-}
-
-/*
- * Detect the LVDS connection.
- *
- * This always returns CONNECTOR_STATUS_CONNECTED.
- * This connector should only have
- * been set up if the LVDS was actually connected anyway.
- */
-static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector
-						   *connector, bool force)
-{
-	return connector_status_connected;
-}
-
-/*
- * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
- */
-static int psb_intel_lvds_get_modes(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-	struct psb_intel_mode_device *mode_dev =
-					psb_intel_output->mode_dev;
-	int ret = 0;
-
-	if (!IS_MRST(dev))
-		ret = psb_intel_ddc_get_modes(psb_intel_output);
-
-	if (ret)
-		return ret;
-
-	/* Didn't get an EDID, so
-	 * Set wide sync ranges so we get all modes
-	 * handed to valid_mode for checking
-	 */
-	connector->display_info.min_vfreq = 0;
-	connector->display_info.max_vfreq = 200;
-	connector->display_info.min_hfreq = 0;
-	connector->display_info.max_hfreq = 200;
-
-	if (mode_dev->panel_fixed_mode != NULL) {
-		struct drm_display_mode *mode =
-		    drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
-		drm_mode_probed_add(connector, mode);
-		return 1;
-	}
-
-	return 0;
-}
-
-/**
- * psb_intel_lvds_destroy - unregister and free LVDS structures
- * @connector: connector to free
- *
- * Unregister the DDC bus for this connector then free the driver private
- * structure.
- */
-void psb_intel_lvds_destroy(struct drm_connector *connector)
-{
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-
-	if (psb_intel_output->ddc_bus)
-		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-	drm_sysfs_connector_remove(connector);
-	drm_connector_cleanup(connector);
-	kfree(connector);
-}
-
-int psb_intel_lvds_set_property(struct drm_connector *connector,
-				       struct drm_property *property,
-				       uint64_t value)
-{
-	struct drm_encoder *encoder = connector->encoder;
-
-	if (!encoder)
-		return -1;
-
-	if (!strcmp(property->name, "scaling mode")) {
-		struct psb_intel_crtc *crtc =
-					to_psb_intel_crtc(encoder->crtc);
-		uint64_t curval;
-
-		if (!crtc)
-			goto set_prop_error;
-
-		switch (value) {
-		case DRM_MODE_SCALE_FULLSCREEN:
-			break;
-		case DRM_MODE_SCALE_NO_SCALE:
-			break;
-		case DRM_MODE_SCALE_ASPECT:
-			break;
-		default:
-			goto set_prop_error;
-		}
-
-		if (drm_connector_property_get_value(connector,
-						     property,
-						     &curval))
-			goto set_prop_error;
-
-		if (curval == value)
-			goto set_prop_done;
-
-		if (drm_connector_property_set_value(connector,
-							property,
-							value))
-			goto set_prop_error;
-
-		if (crtc->saved_mode.hdisplay != 0 &&
-		    crtc->saved_mode.vdisplay != 0) {
-			if (!drm_crtc_helper_set_mode(encoder->crtc,
-						      &crtc->saved_mode,
-						      encoder->crtc->x,
-						      encoder->crtc->y,
-						      encoder->crtc->fb))
-				goto set_prop_error;
-		}
-	} else if (!strcmp(property->name, "backlight")) {
-		if (drm_connector_property_set_value(connector,
-							property,
-							value))
-			goto set_prop_error;
-		else {
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-			struct drm_psb_private *devp =
-						encoder->dev->dev_private;
-			struct backlight_device *bd = devp->backlight_device;
-			if (bd) {
-				bd->props.brightness = value;
-				backlight_update_status(bd);
-			}
-#endif
-		}
-	} else if (!strcmp(property->name, "DPMS")) {
-		struct drm_encoder_helper_funcs *hfuncs
-						= encoder->helper_private;
-		hfuncs->dpms(encoder, value);
-	}
-
-set_prop_done:
-	return 0;
-set_prop_error:
-	return -1;
-}
-
-static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = {
-	.dpms = psb_intel_lvds_encoder_dpms,
-	.mode_fixup = psb_intel_lvds_mode_fixup,
-	.prepare = psb_intel_lvds_prepare,
-	.mode_set = psb_intel_lvds_mode_set,
-	.commit = psb_intel_lvds_commit,
-};
-
-const struct drm_connector_helper_funcs
-				psb_intel_lvds_connector_helper_funcs = {
-	.get_modes = psb_intel_lvds_get_modes,
-	.mode_valid = psb_intel_lvds_mode_valid,
-	.best_encoder = psb_intel_best_encoder,
-};
-
-const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
-	.dpms = drm_helper_connector_dpms,
-	.save = psb_intel_lvds_save,
-	.restore = psb_intel_lvds_restore,
-	.detect = psb_intel_lvds_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.set_property = psb_intel_lvds_set_property,
-	.destroy = psb_intel_lvds_destroy,
-};
-
-
-static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = {
-	.destroy = psb_intel_lvds_enc_destroy,
-};
-
-
-
-/**
- * psb_intel_lvds_init - setup LVDS connectors on this device
- * @dev: drm device
- *
- * Create the connector, register the LVDS DDC bus, and try to figure out what
- * modes we can display on the LVDS panel (if present).
- */
-void psb_intel_lvds_init(struct drm_device *dev,
-		     struct psb_intel_mode_device *mode_dev)
-{
-	struct psb_intel_output *psb_intel_output;
-	struct psb_intel_lvds_priv *lvds_priv;
-	struct drm_connector *connector;
-	struct drm_encoder *encoder;
-	struct drm_display_mode *scan;	/* *modes, *bios_mode; */
-	struct drm_crtc *crtc;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	u32 lvds;
-	int pipe;
-
-	psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
-	if (!psb_intel_output)
-		return;
-
-	lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
-	if (!lvds_priv) {
-		kfree(psb_intel_output);
-		dev_err(dev->dev, "LVDS private allocation error\n");
-		return;
-	}
-
-	psb_intel_output->dev_priv = lvds_priv;
-	psb_intel_output->mode_dev = mode_dev;
-
-	connector = &psb_intel_output->base;
-	encoder = &psb_intel_output->enc;
-	drm_connector_init(dev, &psb_intel_output->base,
-			   &psb_intel_lvds_connector_funcs,
-			   DRM_MODE_CONNECTOR_LVDS);
-
-	drm_encoder_init(dev, &psb_intel_output->enc,
-			 &psb_intel_lvds_enc_funcs,
-			 DRM_MODE_ENCODER_LVDS);
-
-	drm_mode_connector_attach_encoder(&psb_intel_output->base,
-					  &psb_intel_output->enc);
-	psb_intel_output->type = INTEL_OUTPUT_LVDS;
-
-	drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs);
-	drm_connector_helper_add(connector,
-				 &psb_intel_lvds_connector_helper_funcs);
-	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-	connector->interlace_allowed = false;
-	connector->doublescan_allowed = false;
-
-	/*Attach connector properties*/
-	drm_connector_attach_property(connector,
-				      dev->mode_config.scaling_mode_property,
-				      DRM_MODE_SCALE_FULLSCREEN);
-	drm_connector_attach_property(connector,
-				      dev_priv->backlight_property,
-				      BRIGHTNESS_MAX_LEVEL);
-
-	/*
-	 * Set up I2C bus
-	 * FIXME: distroy i2c_bus when exit
-	 */
-	psb_intel_output->i2c_bus = psb_intel_i2c_create(dev,
-							 GPIOB,
-							 "LVDSBLC_B");
-	if (!psb_intel_output->i2c_bus) {
-		dev_printk(KERN_ERR,
-			&dev->pdev->dev, "I2C bus registration failed.\n");
-		goto failed_blc_i2c;
-	}
-	psb_intel_output->i2c_bus->slave_addr = 0x2C;
-	dev_priv->lvds_i2c_bus =  psb_intel_output->i2c_bus;
-
-	/*
-	 * LVDS discovery:
-	 * 1) check for EDID on DDC
-	 * 2) check for VBT data
-	 * 3) check to see if LVDS is already on
-	 *    if none of the above, no panel
-	 * 4) make sure lid is open
-	 *    if closed, act like it's not there for now
-	 */
-
-	/* Set up the DDC bus. */
-	psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
-							 GPIOC,
-							 "LVDSDDC_C");
-	if (!psb_intel_output->ddc_bus) {
-		dev_printk(KERN_ERR, &dev->pdev->dev,
-			   "DDC bus registration " "failed.\n");
-		goto failed_ddc;
-	}
-
-	/*
-	 * Attempt to get the fixed panel mode from DDC.  Assume that the
-	 * preferred mode is the right one.
-	 */
-	psb_intel_ddc_get_modes(psb_intel_output);
-	list_for_each_entry(scan, &connector->probed_modes, head) {
-		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
-			mode_dev->panel_fixed_mode =
-			    drm_mode_duplicate(dev, scan);
-			goto out;	/* FIXME: check for quirks */
-		}
-	}
-
-	/* Failed to get EDID, what about VBT? do we need this? */
-	if (mode_dev->vbt_mode)
-		mode_dev->panel_fixed_mode =
-		    drm_mode_duplicate(dev, mode_dev->vbt_mode);
-
-	if (!mode_dev->panel_fixed_mode)
-		if (dev_priv->lfp_lvds_vbt_mode)
-			mode_dev->panel_fixed_mode =
-				drm_mode_duplicate(dev,
-					dev_priv->lfp_lvds_vbt_mode);
-
-	/*
-	 * If we didn't get EDID, try checking if the panel is already turned
-	 * on.	If so, assume that whatever is currently programmed is the
-	 * correct mode.
-	 */
-	lvds = REG_READ(LVDS);
-	pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
-	crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
-
-	if (crtc && (lvds & LVDS_PORT_EN)) {
-		mode_dev->panel_fixed_mode =
-		    psb_intel_crtc_mode_get(dev, crtc);
-		if (mode_dev->panel_fixed_mode) {
-			mode_dev->panel_fixed_mode->type |=
-			    DRM_MODE_TYPE_PREFERRED;
-			goto out;	/* FIXME: check for quirks */
-		}
-	}
-
-	/* If we still don't have a mode after all that, give up. */
-	if (!mode_dev->panel_fixed_mode) {
-		dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
-		goto failed_find;
-	}
-
-	/*
-	 * Blacklist machines with BIOSes that list an LVDS panel without
-	 * actually having one.
-	 */
-out:
-	drm_sysfs_connector_add(connector);
-	return;
-
-failed_find:
-	if (psb_intel_output->ddc_bus)
-		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
-failed_ddc:
-	if (psb_intel_output->i2c_bus)
-		psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-failed_blc_i2c:
-	drm_encoder_cleanup(encoder);
-	drm_connector_cleanup(connector);
-	kfree(connector);
-}
-
diff --git a/drivers/staging/gma500/psb_intel_modes.c b/drivers/staging/gma500/psb_intel_modes.c
deleted file mode 100644
index bde1aff..0000000
--- a/drivers/staging/gma500/psb_intel_modes.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authers: Jesse Barnes <jesse.barnes@intel.com>
- */
-
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <drm/drmP.h>
-#include "psb_intel_drv.h"
-
-/**
- * psb_intel_ddc_probe
- *
- */
-bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output)
-{
-	u8 out_buf[] = { 0x0, 0x0 };
-	u8 buf[2];
-	int ret;
-	struct i2c_msg msgs[] = {
-		{
-		 .addr = 0x50,
-		 .flags = 0,
-		 .len = 1,
-		 .buf = out_buf,
-		 },
-		{
-		 .addr = 0x50,
-		 .flags = I2C_M_RD,
-		 .len = 1,
-		 .buf = buf,
-		 }
-	};
-
-	ret = i2c_transfer(&psb_intel_output->ddc_bus->adapter, msgs, 2);
-	if (ret == 2)
-		return true;
-
-	return false;
-}
-
-/**
- * psb_intel_ddc_get_modes - get modelist from monitor
- * @connector: DRM connector device to use
- *
- * Fetch the EDID information from @connector using the DDC bus.
- */
-int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output)
-{
-	struct edid *edid;
-	int ret = 0;
-
-	edid =
-	    drm_get_edid(&psb_intel_output->base,
-			 &psb_intel_output->ddc_bus->adapter);
-	if (edid) {
-		drm_mode_connector_update_edid_property(&psb_intel_output->
-							base, edid);
-		ret = drm_add_edid_modes(&psb_intel_output->base, edid);
-		kfree(edid);
-	}
-	return ret;
-}
diff --git a/drivers/staging/gma500/psb_intel_reg.h b/drivers/staging/gma500/psb_intel_reg.h
deleted file mode 100644
index 1ac16aa..0000000
--- a/drivers/staging/gma500/psb_intel_reg.h
+++ /dev/null
@@ -1,1235 +0,0 @@
-/*
- * Copyright (c) 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef __PSB_INTEL_REG_H__
-#define __PSB_INTEL_REG_H__
-
-#define BLC_PWM_CTL		0x61254
-#define BLC_PWM_CTL2		0x61250
-#define BLC_PWM_CTL_C		0x62254
-#define BLC_PWM_CTL2_C		0x62250
-#define BACKLIGHT_MODULATION_FREQ_SHIFT		(17)
-/*
- * This is the most significant 15 bits of the number of backlight cycles in a
- * complete cycle of the modulated backlight control.
- *
- * The actual value is this field multiplied by two.
- */
-#define BACKLIGHT_MODULATION_FREQ_MASK	(0x7fff << 17)
-#define BLM_LEGACY_MODE			(1 << 16)
-/*
- * This is the number of cycles out of the backlight modulation cycle for which
- * the backlight is on.
- *
- * This field must be no greater than the number of cycles in the complete
- * backlight modulation cycle.
- */
-#define BACKLIGHT_DUTY_CYCLE_SHIFT	(0)
-#define BACKLIGHT_DUTY_CYCLE_MASK	(0xffff)
-
-#define I915_GCFGC			0xf0
-#define I915_LOW_FREQUENCY_ENABLE	(1 << 7)
-#define I915_DISPLAY_CLOCK_190_200_MHZ	(0 << 4)
-#define I915_DISPLAY_CLOCK_333_MHZ	(4 << 4)
-#define I915_DISPLAY_CLOCK_MASK		(7 << 4)
-
-#define I855_HPLLCC			0xc0
-#define I855_CLOCK_CONTROL_MASK		(3 << 0)
-#define I855_CLOCK_133_200		(0 << 0)
-#define I855_CLOCK_100_200		(1 << 0)
-#define I855_CLOCK_100_133		(2 << 0)
-#define I855_CLOCK_166_250		(3 << 0)
-
-/* I830 CRTC registers */
-#define HTOTAL_A		0x60000
-#define HBLANK_A		0x60004
-#define HSYNC_A			0x60008
-#define VTOTAL_A		0x6000c
-#define VBLANK_A		0x60010
-#define VSYNC_A			0x60014
-#define PIPEASRC		0x6001c
-#define BCLRPAT_A		0x60020
-#define VSYNCSHIFT_A		0x60028
-
-#define HTOTAL_B		0x61000
-#define HBLANK_B		0x61004
-#define HSYNC_B			0x61008
-#define VTOTAL_B		0x6100c
-#define VBLANK_B		0x61010
-#define VSYNC_B			0x61014
-#define PIPEBSRC		0x6101c
-#define BCLRPAT_B		0x61020
-#define VSYNCSHIFT_B		0x61028
-
-#define HTOTAL_C		0x62000
-#define HBLANK_C		0x62004
-#define HSYNC_C			0x62008
-#define VTOTAL_C		0x6200c
-#define VBLANK_C		0x62010
-#define VSYNC_C			0x62014
-#define PIPECSRC		0x6201c
-#define BCLRPAT_C		0x62020
-#define VSYNCSHIFT_C		0x62028
-
-#define PP_STATUS		0x61200
-# define PP_ON				(1 << 31)
-/*
- * Indicates that all dependencies of the panel are on:
- *
- * - PLL enabled
- * - pipe enabled
- * - LVDS/DVOB/DVOC on
- */
-#define PP_READY			(1 << 30)
-#define PP_SEQUENCE_NONE		(0 << 28)
-#define PP_SEQUENCE_ON			(1 << 28)
-#define PP_SEQUENCE_OFF			(2 << 28)
-#define PP_SEQUENCE_MASK		0x30000000
-#define PP_CONTROL		0x61204
-#define POWER_TARGET_ON			(1 << 0)
-
-#define LVDSPP_ON		0x61208
-#define LVDSPP_OFF		0x6120c
-#define PP_CYCLE		0x61210
-
-#define PFIT_CONTROL		0x61230
-#define PFIT_ENABLE			(1 << 31)
-#define PFIT_PIPE_MASK			(3 << 29)
-#define PFIT_PIPE_SHIFT			29
-#define PFIT_SCALING_MODE_PILLARBOX	(1 << 27)
-#define PFIT_SCALING_MODE_LETTERBOX	(3 << 26)
-#define VERT_INTERP_DISABLE		(0 << 10)
-#define VERT_INTERP_BILINEAR		(1 << 10)
-#define VERT_INTERP_MASK		(3 << 10)
-#define VERT_AUTO_SCALE			(1 << 9)
-#define HORIZ_INTERP_DISABLE		(0 << 6)
-#define HORIZ_INTERP_BILINEAR		(1 << 6)
-#define HORIZ_INTERP_MASK		(3 << 6)
-#define HORIZ_AUTO_SCALE		(1 << 5)
-#define PANEL_8TO6_DITHER_ENABLE	(1 << 3)
-
-#define PFIT_PGM_RATIOS		0x61234
-#define PFIT_VERT_SCALE_MASK			0xfff00000
-#define PFIT_HORIZ_SCALE_MASK			0x0000fff0
-
-#define PFIT_AUTO_RATIOS	0x61238
-
-#define DPLL_A			0x06014
-#define DPLL_B			0x06018
-#define DPLL_VCO_ENABLE			(1 << 31)
-#define DPLL_DVO_HIGH_SPEED		(1 << 30)
-#define DPLL_SYNCLOCK_ENABLE		(1 << 29)
-#define DPLL_VGA_MODE_DIS		(1 << 28)
-#define DPLLB_MODE_DAC_SERIAL		(1 << 26)	/* i915 */
-#define DPLLB_MODE_LVDS			(2 << 26)	/* i915 */
-#define DPLL_MODE_MASK			(3 << 26)
-#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10	(0 << 24)	/* i915 */
-#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5	(1 << 24)	/* i915 */
-#define DPLLB_LVDS_P2_CLOCK_DIV_14	(0 << 24)	/* i915 */
-#define DPLLB_LVDS_P2_CLOCK_DIV_7	(1 << 24)	/* i915 */
-#define DPLL_P2_CLOCK_DIV_MASK		0x03000000	/* i915 */
-#define DPLL_FPA01_P1_POST_DIV_MASK	0x00ff0000	/* i915 */
-#define DPLL_LOCK			(1 << 15)	/* CDV */
-
-/*
- *  The i830 generation, in DAC/serial mode, defines p1 as two plus this
- * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
- */
-# define DPLL_FPA01_P1_POST_DIV_MASK_I830	0x001f0000
-/*
- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
- * this field (only one bit may be set).
- */
-#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS	0x003f0000
-#define DPLL_FPA01_P1_POST_DIV_SHIFT	16
-#define PLL_P2_DIVIDE_BY_4		(1 << 23)	/* i830, required
-							 * in DVO non-gang */
-# define PLL_P1_DIVIDE_BY_TWO		(1 << 21)	/* i830 */
-#define PLL_REF_INPUT_DREFCLK		(0 << 13)
-#define PLL_REF_INPUT_TVCLKINA		(1 << 13)	/* i830 */
-#define PLL_REF_INPUT_TVCLKINBC		(2 << 13)	/* SDVO
-								 * TVCLKIN */
-#define PLLB_REF_INPUT_SPREADSPECTRUMIN	(3 << 13)
-#define PLL_REF_INPUT_MASK		(3 << 13)
-#define PLL_LOAD_PULSE_PHASE_SHIFT	9
-/*
- * Parallel to Serial Load Pulse phase selection.
- * Selects the phase for the 10X DPLL clock for the PCIe
- * digital display port. The range is 4 to 13; 10 or more
- * is just a flip delay. The default is 6
- */
-#define PLL_LOAD_PULSE_PHASE_MASK	(0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
-#define DISPLAY_RATE_SELECT_FPA1	(1 << 8)
-
-/*
- * SDVO multiplier for 945G/GM. Not used on 965.
- *
- * DPLL_MD_UDI_MULTIPLIER_MASK
- */
-#define SDVO_MULTIPLIER_MASK		0x000000ff
-#define SDVO_MULTIPLIER_SHIFT_HIRES	4
-#define SDVO_MULTIPLIER_SHIFT_VGA	0
-
-/*
- * PLL_MD
- */
-/* Pipe A SDVO/UDI clock multiplier/divider register for G965. */
-#define DPLL_A_MD		0x0601c
-/* Pipe B SDVO/UDI clock multiplier/divider register for G965. */
-#define DPLL_B_MD		0x06020
-/*
- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
- *
- * Value is pixels minus 1.  Must be set to 1 pixel for SDVO.
- */
-#define DPLL_MD_UDI_DIVIDER_MASK	0x3f000000
-#define DPLL_MD_UDI_DIVIDER_SHIFT	24
-/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
-#define DPLL_MD_VGA_UDI_DIVIDER_MASK	0x003f0000
-#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT	16
-/*
- * SDVO/UDI pixel multiplier.
- *
- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
- * clock rate is 10 times the DPLL clock.  At low resolution/refresh rate
- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
- * dummy bytes in the datastream at an increased clock rate, with both sides of
- * the link knowing how many bytes are fill.
- *
- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
- * rate to 130Mhz to get a bus rate of 1.30Ghz.  The DPLL clock rate would be
- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
- * through an SDVO command.
- *
- * This register field has values of multiplication factor minus 1, with
- * a maximum multiplier of 5 for SDVO.
- */
-#define DPLL_MD_UDI_MULTIPLIER_MASK	0x00003f00
-#define DPLL_MD_UDI_MULTIPLIER_SHIFT	8
-/*
- * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
- * This best be set to the default value (3) or the CRT won't work. No,
- * I don't entirely understand what this does...
- */
-#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK	0x0000003f
-#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
-
-#define DPLL_TEST		0x606c
-#define DPLLB_TEST_SDVO_DIV_1		(0 << 22)
-#define DPLLB_TEST_SDVO_DIV_2		(1 << 22)
-#define DPLLB_TEST_SDVO_DIV_4		(2 << 22)
-#define DPLLB_TEST_SDVO_DIV_MASK	(3 << 22)
-#define DPLLB_TEST_N_BYPASS		(1 << 19)
-#define DPLLB_TEST_M_BYPASS		(1 << 18)
-#define DPLLB_INPUT_BUFFER_ENABLE	(1 << 16)
-#define DPLLA_TEST_N_BYPASS		(1 << 3)
-#define DPLLA_TEST_M_BYPASS		(1 << 2)
-#define DPLLA_INPUT_BUFFER_ENABLE	(1 << 0)
-
-#define ADPA			0x61100
-#define ADPA_DAC_ENABLE			(1 << 31)
-#define ADPA_DAC_DISABLE		0
-#define ADPA_PIPE_SELECT_MASK		(1 << 30)
-#define ADPA_PIPE_A_SELECT		0
-#define ADPA_PIPE_B_SELECT		(1 << 30)
-#define ADPA_USE_VGA_HVPOLARITY		(1 << 15)
-#define ADPA_SETS_HVPOLARITY		0
-#define ADPA_VSYNC_CNTL_DISABLE		(1 << 11)
-#define ADPA_VSYNC_CNTL_ENABLE		0
-#define ADPA_HSYNC_CNTL_DISABLE		(1 << 10)
-#define ADPA_HSYNC_CNTL_ENABLE		0
-#define ADPA_VSYNC_ACTIVE_HIGH		(1 << 4)
-#define ADPA_VSYNC_ACTIVE_LOW		0
-#define ADPA_HSYNC_ACTIVE_HIGH		(1 << 3)
-#define ADPA_HSYNC_ACTIVE_LOW		0
-
-#define FPA0			0x06040
-#define FPA1			0x06044
-#define FPB0			0x06048
-#define FPB1			0x0604c
-#define FP_N_DIV_MASK			0x003f0000
-#define FP_N_DIV_SHIFT			16
-#define FP_M1_DIV_MASK			0x00003f00
-#define FP_M1_DIV_SHIFT			8
-#define FP_M2_DIV_MASK			0x0000003f
-#define FP_M2_DIV_SHIFT			0
-
-#define PORT_HOTPLUG_EN		0x61110
-#define SDVOB_HOTPLUG_INT_EN		(1 << 26)
-#define SDVOC_HOTPLUG_INT_EN		(1 << 25)
-#define TV_HOTPLUG_INT_EN		(1 << 18)
-#define CRT_HOTPLUG_INT_EN		(1 << 9)
-#define CRT_HOTPLUG_FORCE_DETECT	(1 << 3)
-/* CDV.. */
-#define CRT_HOTPLUG_ACTIVATION_PERIOD_64	(1 << 8)
-#define CRT_HOTPLUG_DAC_ON_TIME_2M		(0 << 7)
-#define CRT_HOTPLUG_DAC_ON_TIME_4M		(1 << 7)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_40		(0 << 5)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_50		(1 << 5)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_60		(2 << 5)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_70		(3 << 5)
-#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK	(3 << 5)
-#define CRT_HOTPLUG_DETECT_DELAY_1G		(0 << 4)
-#define CRT_HOTPLUG_DETECT_DELAY_2G		(1 << 4)
-#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV	(0 << 2)
-#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
-#define CRT_HOTPLUG_DETECT_MASK			0x000000F8
-
-#define PORT_HOTPLUG_STAT	0x61114
-#define CRT_HOTPLUG_INT_STATUS		(1 << 11)
-#define TV_HOTPLUG_INT_STATUS		(1 << 10)
-#define CRT_HOTPLUG_MONITOR_MASK	(3 << 8)
-#define CRT_HOTPLUG_MONITOR_COLOR	(3 << 8)
-#define CRT_HOTPLUG_MONITOR_MONO	(2 << 8)
-#define CRT_HOTPLUG_MONITOR_NONE	(0 << 8)
-#define SDVOC_HOTPLUG_INT_STATUS	(1 << 7)
-#define SDVOB_HOTPLUG_INT_STATUS	(1 << 6)
-
-#define SDVOB			0x61140
-#define SDVOC			0x61160
-#define SDVO_ENABLE			(1 << 31)
-#define SDVO_PIPE_B_SELECT		(1 << 30)
-#define SDVO_STALL_SELECT		(1 << 29)
-#define SDVO_INTERRUPT_ENABLE		(1 << 26)
-
-/**
- * 915G/GM SDVO pixel multiplier.
- *
- * Programmed value is multiplier - 1, up to 5x.
- *
- * DPLL_MD_UDI_MULTIPLIER_MASK
- */
-#define SDVO_PORT_MULTIPLY_MASK		(7 << 23)
-#define SDVO_PORT_MULTIPLY_SHIFT	23
-#define SDVO_PHASE_SELECT_MASK		(15 << 19)
-#define SDVO_PHASE_SELECT_DEFAULT	(6 << 19)
-#define SDVO_CLOCK_OUTPUT_INVERT	(1 << 18)
-#define SDVOC_GANG_MODE			(1 << 16)
-#define SDVO_BORDER_ENABLE		(1 << 7)
-#define SDVOB_PCIE_CONCURRENCY		(1 << 3)
-#define SDVO_DETECTED			(1 << 2)
-/* Bits to be preserved when writing */
-#define SDVOB_PRESERVE_MASK		((1 << 17) | (1 << 16) | (1 << 14))
-#define SDVOC_PRESERVE_MASK		(1 << 17)
-
-/*
- * This register controls the LVDS output enable, pipe selection, and data
- * format selection.
- *
- * All of the clock/data pairs are force powered down by power sequencing.
- */
-#define LVDS			0x61180
-/*
- * Enables the LVDS port.  This bit must be set before DPLLs are enabled, as
- * the DPLL semantics change when the LVDS is assigned to that pipe.
- */
-#define LVDS_PORT_EN			(1 << 31)
-/* Selects pipe B for LVDS data.  Must be set on pre-965. */
-#define LVDS_PIPEB_SELECT		(1 << 30)
-
-/* Turns on border drawing to allow centered display. */
-#define LVDS_BORDER_EN			(1 << 15)
-
-/*
- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
- * pixel.
- */
-#define LVDS_A0A2_CLKA_POWER_MASK	(3 << 8)
-#define LVDS_A0A2_CLKA_POWER_DOWN	(0 << 8)
-#define LVDS_A0A2_CLKA_POWER_UP		(3 << 8)
-/*
- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
- * mode.  Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
- * on.
- */
-#define LVDS_A3_POWER_MASK		(3 << 6)
-#define LVDS_A3_POWER_DOWN		(0 << 6)
-#define LVDS_A3_POWER_UP		(3 << 6)
-/*
- * Controls the CLKB pair.  This should only be set when LVDS_B0B3_POWER_UP
- * is set.
- */
-#define LVDS_CLKB_POWER_MASK		(3 << 4)
-#define LVDS_CLKB_POWER_DOWN		(0 << 4)
-#define LVDS_CLKB_POWER_UP		(3 << 4)
-/*
- * Controls the B0-B3 data pairs.  This must be set to match the DPLL p2
- * setting for whether we are in dual-channel mode.  The B3 pair will
- * additionally only be powered up when LVDS_A3_POWER_UP is set.
- */
-#define LVDS_B0B3_POWER_MASK		(3 << 2)
-#define LVDS_B0B3_POWER_DOWN		(0 << 2)
-#define LVDS_B0B3_POWER_UP		(3 << 2)
-
-#define PIPEACONF		0x70008
-#define PIPEACONF_ENABLE		(1 << 31)
-#define PIPEACONF_DISABLE		0
-#define PIPEACONF_DOUBLE_WIDE		(1 << 30)
-#define PIPECONF_ACTIVE			(1 << 30)
-#define I965_PIPECONF_ACTIVE		(1 << 30)
-#define PIPECONF_DSIPLL_LOCK		(1 << 29)
-#define PIPEACONF_SINGLE_WIDE		0
-#define PIPEACONF_PIPE_UNLOCKED		0
-#define PIPEACONF_DSR			(1 << 26)
-#define PIPEACONF_PIPE_LOCKED		(1 << 25)
-#define PIPEACONF_PALETTE		0
-#define PIPECONF_FORCE_BORDER		(1 << 25)
-#define PIPEACONF_GAMMA			(1 << 24)
-#define PIPECONF_PROGRESSIVE		(0 << 21)
-#define PIPECONF_INTERLACE_W_FIELD_INDICATION	(6 << 21)
-#define PIPECONF_INTERLACE_FIELD_0_ONLY		(7 << 21)
-#define PIPECONF_PLANE_OFF		(1 << 19)
-#define PIPECONF_CURSOR_OFF		(1 << 18)
-
-#define PIPEBCONF		0x71008
-#define PIPEBCONF_ENABLE		(1 << 31)
-#define PIPEBCONF_DISABLE		0
-#define PIPEBCONF_DOUBLE_WIDE		(1 << 30)
-#define PIPEBCONF_DISABLE		0
-#define PIPEBCONF_GAMMA			(1 << 24)
-#define PIPEBCONF_PALETTE		0
-
-#define PIPECCONF		0x72008
-
-#define PIPEBGCMAXRED		0x71010
-#define PIPEBGCMAXGREEN		0x71014
-#define PIPEBGCMAXBLUE		0x71018
-
-#define PIPEASTAT		0x70024
-#define PIPEBSTAT		0x71024
-#define PIPECSTAT		0x72024
-#define PIPE_VBLANK_INTERRUPT_STATUS		(1UL << 1)
-#define PIPE_START_VBLANK_INTERRUPT_STATUS	(1UL << 2)
-#define PIPE_VBLANK_CLEAR			(1 << 1)
-#define PIPE_VBLANK_STATUS			(1 << 1)
-#define PIPE_TE_STATUS				(1UL << 6)
-#define PIPE_DPST_EVENT_STATUS			(1UL << 7)
-#define PIPE_VSYNC_CLEAR			(1UL << 9)
-#define PIPE_VSYNC_STATUS			(1UL << 9)
-#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS		(1UL << 10)
-#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS	(1UL << 11)
-#define PIPE_VBLANK_INTERRUPT_ENABLE		(1UL << 17)
-#define PIPE_START_VBLANK_INTERRUPT_ENABLE	(1UL << 18)
-#define PIPE_TE_ENABLE				(1UL << 22)
-#define PIPE_DPST_EVENT_ENABLE			(1UL << 23)
-#define PIPE_VSYNC_ENABL			(1UL << 25)
-#define PIPE_HDMI_AUDIO_UNDERRUN		(1UL << 26)
-#define PIPE_HDMI_AUDIO_BUFFER_DONE		(1UL << 27)
-#define PIPE_HDMI_AUDIO_INT_MASK		(PIPE_HDMI_AUDIO_UNDERRUN | \
-						PIPE_HDMI_AUDIO_BUFFER_DONE)
-#define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16))
-#define PIPE_VBLANK_MASK ((1 << 25)|(1 << 24)|(1 << 18)|(1 << 17))
-#define HISTOGRAM_INT_CONTROL		0x61268
-#define HISTOGRAM_BIN_DATA		0X61264
-#define HISTOGRAM_LOGIC_CONTROL		0x61260
-#define PWM_CONTROL_LOGIC		0x61250
-#define PIPE_HOTPLUG_INTERRUPT_STATUS		(1UL << 10)
-#define HISTOGRAM_INTERRUPT_ENABLE		(1UL << 31)
-#define HISTOGRAM_LOGIC_ENABLE			(1UL << 31)
-#define PWM_LOGIC_ENABLE			(1UL << 31)
-#define PWM_PHASEIN_ENABLE			(1UL << 25)
-#define PWM_PHASEIN_INT_ENABLE			(1UL << 24)
-#define PWM_PHASEIN_VB_COUNT			0x00001f00
-#define PWM_PHASEIN_INC				0x0000001f
-#define HISTOGRAM_INT_CTRL_CLEAR		(1UL << 30)
-#define DPST_YUV_LUMA_MODE			0
-
-struct dpst_ie_histogram_control {
-	union {
-		uint32_t data;
-		struct {
-			uint32_t bin_reg_index:7;
-			uint32_t reserved:4;
-			uint32_t bin_reg_func_select:1;
-			uint32_t sync_to_phase_in:1;
-			uint32_t alt_enhancement_mode:2;
-			uint32_t reserved1:1;
-			uint32_t sync_to_phase_in_count:8;
-			uint32_t histogram_mode_select:1;
-			uint32_t reserved2:4;
-			uint32_t ie_pipe_assignment:1;
-			uint32_t ie_mode_table_enabled:1;
-			uint32_t ie_histogram_enable:1;
-		};
-	};
-};
-
-struct dpst_guardband {
-	union {
-		uint32_t data;
-		struct {
-			uint32_t guardband:22;
-			uint32_t guardband_interrupt_delay:8;
-			uint32_t interrupt_status:1;
-			uint32_t interrupt_enable:1;
-		};
-	};
-};
-
-#define PIPEAFRAMEHIGH		0x70040
-#define PIPEAFRAMEPIXEL		0x70044
-#define PIPEBFRAMEHIGH		0x71040
-#define PIPEBFRAMEPIXEL		0x71044
-#define PIPECFRAMEHIGH		0x72040
-#define PIPECFRAMEPIXEL		0x72044
-#define PIPE_FRAME_HIGH_MASK	0x0000ffff
-#define PIPE_FRAME_HIGH_SHIFT	0
-#define PIPE_FRAME_LOW_MASK	0xff000000
-#define PIPE_FRAME_LOW_SHIFT	24
-#define PIPE_PIXEL_MASK		0x00ffffff
-#define PIPE_PIXEL_SHIFT	0
-
-#define DSPARB			0x70030
-#define DSPFW1			0x70034
-#define DSPFW2			0x70038
-#define DSPFW3			0x7003c
-#define DSPFW4			0x70050
-#define DSPFW5			0x70054
-#define DSPFW6			0x70058
-#define DSPCHICKENBIT		0x70400
-#define DSPACNTR		0x70180
-#define DSPBCNTR		0x71180
-#define DSPCCNTR		0x72180
-#define DISPLAY_PLANE_ENABLE			(1 << 31)
-#define DISPLAY_PLANE_DISABLE			0
-#define DISPPLANE_GAMMA_ENABLE			(1 << 30)
-#define DISPPLANE_GAMMA_DISABLE			0
-#define DISPPLANE_PIXFORMAT_MASK		(0xf << 26)
-#define DISPPLANE_8BPP				(0x2 << 26)
-#define DISPPLANE_15_16BPP			(0x4 << 26)
-#define DISPPLANE_16BPP				(0x5 << 26)
-#define DISPPLANE_32BPP_NO_ALPHA		(0x6 << 26)
-#define DISPPLANE_32BPP				(0x7 << 26)
-#define DISPPLANE_STEREO_ENABLE			(1 << 25)
-#define DISPPLANE_STEREO_DISABLE		0
-#define DISPPLANE_SEL_PIPE_MASK			(1 << 24)
-#define DISPPLANE_SEL_PIPE_POS			24
-#define DISPPLANE_SEL_PIPE_A			0
-#define DISPPLANE_SEL_PIPE_B			(1 << 24)
-#define DISPPLANE_SRC_KEY_ENABLE		(1 << 22)
-#define DISPPLANE_SRC_KEY_DISABLE		0
-#define DISPPLANE_LINE_DOUBLE			(1 << 20)
-#define DISPPLANE_NO_LINE_DOUBLE		0
-#define DISPPLANE_STEREO_POLARITY_FIRST		0
-#define DISPPLANE_STEREO_POLARITY_SECOND	(1 << 18)
-/* plane B only */
-#define DISPPLANE_ALPHA_TRANS_ENABLE		(1 << 15)
-#define DISPPLANE_ALPHA_TRANS_DISABLE		0
-#define DISPPLANE_SPRITE_ABOVE_DISPLAYA		0
-#define DISPPLANE_SPRITE_ABOVE_OVERLAY		(1)
-#define DISPPLANE_BOTTOM			(4)
-
-#define DSPABASE		0x70184
-#define DSPALINOFF		0x70184
-#define DSPASTRIDE		0x70188
-
-#define DSPBBASE		0x71184
-#define DSPBLINOFF		0X71184
-#define DSPBADDR		DSPBBASE
-#define DSPBSTRIDE		0x71188
-
-#define DSPCBASE		0x72184
-#define DSPCLINOFF		0x72184
-#define DSPCSTRIDE		0x72188
-
-#define DSPAKEYVAL		0x70194
-#define DSPAKEYMASK		0x70198
-
-#define DSPAPOS			0x7018C	/* reserved */
-#define DSPASIZE		0x70190
-#define DSPBPOS			0x7118C
-#define DSPBSIZE		0x71190
-#define DSPCPOS			0x7218C
-#define DSPCSIZE		0x72190
-
-#define DSPASURF		0x7019C
-#define DSPATILEOFF		0x701A4
-
-#define DSPBSURF		0x7119C
-#define DSPBTILEOFF		0x711A4
-
-#define DSPCSURF		0x7219C
-#define DSPCTILEOFF		0x721A4
-#define DSPCKEYMAXVAL		0x721A0
-#define DSPCKEYMINVAL		0x72194
-#define DSPCKEYMSK		0x72198
-
-#define VGACNTRL		0x71400
-#define VGA_DISP_DISABLE		(1 << 31)
-#define VGA_2X_MODE			(1 << 30)
-#define VGA_PIPE_B_SELECT		(1 << 29)
-
-/*
- * Overlay registers
- */
-#define OV_C_OFFSET		0x08000
-#define OV_OVADD		0x30000
-#define OV_DOVASTA		0x30008
-# define OV_PIPE_SELECT			((1 << 6)|(1 << 7))
-# define OV_PIPE_SELECT_POS		6
-# define OV_PIPE_A			0
-# define OV_PIPE_C			1
-#define OV_OGAMC5		0x30010
-#define OV_OGAMC4		0x30014
-#define OV_OGAMC3		0x30018
-#define OV_OGAMC2		0x3001C
-#define OV_OGAMC1		0x30020
-#define OV_OGAMC0		0x30024
-#define OVC_OVADD		0x38000
-#define OVC_DOVCSTA		0x38008
-#define OVC_OGAMC5		0x38010
-#define OVC_OGAMC4		0x38014
-#define OVC_OGAMC3		0x38018
-#define OVC_OGAMC2		0x3801C
-#define OVC_OGAMC1		0x38020
-#define OVC_OGAMC0		0x38024
-
-/*
- * Some BIOS scratch area registers.  The 845 (and 830?) store the amount
- * of video memory available to the BIOS in SWF1.
- */
-#define SWF0			0x71410
-#define SWF1			0x71414
-#define SWF2			0x71418
-#define SWF3			0x7141c
-#define SWF4			0x71420
-#define SWF5			0x71424
-#define SWF6			0x71428
-
-/*
- * 855 scratch registers.
- */
-#define SWF00			0x70410
-#define SWF01			0x70414
-#define SWF02			0x70418
-#define SWF03			0x7041c
-#define SWF04			0x70420
-#define SWF05			0x70424
-#define SWF06			0x70428
-
-#define SWF10			SWF0
-#define SWF11			SWF1
-#define SWF12			SWF2
-#define SWF13			SWF3
-#define SWF14			SWF4
-#define SWF15			SWF5
-#define SWF16			SWF6
-
-#define SWF30			0x72414
-#define SWF31			0x72418
-#define SWF32			0x7241c
-
-
-/*
- * Palette registers
- */
-#define PALETTE_A		0x0a000
-#define PALETTE_B		0x0a800
-#define PALETTE_C		0x0ac00
-
-/* Cursor A & B regs */
-#define CURACNTR		0x70080
-#define CURSOR_MODE_DISABLE		0x00
-#define CURSOR_MODE_64_32B_AX		0x07
-#define CURSOR_MODE_64_ARGB_AX		((1 << 5) | CURSOR_MODE_64_32B_AX)
-#define MCURSOR_GAMMA_ENABLE		(1 << 26)
-#define CURABASE		0x70084
-#define CURAPOS			0x70088
-#define CURSOR_POS_MASK			0x007FF
-#define CURSOR_POS_SIGN			0x8000
-#define CURSOR_X_SHIFT			0
-#define CURSOR_Y_SHIFT			16
-#define CURBCNTR		0x700c0
-#define CURBBASE		0x700c4
-#define CURBPOS			0x700c8
-#define CURCCNTR		0x700e0
-#define CURCBASE		0x700e4
-#define CURCPOS			0x700e8
-
-/*
- * Interrupt Registers
- */
-#define IER			0x020a0
-#define IIR			0x020a4
-#define IMR			0x020a8
-#define ISR			0x020ac
-
-/*
- * MOORESTOWN delta registers
- */
-#define MRST_DPLL_A		0x0f014
-#define MDFLD_DPLL_B		0x0f018
-#define MDFLD_INPUT_REF_SEL		(1 << 14)
-#define MDFLD_VCO_SEL			(1 << 16)
-#define DPLLA_MODE_LVDS			(2 << 26)	/* mrst */
-#define MDFLD_PLL_LATCHEN		(1 << 28)
-#define MDFLD_PWR_GATE_EN		(1 << 30)
-#define MDFLD_P1_MASK			(0x1FF << 17)
-#define MRST_FPA0		0x0f040
-#define MRST_FPA1		0x0f044
-#define MDFLD_DPLL_DIV0		0x0f048
-#define MDFLD_DPLL_DIV1		0x0f04c
-#define MRST_PERF_MODE		0x020f4
-
-/*
- * MEDFIELD HDMI registers
- */
-#define HDMIPHYMISCCTL		0x61134
-#define HDMI_PHY_POWER_DOWN		0x7f
-#define HDMIB_CONTROL		0x61140
-#define HDMIB_PORT_EN			(1 << 31)
-#define HDMIB_PIPE_B_SELECT		(1 << 30)
-#define HDMIB_NULL_PACKET		(1 << 9)
-#define HDMIB_HDCP_PORT			(1 << 5)
-
-/* #define LVDS			0x61180 */
-#define MRST_PANEL_8TO6_DITHER_ENABLE	(1 << 25)
-#define MRST_PANEL_24_DOT_1_FORMAT	(1 << 24)
-#define LVDS_A3_POWER_UP_0_OUTPUT	(1 << 6)
-
-#define MIPI			0x61190
-#define MIPI_C			0x62190
-#define MIPI_PORT_EN			(1 << 31)
-/* Turns on border drawing to allow centered display. */
-#define SEL_FLOPPED_HSTX		(1 << 23)
-#define PASS_FROM_SPHY_TO_AFE		(1 << 16)
-#define MIPI_BORDER_EN			(1 << 15)
-#define MIPIA_3LANE_MIPIC_1LANE		0x1
-#define MIPIA_2LANE_MIPIC_2LANE		0x2
-#define TE_TRIGGER_DSI_PROTOCOL		(1 << 2)
-#define TE_TRIGGER_GPIO_PIN		(1 << 3)
-#define MIPI_TE_COUNT		0x61194
-
-/* #define PP_CONTROL	0x61204 */
-#define POWER_DOWN_ON_RESET		(1 << 1)
-
-/* #define PFIT_CONTROL	0x61230 */
-#define PFIT_PIPE_SELECT		(3 << 29)
-#define PFIT_PIPE_SELECT_SHIFT		(29)
-
-/* #define BLC_PWM_CTL		0x61254 */
-#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT	(16)
-#define MRST_BACKLIGHT_MODULATION_FREQ_MASK	(0xffff << 16)
-
-/* #define PIPEACONF 0x70008 */
-#define PIPEACONF_PIPE_STATE		(1 << 30)
-/* #define DSPACNTR		0x70180 */
-
-#define MRST_DSPABASE		0x7019c
-#define MRST_DSPBBASE		0x7119c
-#define MDFLD_DSPCBASE		0x7219c
-
-/*
- * Moorestown registers.
- */
-
-/*
- *	MIPI IP registers
- */
-#define MIPIC_REG_OFFSET		0x800
-
-#define DEVICE_READY_REG		0xb000
-#define LP_OUTPUT_HOLD				(1 << 16)
-#define EXIT_ULPS_DEV_READY			0x3
-#define LP_OUTPUT_HOLD_RELEASE			0x810000
-# define ENTERING_ULPS				(2 << 1)
-# define EXITING_ULPS				(1 << 1)
-# define ULPS_MASK				(3 << 1)
-# define BUS_POSSESSION				(1 << 3)
-#define INTR_STAT_REG			0xb004
-#define RX_SOT_ERROR				(1 << 0)
-#define RX_SOT_SYNC_ERROR			(1 << 1)
-#define RX_ESCAPE_MODE_ENTRY_ERROR		(1 << 3)
-#define RX_LP_TX_SYNC_ERROR			(1 << 4)
-#define RX_HS_RECEIVE_TIMEOUT_ERROR		(1 << 5)
-#define RX_FALSE_CONTROL_ERROR			(1 << 6)
-#define RX_ECC_SINGLE_BIT_ERROR			(1 << 7)
-#define RX_ECC_MULTI_BIT_ERROR			(1 << 8)
-#define RX_CHECKSUM_ERROR			(1 << 9)
-#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED		(1 << 10)
-#define RX_DSI_VC_ID_INVALID			(1 << 11)
-#define TX_FALSE_CONTROL_ERROR			(1 << 12)
-#define TX_ECC_SINGLE_BIT_ERROR			(1 << 13)
-#define TX_ECC_MULTI_BIT_ERROR			(1 << 14)
-#define TX_CHECKSUM_ERROR			(1 << 15)
-#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED		(1 << 16)
-#define TX_DSI_VC_ID_INVALID			(1 << 17)
-#define HIGH_CONTENTION				(1 << 18)
-#define LOW_CONTENTION				(1 << 19)
-#define DPI_FIFO_UNDER_RUN			(1 << 20)
-#define HS_TX_TIMEOUT				(1 << 21)
-#define LP_RX_TIMEOUT				(1 << 22)
-#define TURN_AROUND_ACK_TIMEOUT			(1 << 23)
-#define ACK_WITH_NO_ERROR			(1 << 24)
-#define HS_GENERIC_WR_FIFO_FULL			(1 << 27)
-#define LP_GENERIC_WR_FIFO_FULL			(1 << 28)
-#define SPL_PKT_SENT				(1 << 30)
-#define INTR_EN_REG			0xb008
-#define DSI_FUNC_PRG_REG		0xb00c
-#define DPI_CHANNEL_NUMBER_POS			0x03
-#define DBI_CHANNEL_NUMBER_POS			0x05
-#define FMT_DPI_POS				0x07
-#define FMT_DBI_POS				0x0A
-#define DBI_DATA_WIDTH_POS			0x0D
-
-/* DPI PIXEL FORMATS */
-#define RGB_565_FMT				0x01	/* RGB 565 FORMAT */
-#define RGB_666_FMT				0x02	/* RGB 666 FORMAT */
-#define LRGB_666_FMT				0x03	/* RGB LOOSELY PACKED
-							 * 666 FORMAT
-							 */
-#define RGB_888_FMT				0x04	/* RGB 888 FORMAT */
-#define VIRTUAL_CHANNEL_NUMBER_0		0x00	/* Virtual channel 0 */
-#define VIRTUAL_CHANNEL_NUMBER_1		0x01	/* Virtual channel 1 */
-#define VIRTUAL_CHANNEL_NUMBER_2		0x02	/* Virtual channel 2 */
-#define VIRTUAL_CHANNEL_NUMBER_3		0x03	/* Virtual channel 3 */
-
-#define DBI_NOT_SUPPORTED			0x00	/* command mode
-							 * is not supported
-							 */
-#define DBI_DATA_WIDTH_16BIT			0x01	/* 16 bit data */
-#define DBI_DATA_WIDTH_9BIT			0x02	/* 9 bit data */
-#define DBI_DATA_WIDTH_8BIT			0x03	/* 8 bit data */
-#define DBI_DATA_WIDTH_OPT1			0x04	/* option 1 */
-#define DBI_DATA_WIDTH_OPT2			0x05	/* option 2 */
-
-#define HS_TX_TIMEOUT_REG		0xb010
-#define LP_RX_TIMEOUT_REG		0xb014
-#define TURN_AROUND_TIMEOUT_REG		0xb018
-#define DEVICE_RESET_REG		0xb01C
-#define DPI_RESOLUTION_REG		0xb020
-#define RES_V_POS				0x10
-#define DBI_RESOLUTION_REG		0xb024 /* Reserved for MDFLD */
-#define HORIZ_SYNC_PAD_COUNT_REG	0xb028
-#define HORIZ_BACK_PORCH_COUNT_REG	0xb02C
-#define HORIZ_FRONT_PORCH_COUNT_REG	0xb030
-#define HORIZ_ACTIVE_AREA_COUNT_REG	0xb034
-#define VERT_SYNC_PAD_COUNT_REG		0xb038
-#define VERT_BACK_PORCH_COUNT_REG	0xb03c
-#define VERT_FRONT_PORCH_COUNT_REG	0xb040
-#define HIGH_LOW_SWITCH_COUNT_REG	0xb044
-#define DPI_CONTROL_REG			0xb048
-#define DPI_SHUT_DOWN				(1 << 0)
-#define DPI_TURN_ON				(1 << 1)
-#define DPI_COLOR_MODE_ON			(1 << 2)
-#define DPI_COLOR_MODE_OFF			(1 << 3)
-#define DPI_BACK_LIGHT_ON			(1 << 4)
-#define DPI_BACK_LIGHT_OFF			(1 << 5)
-#define DPI_LP					(1 << 6)
-#define DPI_DATA_REG			0xb04c
-#define DPI_BACK_LIGHT_ON_DATA			0x07
-#define DPI_BACK_LIGHT_OFF_DATA			0x17
-#define INIT_COUNT_REG			0xb050
-#define MAX_RET_PAK_REG			0xb054
-#define VIDEO_FMT_REG			0xb058
-#define COMPLETE_LAST_PCKT			(1 << 2)
-#define EOT_DISABLE_REG			0xb05c
-#define ENABLE_CLOCK_STOPPING			(1 << 1)
-#define LP_BYTECLK_REG			0xb060
-#define LP_GEN_DATA_REG			0xb064
-#define HS_GEN_DATA_REG			0xb068
-#define LP_GEN_CTRL_REG			0xb06C
-#define HS_GEN_CTRL_REG			0xb070
-#define DCS_CHANNEL_NUMBER_POS		0x6
-#define MCS_COMMANDS_POS		0x8
-#define WORD_COUNTS_POS			0x8
-#define MCS_PARAMETER_POS			0x10
-#define GEN_FIFO_STAT_REG		0xb074
-#define HS_DATA_FIFO_FULL			(1 << 0)
-#define HS_DATA_FIFO_HALF_EMPTY			(1 << 1)
-#define HS_DATA_FIFO_EMPTY			(1 << 2)
-#define LP_DATA_FIFO_FULL			(1 << 8)
-#define LP_DATA_FIFO_HALF_EMPTY			(1 << 9)
-#define LP_DATA_FIFO_EMPTY			(1 << 10)
-#define HS_CTRL_FIFO_FULL			(1 << 16)
-#define HS_CTRL_FIFO_HALF_EMPTY			(1 << 17)
-#define HS_CTRL_FIFO_EMPTY			(1 << 18)
-#define LP_CTRL_FIFO_FULL			(1 << 24)
-#define LP_CTRL_FIFO_HALF_EMPTY			(1 << 25)
-#define LP_CTRL_FIFO_EMPTY			(1 << 26)
-#define DBI_FIFO_EMPTY				(1 << 27)
-#define DPI_FIFO_EMPTY				(1 << 28)
-#define HS_LS_DBI_ENABLE_REG		0xb078
-#define TXCLKESC_REG			0xb07c
-#define DPHY_PARAM_REG			0xb080
-#define DBI_BW_CTRL_REG			0xb084
-#define CLK_LANE_SWT_REG		0xb088
-
-/*
- * MIPI Adapter registers
- */
-#define MIPI_CONTROL_REG		0xb104
-#define MIPI_2X_CLOCK_BITS			((1 << 0) | (1 << 1))
-#define MIPI_DATA_ADDRESS_REG		0xb108
-#define MIPI_DATA_LENGTH_REG		0xb10C
-#define MIPI_COMMAND_ADDRESS_REG	0xb110
-#define MIPI_COMMAND_LENGTH_REG		0xb114
-#define MIPI_READ_DATA_RETURN_REG0	0xb118
-#define MIPI_READ_DATA_RETURN_REG1	0xb11C
-#define MIPI_READ_DATA_RETURN_REG2	0xb120
-#define MIPI_READ_DATA_RETURN_REG3	0xb124
-#define MIPI_READ_DATA_RETURN_REG4	0xb128
-#define MIPI_READ_DATA_RETURN_REG5	0xb12C
-#define MIPI_READ_DATA_RETURN_REG6	0xb130
-#define MIPI_READ_DATA_RETURN_REG7	0xb134
-#define MIPI_READ_DATA_VALID_REG	0xb138
-
-/* DBI COMMANDS */
-#define soft_reset			0x01
-/*
- *	The display module performs a software reset.
- *	Registers are written with their SW Reset default values.
- */
-#define get_power_mode			0x0a
-/*
- *	The display module returns the current power mode
- */
-#define get_address_mode		0x0b
-/*
- *	The display module returns the current status.
- */
-#define get_pixel_format		0x0c
-/*
- *	This command gets the pixel format for the RGB image data
- *	used by the interface.
- */
-#define get_display_mode		0x0d
-/*
- *	The display module returns the Display Image Mode status.
- */
-#define get_signal_mode			0x0e
-/*
- *	The display module returns the Display Signal Mode.
- */
-#define get_diagnostic_result		0x0f
-/*
- *	The display module returns the self-diagnostic results following
- *	a Sleep Out command.
- */
-#define enter_sleep_mode		0x10
-/*
- *	This command causes the display module to enter the Sleep mode.
- *	In this mode, all unnecessary blocks inside the display module are
- *	disabled except interface communication. This is the lowest power
- *	mode the display module supports.
- */
-#define exit_sleep_mode			0x11
-/*
- *	This command causes the display module to exit Sleep mode.
- *	All blocks inside the display module are enabled.
- */
-#define enter_partial_mode		0x12
-/*
- *	This command causes the display module to enter the Partial Display
- *	Mode. The Partial Display Mode window is described by the
- *	set_partial_area command.
- */
-#define enter_normal_mode		0x13
-/*
- *	This command causes the display module to enter the Normal mode.
- *	Normal Mode is defined as Partial Display mode and Scroll mode are off
- */
-#define exit_invert_mode		0x20
-/*
- *	This command causes the display module to stop inverting the image
- *	data on the display device. The frame memory contents remain unchanged.
- *	No status bits are changed.
- */
-#define enter_invert_mode		0x21
-/*
- *	This command causes the display module to invert the image data only on
- *	the display device. The frame memory contents remain unchanged.
- *	No status bits are changed.
- */
-#define set_gamma_curve			0x26
-/*
- *	This command selects the desired gamma curve for the display device.
- *	Four fixed gamma curves are defined in section DCS spec.
- */
-#define set_display_off			0x28
-/* ************************************************************************* *\
-This command causes the display module to stop displaying the image data
-on the display device. The frame memory contents remain unchanged.
-No status bits are changed.
-\* ************************************************************************* */
-#define set_display_on			0x29
-/* ************************************************************************* *\
-This command causes the display module to start displaying the image data
-on the display device. The frame memory contents remain unchanged.
-No status bits are changed.
-\* ************************************************************************* */
-#define set_column_address		0x2a
-/*
- *	This command defines the column extent of the frame memory accessed by
- *	the hostprocessor with the read_memory_continue and
- *	write_memory_continue commands.
- *	No status bits are changed.
- */
-#define set_page_addr			0x2b
-/*
- *	This command defines the page extent of the frame memory accessed by
- *	the host processor with the write_memory_continue and
- *	read_memory_continue command.
- *	No status bits are changed.
- */
-#define write_mem_start			0x2c
-/*
- *	This command transfers image data from the host processor to the
- *	display modules frame memory starting at the pixel location specified
- *	by preceding set_column_address and set_page_address commands.
- */
-#define set_partial_area		0x30
-/*
- *	This command defines the Partial Display mode s display area.
- *	There are two parameters associated with this command, the first
- *	defines the Start Row (SR) and the second the End Row (ER). SR and ER
- *	refer to the Frame Memory Line Pointer.
- */
-#define set_scroll_area			0x33
-/*
- *	This command defines the display modules Vertical Scrolling Area.
- */
-#define set_tear_off			0x34
-/*
- *	This command turns off the display modules Tearing Effect output
- *	signal on the TE signal line.
- */
-#define set_tear_on			0x35
-/*
- *	This command turns on the display modules Tearing Effect output signal
- *	on the TE signal line.
- */
-#define set_address_mode		0x36
-/*
- *	This command sets the data order for transfers from the host processor
- *	to display modules frame memory,bits B[7:5] and B3, and from the
- *	display modules frame memory to the display device, bits B[2:0] and B4.
- */
-#define set_scroll_start		0x37
-/*
- *	This command sets the start of the vertical scrolling area in the frame
- *	memory. The vertical scrolling area is fully defined when this command
- *	is used with the set_scroll_area command The set_scroll_start command
- *	has one parameter, the Vertical Scroll Pointer. The VSP defines the
- *	line in the frame memory that is written to the display device as the
- *	first line of the vertical scroll area.
- */
-#define exit_idle_mode			0x38
-/*
- *	This command causes the display module to exit Idle mode.
- */
-#define enter_idle_mode			0x39
-/*
- *	This command causes the display module to enter Idle Mode.
- *	In Idle Mode, color expression is reduced. Colors are shown on the
- *	display device using the MSB of each of the R, G and B color
- *	components in the frame memory
- */
-#define set_pixel_format		0x3a
-/*
- *	This command sets the pixel format for the RGB image data used by the
- *	interface.
- *	Bits D[6:4]  DPI Pixel Format Definition
- *	Bits D[2:0]  DBI Pixel Format Definition
- *	Bits D7 and D3 are not used.
- */
-#define DCS_PIXEL_FORMAT_3bpp		0x1
-#define DCS_PIXEL_FORMAT_8bpp		0x2
-#define DCS_PIXEL_FORMAT_12bpp		0x3
-#define DCS_PIXEL_FORMAT_16bpp		0x5
-#define DCS_PIXEL_FORMAT_18bpp		0x6
-#define DCS_PIXEL_FORMAT_24bpp		0x7
-
-#define write_mem_cont			0x3c
-
-/*
- *	This command transfers image data from the host processor to the
- *	display module's frame memory continuing from the pixel location
- *	following the previous write_memory_continue or write_memory_start
- *	command.
- */
-#define set_tear_scanline		0x44
-/*
- *	This command turns on the display modules Tearing Effect output signal
- *	on the TE signal line when the display module reaches line N.
- */
-#define get_scanline			0x45
-/*
- *	The display module returns the current scanline, N, used to update the
- *	 display device. The total number of scanlines on a display device is
- *	defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as
- *	the first line of V Sync and is denoted as Line 0.
- *	When in Sleep Mode, the value returned by get_scanline is undefined.
- */
-
-/* MCS or Generic COMMANDS */
-/* MCS/generic data type */
-#define GEN_SHORT_WRITE_0	0x03  /* generic short write, no parameters */
-#define GEN_SHORT_WRITE_1	0x13  /* generic short write, 1 parameters */
-#define GEN_SHORT_WRITE_2	0x23  /* generic short write, 2 parameters */
-#define GEN_READ_0		0x04  /* generic read, no parameters */
-#define GEN_READ_1		0x14  /* generic read, 1 parameters */
-#define GEN_READ_2		0x24  /* generic read, 2 parameters */
-#define GEN_LONG_WRITE		0x29  /* generic long write */
-#define MCS_SHORT_WRITE_0	0x05  /* MCS short write, no parameters */
-#define MCS_SHORT_WRITE_1	0x15  /* MCS short write, 1 parameters */
-#define MCS_READ		0x06  /* MCS read, no parameters */
-#define MCS_LONG_WRITE		0x39  /* MCS long write */
-/* MCS/generic commands */
-/* TPO MCS */
-#define write_display_profile		0x50
-#define write_display_brightness	0x51
-#define write_ctrl_display		0x53
-#define write_ctrl_cabc			0x55
-  #define UI_IMAGE		0x01
-  #define STILL_IMAGE		0x02
-  #define MOVING_IMAGE		0x03
-#define write_hysteresis		0x57
-#define write_gamma_setting		0x58
-#define write_cabc_min_bright		0x5e
-#define write_kbbc_profile		0x60
-/* TMD MCS */
-#define tmd_write_display_brightness 0x8c
-
-/*
- *	This command is used to control ambient light, panel backlight
- *	brightness and gamma settings.
- */
-#define BRIGHT_CNTL_BLOCK_ON	(1 << 5)
-#define AMBIENT_LIGHT_SENSE_ON	(1 << 4)
-#define DISPLAY_DIMMING_ON	(1 << 3)
-#define BACKLIGHT_ON		(1 << 2)
-#define DISPLAY_BRIGHTNESS_AUTO	(1 << 1)
-#define GAMMA_AUTO		(1 << 0)
-
-/* DCS Interface Pixel Formats */
-#define DCS_PIXEL_FORMAT_3BPP	0x1
-#define DCS_PIXEL_FORMAT_8BPP	0x2
-#define DCS_PIXEL_FORMAT_12BPP	0x3
-#define DCS_PIXEL_FORMAT_16BPP	0x5
-#define DCS_PIXEL_FORMAT_18BPP	0x6
-#define DCS_PIXEL_FORMAT_24BPP	0x7
-/* ONE PARAMETER READ DATA */
-#define addr_mode_data		0xfc
-#define diag_res_data		0x00
-#define disp_mode_data		0x23
-#define pxl_fmt_data		0x77
-#define pwr_mode_data		0x74
-#define sig_mode_data		0x00
-/* TWO PARAMETERS READ DATA */
-#define scanline_data1		0xff
-#define scanline_data2		0xff
-#define NON_BURST_MODE_SYNC_PULSE	0x01	/* Non Burst Mode
-						 * with Sync Pulse
-						 */
-#define NON_BURST_MODE_SYNC_EVENTS	0x02	/* Non Burst Mode
-						 * with Sync events
-						 */
-#define BURST_MODE			0x03	/* Burst Mode */
-#define DBI_COMMAND_BUFFER_SIZE		0x240   /* 0x32 */    /* 0x120 */
-						/* Allocate at least
-						 * 0x100 Byte with 32
-						 * byte alignment
-						 */
-#define DBI_DATA_BUFFER_SIZE		0x120	/* Allocate at least
-						 * 0x100 Byte with 32
-						 * byte alignment
-						 */
-#define DBI_CB_TIME_OUT			0xFFFF
-
-#define GEN_FB_TIME_OUT			2000
-
-#define SKU_83				0x01
-#define SKU_100				0x02
-#define SKU_100L			0x04
-#define SKU_BYPASS			0x08
-
-/* Some handy macros for playing with bitfields. */
-#define PSB_MASK(high, low) (((1<<((high)-(low)+1))-1)<<(low))
-#define SET_FIELD(value, field) (((value) << field ## _SHIFT) & field ## _MASK)
-#define GET_FIELD(word, field) (((word)  & field ## _MASK) >> field ## _SHIFT)
-
-#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
-
-/* PCI config space */
-
-#define SB_PCKT         0x02100 /* cedarview */
-# define SB_OPCODE_MASK                         PSB_MASK(31, 16)
-# define SB_OPCODE_SHIFT                        16
-# define SB_OPCODE_READ                         0
-# define SB_OPCODE_WRITE                        1
-# define SB_DEST_MASK                           PSB_MASK(15, 8)
-# define SB_DEST_SHIFT                          8
-# define SB_DEST_DPLL                           0x88
-# define SB_BYTE_ENABLE_MASK                    PSB_MASK(7, 4)
-# define SB_BYTE_ENABLE_SHIFT                   4
-# define SB_BUSY                                (1 << 0)
-
-
-/* 32-bit value read/written from the DPIO reg. */
-#define SB_DATA		0x02104 /* cedarview */
-/* 32-bit address of the DPIO reg to be read/written. */
-#define SB_ADDR		0x02108 /* cedarview */
-#define DPIO_CFG	0x02110 /* cedarview */
-# define DPIO_MODE_SELECT_1			(1 << 3)
-# define DPIO_MODE_SELECT_0			(1 << 2)
-# define DPIO_SFR_BYPASS			(1 << 1)
-/* reset is active low */
-# define DPIO_CMN_RESET_N			(1 << 0)
-
-/* Cedarview sideband registers */
-#define _SB_M_A			0x8008
-#define _SB_M_B			0x8028
-#define SB_M(pipe) _PIPE(pipe, _SB_M_A, _SB_M_B)
-# define SB_M_DIVIDER_MASK			(0xFF << 24)
-# define SB_M_DIVIDER_SHIFT			24
-
-#define _SB_N_VCO_A		0x8014
-#define _SB_N_VCO_B		0x8034
-#define SB_N_VCO(pipe) _PIPE(pipe, _SB_N_VCO_A, _SB_N_VCO_B)
-#define SB_N_VCO_SEL_MASK			PSB_MASK(31, 30)
-#define SB_N_VCO_SEL_SHIFT			30
-#define SB_N_DIVIDER_MASK			PSB_MASK(29, 26)
-#define SB_N_DIVIDER_SHIFT			26
-#define SB_N_CB_TUNE_MASK			PSB_MASK(25, 24)
-#define SB_N_CB_TUNE_SHIFT			24
-
-#define _SB_REF_A		0x8018
-#define _SB_REF_B		0x8038
-#define SB_REF_SFR(pipe)	_PIPE(pipe, _SB_REF_A, _SB_REF_B)
-
-#define _SB_P_A			0x801c
-#define _SB_P_B			0x803c
-#define SB_P(pipe) _PIPE(pipe, _SB_P_A, _SB_P_B)
-#define SB_P2_DIVIDER_MASK			PSB_MASK(31, 30)
-#define SB_P2_DIVIDER_SHIFT			30
-#define SB_P2_10				0 /* HDMI, DP, DAC */
-#define SB_P2_5				1 /* DAC */
-#define SB_P2_14				2 /* LVDS single */
-#define SB_P2_7				3 /* LVDS double */
-#define SB_P1_DIVIDER_MASK			PSB_MASK(15, 12)
-#define SB_P1_DIVIDER_SHIFT			12
-
-#define PSB_LANE0		0x120
-#define PSB_LANE1		0x220
-#define PSB_LANE2		0x2320
-#define PSB_LANE3		0x2420
-
-#define LANE_PLL_MASK		(0x7 << 20)
-#define LANE_PLL_ENABLE		(0x3 << 20)
-
-
-#endif
diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c
deleted file mode 100644
index a4bad1a..0000000
--- a/drivers/staging/gma500/psb_intel_sdvo.c
+++ /dev/null
@@ -1,1293 +0,0 @@
-/*
- * Copyright (c) 2006-2007 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- */
-
-#include <linux/i2c.h>
-#include <linux/delay.h>
-/* #include <drm/drm_crtc.h> */
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_sdvo_regs.h"
-
-struct psb_intel_sdvo_priv {
-	struct psb_intel_i2c_chan *i2c_bus;
-	int slaveaddr;
-	int output_device;
-
-	u16 active_outputs;
-
-	struct psb_intel_sdvo_caps caps;
-	int pixel_clock_min, pixel_clock_max;
-
-	int save_sdvo_mult;
-	u16 save_active_outputs;
-	struct psb_intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
-	struct psb_intel_sdvo_dtd save_output_dtd[16];
-	u32 save_SDVOX;
-	u8 in_out_map[4];
-
-	u8 by_input_wiring;
-	u32 active_device;
-};
-
-/**
- * Writes the SDVOB or SDVOC with the given value, but always writes both
- * SDVOB and SDVOC to work around apparent hardware issues (according to
- * comments in the BIOS).
- */
-void psb_intel_sdvo_write_sdvox(struct psb_intel_output *psb_intel_output,
-				u32 val)
-{
-	struct drm_device *dev = psb_intel_output->base.dev;
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-	u32 bval = val, cval = val;
-	int i;
-
-	if (sdvo_priv->output_device == SDVOB)
-		cval = REG_READ(SDVOC);
-	else
-		bval = REG_READ(SDVOB);
-	/*
-	 * Write the registers twice for luck. Sometimes,
-	 * writing them only once doesn't appear to 'stick'.
-	 * The BIOS does this too. Yay, magic
-	 */
-	for (i = 0; i < 2; i++) {
-		REG_WRITE(SDVOB, bval);
-		REG_READ(SDVOB);
-		REG_WRITE(SDVOC, cval);
-		REG_READ(SDVOC);
-	}
-}
-
-static bool psb_intel_sdvo_read_byte(
-				struct psb_intel_output *psb_intel_output,
-				u8 addr, u8 *ch)
-{
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-	u8 out_buf[2];
-	u8 buf[2];
-	int ret;
-
-	struct i2c_msg msgs[] = {
-		{
-		 .addr = sdvo_priv->i2c_bus->slave_addr,
-		 .flags = 0,
-		 .len = 1,
-		 .buf = out_buf,
-		 },
-		{
-		 .addr = sdvo_priv->i2c_bus->slave_addr,
-		 .flags = I2C_M_RD,
-		 .len = 1,
-		 .buf = buf,
-		 }
-	};
-
-	out_buf[0] = addr;
-	out_buf[1] = 0;
-
-	ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2);
-	if (ret == 2) {
-		*ch = buf[0];
-		return true;
-	}
-
-	return false;
-}
-
-static bool psb_intel_sdvo_write_byte(
-			struct psb_intel_output *psb_intel_output,
-			int addr, u8 ch)
-{
-	u8 out_buf[2];
-	struct i2c_msg msgs[] = {
-		{
-		 .addr = psb_intel_output->i2c_bus->slave_addr,
-		 .flags = 0,
-		 .len = 2,
-		 .buf = out_buf,
-		 }
-	};
-
-	out_buf[0] = addr;
-	out_buf[1] = ch;
-
-	if (i2c_transfer(&psb_intel_output->i2c_bus->adapter, msgs, 1) == 1)
-		return true;
-	return false;
-}
-
-#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
-/** Mapping of command numbers to names, for debug output */
-static const struct _sdvo_cmd_name {
-	u8 cmd;
-	char *name;
-} sdvo_cmd_names[] = {
-SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
-	    SDVO_CMD_NAME_ENTRY
-	    (SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
-	    SDVO_CMD_NAME_ENTRY
-	    (SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
-	    SDVO_CMD_NAME_ENTRY
-	    (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
-	    SDVO_CMD_NAME_ENTRY
-	    (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
-	    SDVO_CMD_NAME_ENTRY
-	    (SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
-	    SDVO_CMD_NAME_ENTRY
-	    (SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
-	    SDVO_CMD_NAME_ENTRY
-	    (SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
-	    SDVO_CMD_NAME_ENTRY
-	    (SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
-	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),};
-
-#define SDVO_NAME(dev_priv) \
-		 ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
-#define SDVO_PRIV(output)   ((struct psb_intel_sdvo_priv *) (output)->dev_priv)
-
-static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output,
-				     u8 cmd,
-				     void *args,
-				     int args_len)
-{
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-	int i;
-
-	if (0) {
-		printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
-		for (i = 0; i < args_len; i++)
-			printk(KERN_CONT "%02X ", ((u8 *) args)[i]);
-		for (; i < 8; i++)
-			printk(KERN_CONT "   ");
-		for (i = 0;
-		     i <
-		     sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]);
-		     i++) {
-			if (cmd == sdvo_cmd_names[i].cmd) {
-				printk(KERN_CONT
-					"(%s)", sdvo_cmd_names[i].name);
-				break;
-			}
-		}
-		if (i ==
-		    sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]))
-			printk(KERN_CONT "(%02X)", cmd);
-		printk(KERN_CONT "\n");
-	}
-
-	for (i = 0; i < args_len; i++) {
-		psb_intel_sdvo_write_byte(psb_intel_output,
-					SDVO_I2C_ARG_0 - i,
-					((u8 *) args)[i]);
-	}
-
-	psb_intel_sdvo_write_byte(psb_intel_output, SDVO_I2C_OPCODE, cmd);
-}
-
-static const char *const cmd_status_names[] = {
-	"Power on",
-	"Success",
-	"Not supported",
-	"Invalid arg",
-	"Pending",
-	"Target not specified",
-	"Scaling not supported"
-};
-
-static u8 psb_intel_sdvo_read_response(
-				struct psb_intel_output *psb_intel_output,
-				void *response, int response_len)
-{
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-	int i;
-	u8 status;
-	u8 retry = 50;
-
-	while (retry--) {
-		/* Read the command response */
-		for (i = 0; i < response_len; i++) {
-			psb_intel_sdvo_read_byte(psb_intel_output,
-					     SDVO_I2C_RETURN_0 + i,
-					     &((u8 *) response)[i]);
-		}
-
-		/* read the return status */
-		psb_intel_sdvo_read_byte(psb_intel_output,
-					 SDVO_I2C_CMD_STATUS,
-					 &status);
-
-		if (0) {
-			pr_debug("%s: R: ", SDVO_NAME(sdvo_priv));
-			for (i = 0; i < response_len; i++)
-				printk(KERN_CONT "%02X ", ((u8 *) response)[i]);
-			for (; i < 8; i++)
-				printk("   ");
-			if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
-				printk(KERN_CONT "(%s)",
-					 cmd_status_names[status]);
-			else
-				printk(KERN_CONT "(??? %d)", status);
-			printk(KERN_CONT "\n");
-		}
-
-		if (status != SDVO_CMD_STATUS_PENDING)
-			return status;
-
-		mdelay(50);
-	}
-
-	return status;
-}
-
-int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
-{
-	if (mode->clock >= 100000)
-		return 1;
-	else if (mode->clock >= 50000)
-		return 2;
-	else
-		return 4;
-}
-
-/**
- * Don't check status code from this as it switches the bus back to the
- * SDVO chips which defeats the purpose of doing a bus switch in the first
- * place.
- */
-void psb_intel_sdvo_set_control_bus_switch(
-				struct psb_intel_output *psb_intel_output,
-				u8 target)
-{
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				 SDVO_CMD_SET_CONTROL_BUS_SWITCH,
-				 &target,
-				 1);
-}
-
-static bool psb_intel_sdvo_set_target_input(
-				struct psb_intel_output *psb_intel_output,
-				bool target_0, bool target_1)
-{
-	struct psb_intel_sdvo_set_target_input_args targets = { 0 };
-	u8 status;
-
-	if (target_0 && target_1)
-		return SDVO_CMD_STATUS_NOTSUPP;
-
-	if (target_1)
-		targets.target_1 = 1;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_INPUT,
-			     &targets, sizeof(targets));
-
-	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-
-	return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-/**
- * Return whether each input is trained.
- *
- * This function is making an assumption about the layout of the response,
- * which should be checked against the docs.
- */
-static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_output
-					  *psb_intel_output, bool *input_1,
-					  bool *input_2)
-{
-	struct psb_intel_sdvo_get_trained_inputs_response response;
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_TRAINED_INPUTS,
-			     NULL, 0);
-	status =
-	    psb_intel_sdvo_read_response(psb_intel_output, &response,
-				     sizeof(response));
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-
-	*input_1 = response.input0_trained;
-	*input_2 = response.input1_trained;
-	return true;
-}
-
-static bool psb_intel_sdvo_get_active_outputs(struct psb_intel_output
-					  *psb_intel_output, u16 *outputs)
-{
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS,
-			     NULL, 0);
-	status =
-	    psb_intel_sdvo_read_response(psb_intel_output, outputs,
-				     sizeof(*outputs));
-
-	return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_output
-					  *psb_intel_output, u16 outputs)
-{
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS,
-			     &outputs, sizeof(outputs));
-	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-	return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_output
-					       *psb_intel_output, int mode)
-{
-	u8 status, state = SDVO_ENCODER_STATE_ON;
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		state = SDVO_ENCODER_STATE_ON;
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-		state = SDVO_ENCODER_STATE_STANDBY;
-		break;
-	case DRM_MODE_DPMS_SUSPEND:
-		state = SDVO_ENCODER_STATE_SUSPEND;
-		break;
-	case DRM_MODE_DPMS_OFF:
-		state = SDVO_ENCODER_STATE_OFF;
-		break;
-	}
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-			     SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
-			     sizeof(state));
-	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-
-	return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_output
-						   *psb_intel_output,
-						   int *clock_min,
-						   int *clock_max)
-{
-	struct psb_intel_sdvo_pixel_clock_range clocks;
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-			     SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL,
-			     0);
-
-	status =
-	    psb_intel_sdvo_read_response(psb_intel_output, &clocks,
-				     sizeof(clocks));
-
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-
-	/* Convert the values from units of 10 kHz to kHz. */
-	*clock_min = clocks.min * 10;
-	*clock_max = clocks.max * 10;
-
-	return true;
-}
-
-static bool psb_intel_sdvo_set_target_output(
-				struct psb_intel_output *psb_intel_output,
-				u16 outputs)
-{
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_OUTPUT,
-			     &outputs, sizeof(outputs));
-
-	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-	return status == SDVO_CMD_STATUS_SUCCESS;
-}
-
-static bool psb_intel_sdvo_get_timing(struct psb_intel_output *psb_intel_output,
-				  u8 cmd, struct psb_intel_sdvo_dtd *dtd)
-{
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, cmd, NULL, 0);
-	status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1,
-					  sizeof(dtd->part1));
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, NULL, 0);
-	status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2,
-					  sizeof(dtd->part2));
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-
-	return true;
-}
-
-static bool psb_intel_sdvo_get_input_timing(
-				struct psb_intel_output *psb_intel_output,
-				struct psb_intel_sdvo_dtd *dtd)
-{
-	return psb_intel_sdvo_get_timing(psb_intel_output,
-				     SDVO_CMD_GET_INPUT_TIMINGS_PART1,
-				     dtd);
-}
-
-static bool psb_intel_sdvo_set_timing(
-				struct psb_intel_output *psb_intel_output,
-				u8 cmd,
-				struct psb_intel_sdvo_dtd *dtd)
-{
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, cmd, &dtd->part1,
-			     sizeof(dtd->part1));
-	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, &dtd->part2,
-			     sizeof(dtd->part2));
-	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-
-	return true;
-}
-
-static bool psb_intel_sdvo_set_input_timing(
-				struct psb_intel_output *psb_intel_output,
-				struct psb_intel_sdvo_dtd *dtd)
-{
-	return psb_intel_sdvo_set_timing(psb_intel_output,
-				     SDVO_CMD_SET_INPUT_TIMINGS_PART1,
-				     dtd);
-}
-
-static bool psb_intel_sdvo_set_output_timing(
-				struct psb_intel_output *psb_intel_output,
-				struct psb_intel_sdvo_dtd *dtd)
-{
-	return psb_intel_sdvo_set_timing(psb_intel_output,
-				     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1,
-				     dtd);
-}
-
-static int psb_intel_sdvo_get_clock_rate_mult(struct psb_intel_output
-						*psb_intel_output)
-{
-	u8 response, status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				 SDVO_CMD_GET_CLOCK_RATE_MULT,
-				 NULL,
-				 0);
-
-	status = psb_intel_sdvo_read_response(psb_intel_output, &response, 1);
-
-	if (status != SDVO_CMD_STATUS_SUCCESS) {
-		DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
-		return SDVO_CLOCK_RATE_MULT_1X;
-	} else {
-		DRM_DEBUG("Current clock rate multiplier: %d\n", response);
-	}
-
-	return response;
-}
-
-static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_output
-						*psb_intel_output, u8 val)
-{
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				SDVO_CMD_SET_CLOCK_RATE_MULT,
-				&val,
-				1);
-
-	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-
-	return true;
-}
-
-static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output,
-					  u32 in0outputmask,
-					  u32 in1outputmask)
-{
-	u8 byArgs[4];
-	u8 status;
-	int i;
-	struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;
-
-	/* Make all fields of the  args/ret to zero */
-	memset(byArgs, 0, sizeof(byArgs));
-
-	/* Fill up the argument values; */
-	byArgs[0] = (u8) (in0outputmask & 0xFF);
-	byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF);
-	byArgs[2] = (u8) (in1outputmask & 0xFF);
-	byArgs[3] = (u8) ((in1outputmask >> 8) & 0xFF);
-
-
-	/*save inoutmap arg here*/
-	for (i = 0; i < 4; i++)
-		sdvo_priv->in_out_map[i] = byArgs[0];
-
-	psb_intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, byArgs, 4);
-	status = psb_intel_sdvo_read_response(output, NULL, 0);
-
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-	return true;
-}
-
-
-static void psb_intel_sdvo_set_iomap(struct psb_intel_output *output)
-{
-	u32 dwCurrentSDVOIn0 = 0;
-	u32 dwCurrentSDVOIn1 = 0;
-	u32 dwDevMask = 0;
-
-
-	struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;
-
-	/* Please DO NOT change the following code. */
-	/* SDVOB_IN0 or SDVOB_IN1 ==> sdvo_in0 */
-	/* SDVOC_IN0 or SDVOC_IN1 ==> sdvo_in1 */
-	if (sdvo_priv->by_input_wiring & (SDVOB_IN0 | SDVOC_IN0)) {
-		switch (sdvo_priv->active_device) {
-		case SDVO_DEVICE_LVDS:
-			dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
-			break;
-		case SDVO_DEVICE_TMDS:
-			dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
-			break;
-		case SDVO_DEVICE_TV:
-			dwDevMask =
-			SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
-			SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
-			SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
-			SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
-			break;
-		case SDVO_DEVICE_CRT:
-			dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
-			break;
-		}
-		dwCurrentSDVOIn0 = (sdvo_priv->active_outputs & dwDevMask);
-	} else if (sdvo_priv->by_input_wiring & (SDVOB_IN1 | SDVOC_IN1)) {
-		switch (sdvo_priv->active_device) {
-		case SDVO_DEVICE_LVDS:
-			dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
-			break;
-		case SDVO_DEVICE_TMDS:
-			dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
-			break;
-		case SDVO_DEVICE_TV:
-			dwDevMask =
-			SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
-			SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
-			SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
-			SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
-			break;
-		case SDVO_DEVICE_CRT:
-			dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
-			break;
-		}
-		dwCurrentSDVOIn1 = (sdvo_priv->active_outputs & dwDevMask);
-	}
-
-	psb_sdvo_set_current_inoutmap(output, dwCurrentSDVOIn0,
-					  dwCurrentSDVOIn1);
-}
-
-
-static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
-{
-	/* Make the CRTC code factor in the SDVO pixel multiplier.  The SDVO
-	 * device will be told of the multiplier during mode_set.
-	 */
-	adjusted_mode->clock *= psb_intel_sdvo_get_pixel_multiplier(mode);
-	return true;
-}
-
-static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct drm_crtc *crtc = encoder->crtc;
-	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct psb_intel_output *psb_intel_output =
-					enc_to_psb_intel_output(encoder);
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-	u16 width, height;
-	u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
-	u16 h_sync_offset, v_sync_offset;
-	u32 sdvox;
-	struct psb_intel_sdvo_dtd output_dtd;
-	int sdvo_pixel_multiply;
-
-	if (!mode)
-		return;
-
-	psb_intel_sdvo_set_target_output(psb_intel_output, 0);
-
-	width = mode->crtc_hdisplay;
-	height = mode->crtc_vdisplay;
-
-	/* do some mode translations */
-	h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
-	h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
-
-	v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
-	v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
-
-	h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
-	v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
-
-	output_dtd.part1.clock = mode->clock / 10;
-	output_dtd.part1.h_active = width & 0xff;
-	output_dtd.part1.h_blank = h_blank_len & 0xff;
-	output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
-	    ((h_blank_len >> 8) & 0xf);
-	output_dtd.part1.v_active = height & 0xff;
-	output_dtd.part1.v_blank = v_blank_len & 0xff;
-	output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
-	    ((v_blank_len >> 8) & 0xf);
-
-	output_dtd.part2.h_sync_off = h_sync_offset;
-	output_dtd.part2.h_sync_width = h_sync_len & 0xff;
-	output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
-	    (v_sync_len & 0xf);
-	output_dtd.part2.sync_off_width_high =
-	    ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) |
-	    ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4);
-
-	output_dtd.part2.dtd_flags = 0x18;
-	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
-		output_dtd.part2.dtd_flags |= 0x2;
-	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
-		output_dtd.part2.dtd_flags |= 0x4;
-
-	output_dtd.part2.sdvo_flags = 0;
-	output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
-	output_dtd.part2.reserved = 0;
-
-	/* Set the output timing to the screen */
-	psb_intel_sdvo_set_target_output(psb_intel_output,
-				     sdvo_priv->active_outputs);
-
-	/* Set the input timing to the screen. Assume always input 0. */
-	psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
-
-	psb_intel_sdvo_set_output_timing(psb_intel_output, &output_dtd);
-
-	/* We would like to use i830_sdvo_create_preferred_input_timing() to
-	 * provide the device with a timing it can support, if it supports that
-	 * feature.  However, presumably we would need to adjust the CRTC to
-	 * output the preferred timing, and we don't support that currently.
-	 */
-	psb_intel_sdvo_set_input_timing(psb_intel_output, &output_dtd);
-
-	switch (psb_intel_sdvo_get_pixel_multiplier(mode)) {
-	case 1:
-		psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
-					       SDVO_CLOCK_RATE_MULT_1X);
-		break;
-	case 2:
-		psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
-					       SDVO_CLOCK_RATE_MULT_2X);
-		break;
-	case 4:
-		psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
-					       SDVO_CLOCK_RATE_MULT_4X);
-		break;
-	}
-
-	/* Set the SDVO control regs. */
-	sdvox = REG_READ(sdvo_priv->output_device);
-	switch (sdvo_priv->output_device) {
-	case SDVOB:
-		sdvox &= SDVOB_PRESERVE_MASK;
-		break;
-	case SDVOC:
-		sdvox &= SDVOC_PRESERVE_MASK;
-		break;
-	}
-	sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
-	if (psb_intel_crtc->pipe == 1)
-		sdvox |= SDVO_PIPE_B_SELECT;
-
-	sdvo_pixel_multiply = psb_intel_sdvo_get_pixel_multiplier(mode);
-
-	psb_intel_sdvo_write_sdvox(psb_intel_output, sdvox);
-
-	 psb_intel_sdvo_set_iomap(psb_intel_output);
-}
-
-static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct psb_intel_output *psb_intel_output =
-					enc_to_psb_intel_output(encoder);
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-	u32 temp;
-
-	if (mode != DRM_MODE_DPMS_ON) {
-		psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
-		if (0)
-			psb_intel_sdvo_set_encoder_power_state(
-							psb_intel_output,
-							mode);
-
-		if (mode == DRM_MODE_DPMS_OFF) {
-			temp = REG_READ(sdvo_priv->output_device);
-			if ((temp & SDVO_ENABLE) != 0) {
-				psb_intel_sdvo_write_sdvox(psb_intel_output,
-						       temp &
-						       ~SDVO_ENABLE);
-			}
-		}
-	} else {
-		bool input1, input2;
-		int i;
-		u8 status;
-
-		temp = REG_READ(sdvo_priv->output_device);
-		if ((temp & SDVO_ENABLE) == 0)
-			psb_intel_sdvo_write_sdvox(psb_intel_output,
-					       temp | SDVO_ENABLE);
-		for (i = 0; i < 2; i++)
-			psb_intel_wait_for_vblank(dev);
-
-		status =
-		    psb_intel_sdvo_get_trained_inputs(psb_intel_output,
-							&input1,
-							&input2);
-
-
-		/* Warn if the device reported failure to sync.
-		 * A lot of SDVO devices fail to notify of sync, but it's
-		 * a given it the status is a success, we succeeded.
-		 */
-		if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
-			DRM_DEBUG
-			    ("First %s output reported failure to sync\n",
-			     SDVO_NAME(sdvo_priv));
-		}
-
-		if (0)
-			psb_intel_sdvo_set_encoder_power_state(
-							psb_intel_output,
-							mode);
-		psb_intel_sdvo_set_active_outputs(psb_intel_output,
-					      sdvo_priv->active_outputs);
-	}
-	return;
-}
-
-static void psb_intel_sdvo_save(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-	/*int o;*/
-
-	sdvo_priv->save_sdvo_mult =
-	    psb_intel_sdvo_get_clock_rate_mult(psb_intel_output);
-	psb_intel_sdvo_get_active_outputs(psb_intel_output,
-				      &sdvo_priv->save_active_outputs);
-
-	if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-		psb_intel_sdvo_set_target_input(psb_intel_output,
-						true,
-						false);
-		psb_intel_sdvo_get_input_timing(psb_intel_output,
-					    &sdvo_priv->save_input_dtd_1);
-	}
-
-	if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-		psb_intel_sdvo_set_target_input(psb_intel_output,
-						false,
-						true);
-		psb_intel_sdvo_get_input_timing(psb_intel_output,
-					    &sdvo_priv->save_input_dtd_2);
-	}
-	sdvo_priv->save_SDVOX = REG_READ(sdvo_priv->output_device);
-
-	/*TODO: save the in_out_map state*/
-}
-
-static void psb_intel_sdvo_restore(struct drm_connector *connector)
-{
-	struct drm_device *dev = connector->dev;
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-	/*int o;*/
-	int i;
-	bool input1, input2;
-	u8 status;
-
-	psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
-
-	if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-		psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
-		psb_intel_sdvo_set_input_timing(psb_intel_output,
-					    &sdvo_priv->save_input_dtd_1);
-	}
-
-	if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-		psb_intel_sdvo_set_target_input(psb_intel_output, false, true);
-		psb_intel_sdvo_set_input_timing(psb_intel_output,
-					    &sdvo_priv->save_input_dtd_2);
-	}
-
-	psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
-				       sdvo_priv->save_sdvo_mult);
-
-	REG_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
-
-	if (sdvo_priv->save_SDVOX & SDVO_ENABLE) {
-		for (i = 0; i < 2; i++)
-			psb_intel_wait_for_vblank(dev);
-		status =
-		    psb_intel_sdvo_get_trained_inputs(psb_intel_output,
-							&input1,
-							&input2);
-		if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
-			DRM_DEBUG
-			    ("First %s output reported failure to sync\n",
-			     SDVO_NAME(sdvo_priv));
-	}
-
-	psb_intel_sdvo_set_active_outputs(psb_intel_output,
-				      sdvo_priv->save_active_outputs);
-
-	/*TODO: restore in_out_map*/
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				 SDVO_CMD_SET_IN_OUT_MAP,
-				 sdvo_priv->in_out_map,
-				 4);
-
-	psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
-}
-
-static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
-				 struct drm_display_mode *mode)
-{
-	struct psb_intel_output *psb_intel_output =
-				to_psb_intel_output(connector);
-	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-		return MODE_NO_DBLESCAN;
-
-	if (sdvo_priv->pixel_clock_min > mode->clock)
-		return MODE_CLOCK_LOW;
-
-	if (sdvo_priv->pixel_clock_max < mode->clock)
-		return MODE_CLOCK_HIGH;
-
-	return MODE_OK;
-}
-
-static bool psb_intel_sdvo_get_capabilities(
-				struct psb_intel_output *psb_intel_output,
-				struct psb_intel_sdvo_caps *caps)
-{
-	u8 status;
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				 SDVO_CMD_GET_DEVICE_CAPS,
-				 NULL,
-				 0);
-	status = psb_intel_sdvo_read_response(psb_intel_output,
-						caps,
-						sizeof(*caps));
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return false;
-
-	return true;
-}
-
-struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, int sdvoB)
-{
-	struct drm_connector *connector = NULL;
-	struct psb_intel_output *iout = NULL;
-	struct psb_intel_sdvo_priv *sdvo;
-
-	/* find the sdvo connector */
-	list_for_each_entry(connector, &dev->mode_config.connector_list,
-			    head) {
-		iout = to_psb_intel_output(connector);
-
-		if (iout->type != INTEL_OUTPUT_SDVO)
-			continue;
-
-		sdvo = iout->dev_priv;
-
-		if (sdvo->output_device == SDVOB && sdvoB)
-			return connector;
-
-		if (sdvo->output_device == SDVOC && !sdvoB)
-			return connector;
-
-	}
-
-	return NULL;
-}
-
-int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector)
-{
-	u8 response[2];
-	u8 status;
-	struct psb_intel_output *psb_intel_output;
-
-	if (!connector)
-		return 0;
-
-	psb_intel_output = to_psb_intel_output(connector);
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				 SDVO_CMD_GET_HOT_PLUG_SUPPORT,
-				 NULL,
-				 0);
-	status = psb_intel_sdvo_read_response(psb_intel_output,
-						&response,
-						2);
-
-	if (response[0] != 0)
-		return 1;
-
-	return 0;
-}
-
-void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
-{
-	u8 response[2];
-	u8 status;
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				 SDVO_CMD_GET_ACTIVE_HOT_PLUG,
-				 NULL,
-				 0);
-	psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
-
-	if (on) {
-		psb_intel_sdvo_write_cmd(psb_intel_output,
-				     SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL,
-				     0);
-		status = psb_intel_sdvo_read_response(psb_intel_output,
-						      &response,
-						      2);
-
-		psb_intel_sdvo_write_cmd(psb_intel_output,
-				     SDVO_CMD_SET_ACTIVE_HOT_PLUG,
-				     &response, 2);
-	} else {
-		response[0] = 0;
-		response[1] = 0;
-		psb_intel_sdvo_write_cmd(psb_intel_output,
-				     SDVO_CMD_SET_ACTIVE_HOT_PLUG,
-				     &response, 2);
-	}
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				 SDVO_CMD_GET_ACTIVE_HOT_PLUG,
-				 NULL,
-				 0);
-	psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
-}
-
-static enum drm_connector_status psb_intel_sdvo_detect(struct drm_connector
-						   *connector, bool force)
-{
-	u8 response[2];
-	u8 status;
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-
-	psb_intel_sdvo_write_cmd(psb_intel_output,
-				 SDVO_CMD_GET_ATTACHED_DISPLAYS,
-				 NULL,
-				 0);
-	status = psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
-
-	DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
-	if ((response[0] != 0) || (response[1] != 0))
-		return connector_status_connected;
-	else
-		return connector_status_disconnected;
-}
-
-static int psb_intel_sdvo_get_modes(struct drm_connector *connector)
-{
-	struct psb_intel_output *psb_intel_output =
-					to_psb_intel_output(connector);
-
-	/* set the bus switch and get the modes */
-	psb_intel_sdvo_set_control_bus_switch(psb_intel_output,
-					  SDVO_CONTROL_BUS_DDC2);
-	psb_intel_ddc_get_modes(psb_intel_output);
-
-	if (list_empty(&connector->probed_modes))
-		return 0;
-	return 1;
-}
-
-static void psb_intel_sdvo_destroy(struct drm_connector *connector)
-{
-	struct psb_intel_output *psb_intel_output =
-				to_psb_intel_output(connector);
-
-	if (psb_intel_output->i2c_bus)
-		psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-	drm_sysfs_connector_remove(connector);
-	drm_connector_cleanup(connector);
-	kfree(psb_intel_output);
-}
-
-static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
-	.dpms = psb_intel_sdvo_dpms,
-	.mode_fixup = psb_intel_sdvo_mode_fixup,
-	.prepare = psb_intel_encoder_prepare,
-	.mode_set = psb_intel_sdvo_mode_set,
-	.commit = psb_intel_encoder_commit,
-};
-
-static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
-	.dpms = drm_helper_connector_dpms,
-	.save = psb_intel_sdvo_save,
-	.restore = psb_intel_sdvo_restore,
-	.detect = psb_intel_sdvo_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = psb_intel_sdvo_destroy,
-};
-
-static const struct drm_connector_helper_funcs
-				psb_intel_sdvo_connector_helper_funcs = {
-	.get_modes = psb_intel_sdvo_get_modes,
-	.mode_valid = psb_intel_sdvo_mode_valid,
-	.best_encoder = psb_intel_best_encoder,
-};
-
-void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = {
-	.destroy = psb_intel_sdvo_enc_destroy,
-};
-
-
-void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
-{
-	struct drm_connector *connector;
-	struct psb_intel_output *psb_intel_output;
-	struct psb_intel_sdvo_priv *sdvo_priv;
-	struct psb_intel_i2c_chan *i2cbus = NULL;
-	int connector_type;
-	u8 ch[0x40];
-	int i;
-	int encoder_type, output_id;
-
-	psb_intel_output =
-	    kcalloc(sizeof(struct psb_intel_output) +
-		    sizeof(struct psb_intel_sdvo_priv), 1, GFP_KERNEL);
-	if (!psb_intel_output)
-		return;
-
-	connector = &psb_intel_output->base;
-
-	drm_connector_init(dev, connector, &psb_intel_sdvo_connector_funcs,
-			   DRM_MODE_CONNECTOR_Unknown);
-	drm_connector_helper_add(connector,
-				 &psb_intel_sdvo_connector_helper_funcs);
-	sdvo_priv = (struct psb_intel_sdvo_priv *) (psb_intel_output + 1);
-	psb_intel_output->type = INTEL_OUTPUT_SDVO;
-
-	connector->interlace_allowed = 0;
-	connector->doublescan_allowed = 0;
-
-	/* setup the DDC bus. */
-	if (output_device == SDVOB)
-		i2cbus =
-		    psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
-	else
-		i2cbus =
-		    psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
-
-	if (!i2cbus)
-		goto err_connector;
-
-	sdvo_priv->i2c_bus = i2cbus;
-
-	if (output_device == SDVOB) {
-		output_id = 1;
-		sdvo_priv->by_input_wiring = SDVOB_IN0;
-		sdvo_priv->i2c_bus->slave_addr = 0x38;
-	} else {
-		output_id = 2;
-		sdvo_priv->i2c_bus->slave_addr = 0x39;
-	}
-
-	sdvo_priv->output_device = output_device;
-	psb_intel_output->i2c_bus = i2cbus;
-	psb_intel_output->dev_priv = sdvo_priv;
-
-
-	/* Read the regs to test if we can talk to the device */
-	for (i = 0; i < 0x40; i++) {
-		if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) {
-			dev_dbg(dev->dev, "No SDVO device found on SDVO%c\n",
-				  output_device == SDVOB ? 'B' : 'C');
-			goto err_i2c;
-		}
-	}
-
-	psb_intel_sdvo_get_capabilities(psb_intel_output, &sdvo_priv->caps);
-
-	memset(&sdvo_priv->active_outputs, 0,
-	       sizeof(sdvo_priv->active_outputs));
-
-	/* TODO, CVBS, SVID, YPRPB & SCART outputs. */
-	if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) {
-		sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
-		sdvo_priv->active_device = SDVO_DEVICE_CRT;
-		connector->display_info.subpixel_order =
-		    SubPixelHorizontalRGB;
-		encoder_type = DRM_MODE_ENCODER_DAC;
-		connector_type = DRM_MODE_CONNECTOR_VGA;
-	} else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) {
-		sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
-		sdvo_priv->active_outputs = SDVO_DEVICE_CRT;
-		connector->display_info.subpixel_order =
-		    SubPixelHorizontalRGB;
-		encoder_type = DRM_MODE_ENCODER_DAC;
-		connector_type = DRM_MODE_CONNECTOR_VGA;
-	} else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) {
-		sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
-		sdvo_priv->active_device = SDVO_DEVICE_TMDS;
-		connector->display_info.subpixel_order =
-		    SubPixelHorizontalRGB;
-		encoder_type = DRM_MODE_ENCODER_TMDS;
-		connector_type = DRM_MODE_CONNECTOR_DVID;
-	} else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) {
-		sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
-		sdvo_priv->active_device = SDVO_DEVICE_TMDS;
-		connector->display_info.subpixel_order =
-		    SubPixelHorizontalRGB;
-		encoder_type = DRM_MODE_ENCODER_TMDS;
-		connector_type = DRM_MODE_CONNECTOR_DVID;
-	} else {
-		unsigned char bytes[2];
-
-		memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
-		dev_dbg(dev->dev, "%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
-		     SDVO_NAME(sdvo_priv), bytes[0], bytes[1]);
-		goto err_i2c;
-	}
-
-	drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_sdvo_enc_funcs,
-			 encoder_type);
-	drm_encoder_helper_add(&psb_intel_output->enc,
-			       &psb_intel_sdvo_helper_funcs);
-	connector->connector_type = connector_type;
-
-	drm_mode_connector_attach_encoder(&psb_intel_output->base,
-					  &psb_intel_output->enc);
-	drm_sysfs_connector_add(connector);
-
-	/* Set the input timing to the screen. Assume always input 0. */
-	psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
-
-	psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_output,
-					       &sdvo_priv->pixel_clock_min,
-					       &sdvo_priv->
-					       pixel_clock_max);
-
-
-	dev_dbg(dev->dev, "%s device VID/DID: %02X:%02X.%02X, "
-		  "clock range %dMHz - %dMHz, "
-		  "input 1: %c, input 2: %c, "
-		  "output 1: %c, output 2: %c\n",
-		  SDVO_NAME(sdvo_priv),
-		  sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
-		  sdvo_priv->caps.device_rev_id,
-		  sdvo_priv->pixel_clock_min / 1000,
-		  sdvo_priv->pixel_clock_max / 1000,
-		  (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
-		  (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
-		  /* check currently supported outputs */
-		  sdvo_priv->caps.output_flags &
-		  (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
-		  sdvo_priv->caps.output_flags &
-		  (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
-
-	psb_intel_output->ddc_bus = i2cbus;
-
-	return;
-
-err_i2c:
-	psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
-err_connector:
-	drm_connector_cleanup(connector);
-	kfree(psb_intel_output);
-
-	return;
-}
diff --git a/drivers/staging/gma500/psb_intel_sdvo_regs.h b/drivers/staging/gma500/psb_intel_sdvo_regs.h
deleted file mode 100644
index 96862ea..0000000
--- a/drivers/staging/gma500/psb_intel_sdvo_regs.h
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * SDVO command definitions and structures.
- *
- * Copyright (c) 2008, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *	Eric Anholt <eric@anholt.net>
- */
-
-#define SDVO_OUTPUT_FIRST   (0)
-#define SDVO_OUTPUT_TMDS0   (1 << 0)
-#define SDVO_OUTPUT_RGB0    (1 << 1)
-#define SDVO_OUTPUT_CVBS0   (1 << 2)
-#define SDVO_OUTPUT_SVID0   (1 << 3)
-#define SDVO_OUTPUT_YPRPB0  (1 << 4)
-#define SDVO_OUTPUT_SCART0  (1 << 5)
-#define SDVO_OUTPUT_LVDS0   (1 << 6)
-#define SDVO_OUTPUT_TMDS1   (1 << 8)
-#define SDVO_OUTPUT_RGB1    (1 << 9)
-#define SDVO_OUTPUT_CVBS1   (1 << 10)
-#define SDVO_OUTPUT_SVID1   (1 << 11)
-#define SDVO_OUTPUT_YPRPB1  (1 << 12)
-#define SDVO_OUTPUT_SCART1  (1 << 13)
-#define SDVO_OUTPUT_LVDS1   (1 << 14)
-#define SDVO_OUTPUT_LAST    (14)
-
-struct psb_intel_sdvo_caps {
-	u8 vendor_id;
-	u8 device_id;
-	u8 device_rev_id;
-	u8 sdvo_version_major;
-	u8 sdvo_version_minor;
-	unsigned int sdvo_inputs_mask:2;
-	unsigned int smooth_scaling:1;
-	unsigned int sharp_scaling:1;
-	unsigned int up_scaling:1;
-	unsigned int down_scaling:1;
-	unsigned int stall_support:1;
-	unsigned int pad:1;
-	u16 output_flags;
-} __packed;
-
-/** This matches the EDID DTD structure, more or less */
-struct psb_intel_sdvo_dtd {
-	struct {
-		u16 clock;	/**< pixel clock, in 10kHz units */
-		u8 h_active;	/**< lower 8 bits (pixels) */
-		u8 h_blank;	/**< lower 8 bits (pixels) */
-		u8 h_high;	/**< upper 4 bits each h_active, h_blank */
-		u8 v_active;	/**< lower 8 bits (lines) */
-		u8 v_blank;	/**< lower 8 bits (lines) */
-		u8 v_high;	/**< upper 4 bits each v_active, v_blank */
-	} part1;
-
-	struct {
-		u8 h_sync_off;
-			/**< lower 8 bits, from hblank start */
-		u8 h_sync_width;/**< lower 8 bits (pixels) */
-	/** lower 4 bits each vsync offset, vsync width */
-		u8 v_sync_off_width;
-	/**
-	 * 2 high bits of hsync offset, 2 high bits of hsync width,
-	 * bits 4-5 of vsync offset, and 2 high bits of vsync width.
-	 */
-		u8 sync_off_width_high;
-		u8 dtd_flags;
-		u8 sdvo_flags;
-	/** bits 6-7 of vsync offset at bits 6-7 */
-		u8 v_sync_off_high;
-		u8 reserved;
-	} part2;
-} __packed;
-
-struct psb_intel_sdvo_pixel_clock_range {
-	u16 min;		/**< pixel clock, in 10kHz units */
-	u16 max;		/**< pixel clock, in 10kHz units */
-} __packed;
-
-struct psb_intel_sdvo_preferred_input_timing_args {
-	u16 clock;
-	u16 width;
-	u16 height;
-} __packed;
-
-/* I2C registers for SDVO */
-#define SDVO_I2C_ARG_0				0x07
-#define SDVO_I2C_ARG_1				0x06
-#define SDVO_I2C_ARG_2				0x05
-#define SDVO_I2C_ARG_3				0x04
-#define SDVO_I2C_ARG_4				0x03
-#define SDVO_I2C_ARG_5				0x02
-#define SDVO_I2C_ARG_6				0x01
-#define SDVO_I2C_ARG_7				0x00
-#define SDVO_I2C_OPCODE				0x08
-#define SDVO_I2C_CMD_STATUS			0x09
-#define SDVO_I2C_RETURN_0			0x0a
-#define SDVO_I2C_RETURN_1			0x0b
-#define SDVO_I2C_RETURN_2			0x0c
-#define SDVO_I2C_RETURN_3			0x0d
-#define SDVO_I2C_RETURN_4			0x0e
-#define SDVO_I2C_RETURN_5			0x0f
-#define SDVO_I2C_RETURN_6			0x10
-#define SDVO_I2C_RETURN_7			0x11
-#define SDVO_I2C_VENDOR_BEGIN			0x20
-
-/* Status results */
-#define SDVO_CMD_STATUS_POWER_ON		0x0
-#define SDVO_CMD_STATUS_SUCCESS			0x1
-#define SDVO_CMD_STATUS_NOTSUPP			0x2
-#define SDVO_CMD_STATUS_INVALID_ARG		0x3
-#define SDVO_CMD_STATUS_PENDING			0x4
-#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED	0x5
-#define SDVO_CMD_STATUS_SCALING_NOT_SUPP	0x6
-
-/* SDVO commands, argument/result registers */
-
-#define SDVO_CMD_RESET					0x01
-
-/** Returns a struct psb_intel_sdvo_caps */
-#define SDVO_CMD_GET_DEVICE_CAPS			0x02
-
-#define SDVO_CMD_GET_FIRMWARE_REV			0x86
-# define SDVO_DEVICE_FIRMWARE_MINOR			SDVO_I2C_RETURN_0
-# define SDVO_DEVICE_FIRMWARE_MAJOR			SDVO_I2C_RETURN_1
-# define SDVO_DEVICE_FIRMWARE_PATCH			SDVO_I2C_RETURN_2
-
-/**
- * Reports which inputs are trained (managed to sync).
- *
- * Devices must have trained within 2 vsyncs of a mode change.
- */
-#define SDVO_CMD_GET_TRAINED_INPUTS			0x03
-struct psb_intel_sdvo_get_trained_inputs_response {
-	unsigned int input0_trained:1;
-	unsigned int input1_trained:1;
-	unsigned int pad:6;
-} __packed;
-
-/** Returns a struct psb_intel_sdvo_output_flags of active outputs. */
-#define SDVO_CMD_GET_ACTIVE_OUTPUTS			0x04
-
-/**
- * Sets the current set of active outputs.
- *
- * Takes a struct psb_intel_sdvo_output_flags.
- * Must be preceded by a SET_IN_OUT_MAP
- * on multi-output devices.
- */
-#define SDVO_CMD_SET_ACTIVE_OUTPUTS			0x05
-
-/**
- * Returns the current mapping of SDVO inputs to outputs on the device.
- *
- * Returns two struct psb_intel_sdvo_output_flags structures.
- */
-#define SDVO_CMD_GET_IN_OUT_MAP				0x06
-
-/**
- * Sets the current mapping of SDVO inputs to outputs on the device.
- *
- * Takes two struct i380_sdvo_output_flags structures.
- */
-#define SDVO_CMD_SET_IN_OUT_MAP				0x07
-
-/**
- * Returns a struct psb_intel_sdvo_output_flags of attached displays.
- */
-#define SDVO_CMD_GET_ATTACHED_DISPLAYS			0x0b
-
-/**
- * Returns a struct psb_intel_sdvo_ouptut_flags of displays supporting hot plugging.
- */
-#define SDVO_CMD_GET_HOT_PLUG_SUPPORT			0x0c
-
-/**
- * Takes a struct psb_intel_sdvo_output_flags.
- */
-#define SDVO_CMD_SET_ACTIVE_HOT_PLUG			0x0d
-
-/**
- * Returns a struct psb_intel_sdvo_output_flags of displays with hot plug
- * interrupts enabled.
- */
-#define SDVO_CMD_GET_ACTIVE_HOT_PLUG			0x0e
-
-#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE		0x0f
-struct psb_intel_sdvo_get_interrupt_event_source_response {
-	u16 interrupt_status;
-	unsigned int ambient_light_interrupt:1;
-	unsigned int pad:7;
-} __packed;
-
-/**
- * Selects which input is affected by future input commands.
- *
- * Commands affected include SET_INPUT_TIMINGS_PART[12],
- * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12],
- * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS.
- */
-#define SDVO_CMD_SET_TARGET_INPUT			0x10
-struct psb_intel_sdvo_set_target_input_args {
-	unsigned int target_1:1;
-	unsigned int pad:7;
-} __packed;
-
-/**
- * Takes a struct psb_intel_sdvo_output_flags of which outputs are targeted by
- * future output commands.
- *
- * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12],
- * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE.
- */
-#define SDVO_CMD_SET_TARGET_OUTPUT			0x11
-
-#define SDVO_CMD_GET_INPUT_TIMINGS_PART1		0x12
-#define SDVO_CMD_GET_INPUT_TIMINGS_PART2		0x13
-#define SDVO_CMD_SET_INPUT_TIMINGS_PART1		0x14
-#define SDVO_CMD_SET_INPUT_TIMINGS_PART2		0x15
-#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1		0x16
-#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2		0x17
-#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1		0x18
-#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2		0x19
-/* Part 1 */
-# define SDVO_DTD_CLOCK_LOW				SDVO_I2C_ARG_0
-# define SDVO_DTD_CLOCK_HIGH				SDVO_I2C_ARG_1
-# define SDVO_DTD_H_ACTIVE				SDVO_I2C_ARG_2
-# define SDVO_DTD_H_BLANK				SDVO_I2C_ARG_3
-# define SDVO_DTD_H_HIGH				SDVO_I2C_ARG_4
-# define SDVO_DTD_V_ACTIVE				SDVO_I2C_ARG_5
-# define SDVO_DTD_V_BLANK				SDVO_I2C_ARG_6
-# define SDVO_DTD_V_HIGH				SDVO_I2C_ARG_7
-/* Part 2 */
-# define SDVO_DTD_HSYNC_OFF				SDVO_I2C_ARG_0
-# define SDVO_DTD_HSYNC_WIDTH				SDVO_I2C_ARG_1
-# define SDVO_DTD_VSYNC_OFF_WIDTH			SDVO_I2C_ARG_2
-# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH			SDVO_I2C_ARG_3
-# define SDVO_DTD_DTD_FLAGS				SDVO_I2C_ARG_4
-# define SDVO_DTD_DTD_FLAG_INTERLACED				(1 << 7)
-# define SDVO_DTD_DTD_FLAG_STEREO_MASK				(3 << 5)
-# define SDVO_DTD_DTD_FLAG_INPUT_MASK				(3 << 3)
-# define SDVO_DTD_DTD_FLAG_SYNC_MASK				(3 << 1)
-# define SDVO_DTD_SDVO_FLAS				SDVO_I2C_ARG_5
-# define SDVO_DTD_SDVO_FLAG_STALL				(1 << 7)
-# define SDVO_DTD_SDVO_FLAG_CENTERED				(0 << 6)
-# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT				(1 << 6)
-# define SDVO_DTD_SDVO_FLAG_SCALING_MASK			(3 << 4)
-# define SDVO_DTD_SDVO_FLAG_SCALING_NONE			(0 << 4)
-# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP			(1 << 4)
-# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH			(2 << 4)
-# define SDVO_DTD_VSYNC_OFF_HIGH			SDVO_I2C_ARG_6
-
-/**
- * Generates a DTD based on the given width, height, and flags.
- *
- * This will be supported by any device supporting scaling or interlaced
- * modes.
- */
-#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING		0x1a
-# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW		SDVO_I2C_ARG_0
-# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH		SDVO_I2C_ARG_1
-# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW		SDVO_I2C_ARG_2
-# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH		SDVO_I2C_ARG_3
-# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW		SDVO_I2C_ARG_4
-# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH	SDVO_I2C_ARG_5
-# define SDVO_PREFERRED_INPUT_TIMING_FLAGS		SDVO_I2C_ARG_6
-# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED		(1 << 0)
-# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED		(1 << 1)
-
-#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1	0x1b
-#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2	0x1c
-
-/** Returns a struct psb_intel_sdvo_pixel_clock_range */
-#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE		0x1d
-/** Returns a struct psb_intel_sdvo_pixel_clock_range */
-#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE		0x1e
-
-/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */
-#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS		0x1f
-
-/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
-#define SDVO_CMD_GET_CLOCK_RATE_MULT			0x20
-/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
-#define SDVO_CMD_SET_CLOCK_RATE_MULT			0x21
-# define SDVO_CLOCK_RATE_MULT_1X				(1 << 0)
-# define SDVO_CLOCK_RATE_MULT_2X				(1 << 1)
-# define SDVO_CLOCK_RATE_MULT_4X				(1 << 3)
-
-#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS		0x27
-
-#define SDVO_CMD_GET_TV_FORMAT				0x28
-
-#define SDVO_CMD_SET_TV_FORMAT				0x29
-
-#define SDVO_CMD_GET_SUPPORTED_POWER_STATES		0x2a
-#define SDVO_CMD_GET_ENCODER_POWER_STATE		0x2b
-#define SDVO_CMD_SET_ENCODER_POWER_STATE		0x2c
-# define SDVO_ENCODER_STATE_ON					(1 << 0)
-# define SDVO_ENCODER_STATE_STANDBY				(1 << 1)
-# define SDVO_ENCODER_STATE_SUSPEND				(1 << 2)
-# define SDVO_ENCODER_STATE_OFF					(1 << 3)
-
-#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT		0x93
-
-#define SDVO_CMD_SET_CONTROL_BUS_SWITCH			0x7a
-# define SDVO_CONTROL_BUS_PROM				0x0
-# define SDVO_CONTROL_BUS_DDC1				0x1
-# define SDVO_CONTROL_BUS_DDC2				0x2
-# define SDVO_CONTROL_BUS_DDC3				0x3
-
-/* SDVO Bus & SDVO Inputs wiring details*/
-/* Bit 0: Is SDVOB connected to In0 (1 = yes, 0 = no*/
-/* Bit 1: Is SDVOB connected to In1 (1 = yes, 0 = no*/
-/* Bit 2: Is SDVOC connected to In0 (1 = yes, 0 = no*/
-/* Bit 3: Is SDVOC connected to In1 (1 = yes, 0 = no*/
-#define SDVOB_IN0 0x01
-#define SDVOB_IN1 0x02
-#define SDVOC_IN0 0x04
-#define SDVOC_IN1 0x08
-
-#define SDVO_DEVICE_NONE 0x00
-#define        SDVO_DEVICE_CRT 0x01
-#define        SDVO_DEVICE_TV 0x02
-#define        SDVO_DEVICE_LVDS 0x04
-#define        SDVO_DEVICE_TMDS 0x08
-
diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c
deleted file mode 100644
index 36dd630..0000000
--- a/drivers/staging/gma500/psb_irq.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- * develop this driver.
- *
- **************************************************************************/
-/*
- */
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "power.h"
-#include "mdfld_output.h"
-
-/*
- * inline functions
- */
-
-static inline u32
-psb_pipestat(int pipe)
-{
-	if (pipe == 0)
-		return PIPEASTAT;
-	if (pipe == 1)
-		return PIPEBSTAT;
-	if (pipe == 2)
-		return PIPECSTAT;
-	BUG();
-}
-
-static inline u32
-mid_pipe_event(int pipe)
-{
-	if (pipe == 0)
-		return _PSB_PIPEA_EVENT_FLAG;
-	if (pipe == 1)
-		return _MDFLD_PIPEB_EVENT_FLAG;
-	if (pipe == 2)
-		return _MDFLD_PIPEC_EVENT_FLAG;
-	BUG();
-}
-
-static inline u32
-mid_pipe_vsync(int pipe)
-{
-	if (pipe == 0)
-		return _PSB_VSYNC_PIPEA_FLAG;
-	if (pipe == 1)
-		return _PSB_VSYNC_PIPEB_FLAG;
-	if (pipe == 2)
-		return _MDFLD_PIPEC_VBLANK_FLAG;
-	BUG();
-}
-
-static inline u32
-mid_pipeconf(int pipe)
-{
-	if (pipe == 0)
-		return PIPEACONF;
-	if (pipe == 1)
-		return PIPEBCONF;
-	if (pipe == 2)
-		return PIPECCONF;
-	BUG();
-}
-
-void
-psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
-{
-	if ((dev_priv->pipestat[pipe] & mask) != mask) {
-		u32 reg = psb_pipestat(pipe);
-		dev_priv->pipestat[pipe] |= mask;
-		/* Enable the interrupt, clear any pending status */
-		if (gma_power_begin(dev_priv->dev, false)) {
-			u32 writeVal = PSB_RVDC32(reg);
-			writeVal |= (mask | (mask >> 16));
-			PSB_WVDC32(writeVal, reg);
-			(void) PSB_RVDC32(reg);
-			gma_power_end(dev_priv->dev);
-		}
-	}
-}
-
-void
-psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
-{
-	if ((dev_priv->pipestat[pipe] & mask) != 0) {
-		u32 reg = psb_pipestat(pipe);
-		dev_priv->pipestat[pipe] &= ~mask;
-		if (gma_power_begin(dev_priv->dev, false)) {
-			u32 writeVal = PSB_RVDC32(reg);
-			writeVal &= ~mask;
-			PSB_WVDC32(writeVal, reg);
-			(void) PSB_RVDC32(reg);
-			gma_power_end(dev_priv->dev);
-		}
-	}
-}
-
-void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
-{
-	if (gma_power_begin(dev_priv->dev, false)) {
-		u32 pipe_event = mid_pipe_event(pipe);
-		dev_priv->vdc_irq_mask |= pipe_event;
-		PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-		PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-		gma_power_end(dev_priv->dev);
-	}
-}
-
-void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
-{
-	if (dev_priv->pipestat[pipe] == 0) {
-		if (gma_power_begin(dev_priv->dev, false)) {
-			u32 pipe_event = mid_pipe_event(pipe);
-			dev_priv->vdc_irq_mask &= ~pipe_event;
-			PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-			PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-			gma_power_end(dev_priv->dev);
-		}
-	}
-}
-
-/**
- * Display controller interrupt handler for pipe event.
- *
- */
-static void mid_pipe_event_handler(struct drm_device *dev, int pipe)
-{
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-
-	uint32_t pipe_stat_val = 0;
-	uint32_t pipe_stat_reg = psb_pipestat(pipe);
-	uint32_t pipe_enable = dev_priv->pipestat[pipe];
-	uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;
-	uint32_t pipe_clear;
-	uint32_t i = 0;
-
-	spin_lock(&dev_priv->irqmask_lock);
-
-	pipe_stat_val = PSB_RVDC32(pipe_stat_reg);
-	pipe_stat_val &= pipe_enable | pipe_status;
-	pipe_stat_val &= pipe_stat_val >> 16;
-
-	spin_unlock(&dev_priv->irqmask_lock);
-
-	/* Clear the 2nd level interrupt status bits
-	 * Sometimes the bits are very sticky so we repeat until they unstick */
-	for (i = 0; i < 0xffff; i++) {
-		PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg);
-		pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status;
-
-		if (pipe_clear == 0)
-			break;
-	}
-
-	if (pipe_clear)
-		dev_err(dev->dev,
-		"%s, can't clear status bits for pipe %d, its value = 0x%x.\n",
-		__func__, pipe, PSB_RVDC32(pipe_stat_reg));
-
-	if (pipe_stat_val & PIPE_VBLANK_STATUS)
-		drm_handle_vblank(dev, pipe);
-
-	if (pipe_stat_val & PIPE_TE_STATUS)
-		drm_handle_vblank(dev, pipe);
-}
-
-/*
- * Display controller interrupt handler.
- */
-static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
-{
-	if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
-		mid_pipe_event_handler(dev, 0);
-
-	if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)
-		mid_pipe_event_handler(dev, 1);
-}
-
-irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
-{
-	struct drm_device *dev = (struct drm_device *) arg;
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-
-	uint32_t vdc_stat, dsp_int = 0, sgx_int = 0;
-	int handled = 0;
-
-	spin_lock(&dev_priv->irqmask_lock);
-
-	vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
-
-	if (vdc_stat & _PSB_PIPE_EVENT_FLAG)
-		dsp_int = 1;
-
-	/* FIXME: Handle Medfield
-	if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG)
-		dsp_int = 1;
-	*/
-
-	if (vdc_stat & _PSB_IRQ_SGX_FLAG)
-		sgx_int = 1;
-
-	vdc_stat &= dev_priv->vdc_irq_mask;
-	spin_unlock(&dev_priv->irqmask_lock);
-
-	if (dsp_int && gma_power_is_on(dev)) {
-		psb_vdc_interrupt(dev, vdc_stat);
-		handled = 1;
-	}
-
-	if (sgx_int) {
-		/* Not expected - we have it masked, shut it up */
-		u32 s, s2;
-		s = PSB_RSGX32(PSB_CR_EVENT_STATUS);
-		s2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2);
-		PSB_WSGX32(s, PSB_CR_EVENT_HOST_CLEAR);
-		PSB_WSGX32(s2, PSB_CR_EVENT_HOST_CLEAR2);
-		/* if s & _PSB_CE_TWOD_COMPLETE we have 2D done but
-		   we may as well poll even if we add that ! */
-		handled = 1;
-	}
-
-	PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
-	(void) PSB_RVDC32(PSB_INT_IDENTITY_R);
-	DRM_READMEMORYBARRIER();
-
-	if (!handled)
-		return IRQ_NONE;
-
-	return IRQ_HANDLED;
-}
-
-void psb_irq_preinstall(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-	if (gma_power_is_on(dev))
-		PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-	if (dev->vblank_enabled[0])
-		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
-	if (dev->vblank_enabled[1])
-		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
-
-	/* FIXME: Handle Medfield irq mask
-	if (dev->vblank_enabled[1])
-		dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
-	if (dev->vblank_enabled[2])
-		dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
-	*/
-
-	/* This register is safe even if display island is off */
-	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-}
-
-int psb_irq_postinstall(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-	/* This register is safe even if display island is off */
-	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-
-	if (dev->vblank_enabled[0])
-		psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
-	else
-		psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-	if (dev->vblank_enabled[1])
-		psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
-	else
-		psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-	if (dev->vblank_enabled[2])
-		psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
-	else
-		psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-	return 0;
-}
-
-void psb_irq_uninstall(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-
-	if (dev->vblank_enabled[0])
-		psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-	if (dev->vblank_enabled[1])
-		psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-	if (dev->vblank_enabled[2])
-		psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-	dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
-				  _PSB_IRQ_MSVDX_FLAG |
-				  _LNC_IRQ_TOPAZ_FLAG;
-
-	/* These two registers are safe even if display island is off */
-	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-
-	wmb();
-
-	/* This register is safe even if display island is off */
-	PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-}
-
-void psb_irq_turn_on_dpst(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv =
-		(struct drm_psb_private *) dev->dev_private;
-	u32 hist_reg;
-	u32 pwm_reg;
-
-	if (gma_power_begin(dev, false)) {
-		PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL);
-		hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
-		PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL);
-		hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-
-		PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC);
-		pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-		PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE
-						| PWM_PHASEIN_INT_ENABLE,
-							   PWM_CONTROL_LOGIC);
-		pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-
-		psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
-
-		hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-		PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR,
-							HISTOGRAM_INT_CONTROL);
-		pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-		PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
-							PWM_CONTROL_LOGIC);
-
-		gma_power_end(dev);
-	}
-}
-
-int psb_irq_enable_dpst(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv =
-		(struct drm_psb_private *) dev->dev_private;
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-	/* enable DPST */
-	mid_enable_pipe_event(dev_priv, 0);
-	psb_irq_turn_on_dpst(dev);
-
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-	return 0;
-}
-
-void psb_irq_turn_off_dpst(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-	u32 hist_reg;
-	u32 pwm_reg;
-
-	if (gma_power_begin(dev, false)) {
-		PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
-		hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-
-		psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
-
-		pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-		PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE),
-							PWM_CONTROL_LOGIC);
-		pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-
-		gma_power_end(dev);
-	}
-}
-
-int psb_irq_disable_dpst(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-	mid_disable_pipe_event(dev_priv, 0);
-	psb_irq_turn_off_dpst(dev);
-
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-
-	return 0;
-}
-
-#ifdef PSB_FIXME
-static int psb_vblank_do_wait(struct drm_device *dev,
-			      unsigned int *sequence, atomic_t *counter)
-{
-	unsigned int cur_vblank;
-	int ret = 0;
-	DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
-		    (((cur_vblank = atomic_read(counter))
-		      - *sequence) <= (1 << 23)));
-	*sequence = cur_vblank;
-
-	return ret;
-}
-#endif
-
-/*
- * It is used to enable VBLANK interrupt
- */
-int psb_enable_vblank(struct drm_device *dev, int pipe)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long irqflags;
-	uint32_t reg_val = 0;
-	uint32_t pipeconf_reg = mid_pipeconf(pipe);
-
-#if defined(CONFIG_DRM_PSB_MFLD)
-	/* Medfield is different - we should perhaps extract out vblank
-	   and blacklight etc ops */
-	if (IS_MFLD(dev) && !mdfld_panel_dpi(dev))
-		return mdfld_enable_te(dev, pipe);
-#endif
-	if (gma_power_begin(dev, false)) {
-		reg_val = REG_READ(pipeconf_reg);
-		gma_power_end(dev);
-	}
-
-	if (!(reg_val & PIPEACONF_ENABLE))
-		return -EINVAL;
-
-	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-	if (pipe == 0)
-		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
-	else if (pipe == 1)
-		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
-
-	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-	psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-
-	return 0;
-}
-
-/*
- * It is used to disable VBLANK interrupt
- */
-void psb_disable_vblank(struct drm_device *dev, int pipe)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long irqflags;
-
-#if defined(CONFIG_DRM_PSB_MFLD)
-	if (IS_MFLD(dev) && !mdfld_panel_dpi(dev))
-		mdfld_disable_te(dev, pipe);
-#endif
-	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-
-	if (pipe == 0)
-		dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG;
-	else if (pipe == 1)
-		dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG;
-
-	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-	psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
-
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-}
-
-/**
- *	mdfld_enable_te		-	enable TE events
- *	@dev: our DRM device
- *	@pipe: which pipe to work on
- *
- *	Enable TE events on a Medfield display pipe. Medfield specific.
- */
-int mdfld_enable_te(struct drm_device *dev, int pipe)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long flags;
-	uint32_t reg_val = 0;
-	uint32_t pipeconf_reg = mid_pipeconf(pipe);
-
-	if (gma_power_begin(dev, false)) {
-		reg_val = REG_READ(pipeconf_reg);
-		gma_power_end(dev);
-	}
-
-	if (!(reg_val & PIPEACONF_ENABLE))
-		return -EINVAL;
-
-	spin_lock_irqsave(&dev_priv->irqmask_lock, flags);
-
-	mid_enable_pipe_event(dev_priv, pipe);
-	psb_enable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE);
-
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, flags);
-
-	return 0;
-}
-
-/**
- *	mdfld_disable_te		-	disable TE events
- *	@dev: our DRM device
- *	@pipe: which pipe to work on
- *
- *	Disable TE events on a Medfield display pipe. Medfield specific.
- */
-void mdfld_disable_te(struct drm_device *dev, int pipe)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev_priv->irqmask_lock, flags);
-
-	mid_disable_pipe_event(dev_priv, pipe);
-	psb_disable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE);
-
-	spin_unlock_irqrestore(&dev_priv->irqmask_lock, flags);
-}
-
-/* Called from drm generic code, passed a 'crtc', which
- * we use as a pipe index
- */
-u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
-{
-	uint32_t high_frame = PIPEAFRAMEHIGH;
-	uint32_t low_frame = PIPEAFRAMEPIXEL;
-	uint32_t pipeconf_reg = PIPEACONF;
-	uint32_t reg_val = 0;
-	uint32_t high1 = 0, high2 = 0, low = 0, count = 0;
-
-	switch (pipe) {
-	case 0:
-		break;
-	case 1:
-		high_frame = PIPEBFRAMEHIGH;
-		low_frame = PIPEBFRAMEPIXEL;
-		pipeconf_reg = PIPEBCONF;
-		break;
-	case 2:
-		high_frame = PIPECFRAMEHIGH;
-		low_frame = PIPECFRAMEPIXEL;
-		pipeconf_reg = PIPECCONF;
-		break;
-	default:
-		dev_err(dev->dev, "%s, invalid pipe.\n", __func__);
-		return 0;
-	}
-
-	if (!gma_power_begin(dev, false))
-		return 0;
-
-	reg_val = REG_READ(pipeconf_reg);
-
-	if (!(reg_val & PIPEACONF_ENABLE)) {
-		dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n",
-								pipe);
-		goto psb_get_vblank_counter_exit;
-	}
-
-	/*
-	 * High & low register fields aren't synchronized, so make sure
-	 * we get a low value that's stable across two reads of the high
-	 * register.
-	 */
-	do {
-		high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
-			 PIPE_FRAME_HIGH_SHIFT);
-		low =  ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
-			PIPE_FRAME_LOW_SHIFT);
-		high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
-			 PIPE_FRAME_HIGH_SHIFT);
-	} while (high1 != high2);
-
-	count = (high1 << 8) | low;
-
-psb_get_vblank_counter_exit:
-
-	gma_power_end(dev);
-
-	return count;
-}
-
diff --git a/drivers/staging/gma500/psb_irq.h b/drivers/staging/gma500/psb_irq.h
deleted file mode 100644
index 216fda3..0000000
--- a/drivers/staging/gma500/psb_irq.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2009-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors:
- *    Benjamin Defnet <benjamin.r.defnet@intel.com>
- *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- *
- **************************************************************************/
-
-#ifndef _SYSIRQ_H_
-#define _SYSIRQ_H_
-
-#include <drm/drmP.h>
-
-bool sysirq_init(struct drm_device *dev);
-void sysirq_uninit(struct drm_device *dev);
-
-void psb_irq_preinstall(struct drm_device *dev);
-int  psb_irq_postinstall(struct drm_device *dev);
-void psb_irq_uninstall(struct drm_device *dev);
-irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);
-
-int psb_irq_enable_dpst(struct drm_device *dev);
-int psb_irq_disable_dpst(struct drm_device *dev);
-void psb_irq_turn_on_dpst(struct drm_device *dev);
-void psb_irq_turn_off_dpst(struct drm_device *dev);
-int  psb_enable_vblank(struct drm_device *dev, int pipe);
-void psb_disable_vblank(struct drm_device *dev, int pipe);
-u32  psb_get_vblank_counter(struct drm_device *dev, int pipe);
-
-#endif /* _SYSIRQ_H_ */
diff --git a/drivers/staging/gma500/psb_lid.c b/drivers/staging/gma500/psb_lid.c
deleted file mode 100644
index b867aab..0000000
--- a/drivers/staging/gma500/psb_lid.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include <linux/spinlock.h>
-
-static void psb_lid_timer_func(unsigned long data)
-{
-	struct drm_psb_private * dev_priv = (struct drm_psb_private *)data;
-	struct drm_device *dev = (struct drm_device *)dev_priv->dev;
-	struct timer_list *lid_timer = &dev_priv->lid_timer;
-	unsigned long irq_flags;
-	u32 *lid_state = dev_priv->lid_state;
-	u32 pp_status;
-
-	if (readl(lid_state) == dev_priv->lid_last_state)
-		goto lid_timer_schedule;
-
-	if ((readl(lid_state)) & 0x01) {
-		/*lid state is open*/
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while ((pp_status & PP_ON) == 0);
-
-		/*FIXME: should be backlight level before*/
-		psb_intel_lvds_set_brightness(dev, 100);
-	} else {
-		psb_intel_lvds_set_brightness(dev, 0);
-
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while ((pp_status & PP_ON) == 0);
-	}
-	dev_priv->lid_last_state =  readl(lid_state);
-
-lid_timer_schedule:
-	spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
-	if (!timer_pending(lid_timer)) {
-		lid_timer->expires = jiffies + PSB_LID_DELAY;
-		add_timer(lid_timer);
-	}
-	spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
-}
-
-void psb_lid_timer_init(struct drm_psb_private *dev_priv)
-{
-	struct timer_list *lid_timer = &dev_priv->lid_timer;
-	unsigned long irq_flags;
-
-	spin_lock_init(&dev_priv->lid_lock);
-	spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
-
-	init_timer(lid_timer);
-
-	lid_timer->data = (unsigned long)dev_priv;
-	lid_timer->function = psb_lid_timer_func;
-	lid_timer->expires = jiffies + PSB_LID_DELAY;
-
-	add_timer(lid_timer);
-	spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
-}
-
-void psb_lid_timer_takedown(struct drm_psb_private *dev_priv)
-{
-	del_timer_sync(&dev_priv->lid_timer);
-}
-
diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h
deleted file mode 100644
index b81c7c1..0000000
--- a/drivers/staging/gma500/psb_reg.h
+++ /dev/null
@@ -1,582 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) (2005-2007) Imagination Technologies Limited.
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA..
- *
- **************************************************************************/
-
-#ifndef _PSB_REG_H_
-#define _PSB_REG_H_
-
-#define PSB_CR_CLKGATECTL		0x0000
-#define _PSB_C_CLKGATECTL_AUTO_MAN_REG		(1 << 24)
-#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT	(20)
-#define _PSB_C_CLKGATECTL_USE_CLKG_MASK		(0x3 << 20)
-#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT	(16)
-#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK		(0x3 << 16)
-#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT		(12)
-#define _PSB_C_CLKGATECTL_TA_CLKG_MASK		(0x3 << 12)
-#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT	(8)
-#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK		(0x3 << 8)
-#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT	(4)
-#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK		(0x3 << 4)
-#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT		(0)
-#define _PSB_C_CLKGATECTL_2D_CLKG_MASK		(0x3 << 0)
-#define _PSB_C_CLKGATECTL_CLKG_ENABLED		(0)
-#define _PSB_C_CLKGATECTL_CLKG_DISABLED		(1)
-#define _PSB_C_CLKGATECTL_CLKG_AUTO		(2)
-
-#define PSB_CR_CORE_ID			0x0010
-#define _PSB_CC_ID_ID_SHIFT			(16)
-#define _PSB_CC_ID_ID_MASK			(0xFFFF << 16)
-#define _PSB_CC_ID_CONFIG_SHIFT			(0)
-#define _PSB_CC_ID_CONFIG_MASK			(0xFFFF << 0)
-
-#define PSB_CR_CORE_REVISION		0x0014
-#define _PSB_CC_REVISION_DESIGNER_SHIFT		(24)
-#define _PSB_CC_REVISION_DESIGNER_MASK		(0xFF << 24)
-#define _PSB_CC_REVISION_MAJOR_SHIFT		(16)
-#define _PSB_CC_REVISION_MAJOR_MASK		(0xFF << 16)
-#define _PSB_CC_REVISION_MINOR_SHIFT		(8)
-#define _PSB_CC_REVISION_MINOR_MASK		(0xFF << 8)
-#define _PSB_CC_REVISION_MAINTENANCE_SHIFT	(0)
-#define _PSB_CC_REVISION_MAINTENANCE_MASK	(0xFF << 0)
-
-#define PSB_CR_DESIGNER_REV_FIELD1	0x0018
-
-#define PSB_CR_SOFT_RESET		0x0080
-#define _PSB_CS_RESET_TSP_RESET		(1 << 6)
-#define _PSB_CS_RESET_ISP_RESET		(1 << 5)
-#define _PSB_CS_RESET_USE_RESET		(1 << 4)
-#define _PSB_CS_RESET_TA_RESET		(1 << 3)
-#define _PSB_CS_RESET_DPM_RESET		(1 << 2)
-#define _PSB_CS_RESET_TWOD_RESET	(1 << 1)
-#define _PSB_CS_RESET_BIF_RESET			(1 << 0)
-
-#define PSB_CR_DESIGNER_REV_FIELD2	0x001C
-
-#define PSB_CR_EVENT_HOST_ENABLE2	0x0110
-
-#define PSB_CR_EVENT_STATUS2		0x0118
-
-#define PSB_CR_EVENT_HOST_CLEAR2	0x0114
-#define _PSB_CE2_BIF_REQUESTER_FAULT		(1 << 4)
-
-#define PSB_CR_EVENT_STATUS		0x012C
-
-#define PSB_CR_EVENT_HOST_ENABLE	0x0130
-
-#define PSB_CR_EVENT_HOST_CLEAR		0x0134
-#define _PSB_CE_MASTER_INTERRUPT		(1 << 31)
-#define _PSB_CE_TA_DPM_FAULT			(1 << 28)
-#define _PSB_CE_TWOD_COMPLETE			(1 << 27)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS		(1 << 25)
-#define _PSB_CE_DPM_TA_MEM_FREE			(1 << 24)
-#define _PSB_CE_PIXELBE_END_RENDER		(1 << 18)
-#define _PSB_CE_SW_EVENT			(1 << 14)
-#define _PSB_CE_TA_FINISHED			(1 << 13)
-#define _PSB_CE_TA_TERMINATE			(1 << 12)
-#define _PSB_CE_DPM_REACHED_MEM_THRESH		(1 << 3)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL		(1 << 2)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_MT		(1 << 1)
-#define _PSB_CE_DPM_3D_MEM_FREE			(1 << 0)
-
-
-#define PSB_USE_OFFSET_MASK		0x0007FFFF
-#define PSB_USE_OFFSET_SIZE		(PSB_USE_OFFSET_MASK + 1)
-#define PSB_CR_USE_CODE_BASE0		0x0A0C
-#define PSB_CR_USE_CODE_BASE1		0x0A10
-#define PSB_CR_USE_CODE_BASE2		0x0A14
-#define PSB_CR_USE_CODE_BASE3		0x0A18
-#define PSB_CR_USE_CODE_BASE4		0x0A1C
-#define PSB_CR_USE_CODE_BASE5		0x0A20
-#define PSB_CR_USE_CODE_BASE6		0x0A24
-#define PSB_CR_USE_CODE_BASE7		0x0A28
-#define PSB_CR_USE_CODE_BASE8		0x0A2C
-#define PSB_CR_USE_CODE_BASE9		0x0A30
-#define PSB_CR_USE_CODE_BASE10		0x0A34
-#define PSB_CR_USE_CODE_BASE11		0x0A38
-#define PSB_CR_USE_CODE_BASE12		0x0A3C
-#define PSB_CR_USE_CODE_BASE13		0x0A40
-#define PSB_CR_USE_CODE_BASE14		0x0A44
-#define PSB_CR_USE_CODE_BASE15		0x0A48
-#define PSB_CR_USE_CODE_BASE(_i)	(0x0A0C + ((_i) << 2))
-#define _PSB_CUC_BASE_DM_SHIFT			(25)
-#define _PSB_CUC_BASE_DM_MASK			(0x3 << 25)
-#define _PSB_CUC_BASE_ADDR_SHIFT		(0)	/* 1024-bit aligned address? */
-#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT		(7)
-#define _PSB_CUC_BASE_ADDR_MASK			(0x1FFFFFF << 0)
-#define _PSB_CUC_DM_VERTEX			(0)
-#define _PSB_CUC_DM_PIXEL			(1)
-#define _PSB_CUC_DM_RESERVED			(2)
-#define _PSB_CUC_DM_EDM				(3)
-
-#define PSB_CR_PDS_EXEC_BASE		0x0AB8
-#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT	(20)	/* 1MB aligned address */
-#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT	(20)
-
-#define PSB_CR_EVENT_KICKER		0x0AC4
-#define _PSB_CE_KICKER_ADDRESS_SHIFT		(4)	/* 128-bit aligned address */
-
-#define PSB_CR_EVENT_KICK		0x0AC8
-#define _PSB_CE_KICK_NOW			(1 << 0)
-
-#define PSB_CR_BIF_DIR_LIST_BASE1	0x0C38
-
-#define PSB_CR_BIF_CTRL			0x0C00
-#define _PSB_CB_CTRL_CLEAR_FAULT		(1 << 4)
-#define _PSB_CB_CTRL_INVALDC			(1 << 3)
-#define _PSB_CB_CTRL_FLUSH			(1 << 2)
-
-#define PSB_CR_BIF_INT_STAT		0x0C04
-
-#define PSB_CR_BIF_FAULT		0x0C08
-#define _PSB_CBI_STAT_PF_N_RW			(1 << 14)
-#define _PSB_CBI_STAT_FAULT_SHIFT		(0)
-#define _PSB_CBI_STAT_FAULT_MASK		(0x3FFF << 0)
-#define _PSB_CBI_STAT_FAULT_CACHE		(1 << 1)
-#define _PSB_CBI_STAT_FAULT_TA			(1 << 2)
-#define _PSB_CBI_STAT_FAULT_VDM			(1 << 3)
-#define _PSB_CBI_STAT_FAULT_2D			(1 << 4)
-#define _PSB_CBI_STAT_FAULT_PBE			(1 << 5)
-#define _PSB_CBI_STAT_FAULT_TSP			(1 << 6)
-#define _PSB_CBI_STAT_FAULT_ISP			(1 << 7)
-#define _PSB_CBI_STAT_FAULT_USSEPDS		(1 << 8)
-#define _PSB_CBI_STAT_FAULT_HOST		(1 << 9)
-
-#define PSB_CR_BIF_BANK0		0x0C78
-#define PSB_CR_BIF_BANK1		0x0C7C
-#define PSB_CR_BIF_DIR_LIST_BASE0	0x0C84
-#define PSB_CR_BIF_TWOD_REQ_BASE	0x0C88
-#define PSB_CR_BIF_3D_REQ_BASE		0x0CAC
-
-#define PSB_CR_2D_SOCIF			0x0E18
-#define _PSB_C2_SOCIF_FREESPACE_SHIFT		(0)
-#define _PSB_C2_SOCIF_FREESPACE_MASK		(0xFF << 0)
-#define _PSB_C2_SOCIF_EMPTY			(0x80 << 0)
-
-#define PSB_CR_2D_BLIT_STATUS		0x0E04
-#define _PSB_C2B_STATUS_BUSY			(1 << 24)
-#define _PSB_C2B_STATUS_COMPLETE_SHIFT		(0)
-#define _PSB_C2B_STATUS_COMPLETE_MASK		(0xFFFFFF << 0)
-
-/*
- * 2D defs.
- */
-
-/*
- * 2D Slave Port Data : Block Header's Object Type
- */
-
-#define	PSB_2D_CLIP_BH			(0x00000000)
-#define	PSB_2D_PAT_BH			(0x10000000)
-#define	PSB_2D_CTRL_BH			(0x20000000)
-#define	PSB_2D_SRC_OFF_BH		(0x30000000)
-#define	PSB_2D_MASK_OFF_BH		(0x40000000)
-#define	PSB_2D_RESERVED1_BH		(0x50000000)
-#define	PSB_2D_RESERVED2_BH		(0x60000000)
-#define	PSB_2D_FENCE_BH			(0x70000000)
-#define	PSB_2D_BLIT_BH			(0x80000000)
-#define	PSB_2D_SRC_SURF_BH		(0x90000000)
-#define	PSB_2D_DST_SURF_BH		(0xA0000000)
-#define	PSB_2D_PAT_SURF_BH		(0xB0000000)
-#define	PSB_2D_SRC_PAL_BH		(0xC0000000)
-#define	PSB_2D_PAT_PAL_BH		(0xD0000000)
-#define	PSB_2D_MASK_SURF_BH		(0xE0000000)
-#define	PSB_2D_FLUSH_BH			(0xF0000000)
-
-/*
- * Clip Definition block (PSB_2D_CLIP_BH)
- */
-#define PSB_2D_CLIPCOUNT_MAX		(1)
-#define PSB_2D_CLIPCOUNT_MASK		(0x00000000)
-#define PSB_2D_CLIPCOUNT_CLRMASK	(0xFFFFFFFF)
-#define PSB_2D_CLIPCOUNT_SHIFT		(0)
-/* clip rectangle min & max */
-#define PSB_2D_CLIP_XMAX_MASK		(0x00FFF000)
-#define PSB_2D_CLIP_XMAX_CLRMASK	(0xFF000FFF)
-#define PSB_2D_CLIP_XMAX_SHIFT		(12)
-#define PSB_2D_CLIP_XMIN_MASK		(0x00000FFF)
-#define PSB_2D_CLIP_XMIN_CLRMASK	(0x00FFF000)
-#define PSB_2D_CLIP_XMIN_SHIFT		(0)
-/* clip rectangle offset */
-#define PSB_2D_CLIP_YMAX_MASK		(0x00FFF000)
-#define PSB_2D_CLIP_YMAX_CLRMASK	(0xFF000FFF)
-#define PSB_2D_CLIP_YMAX_SHIFT		(12)
-#define PSB_2D_CLIP_YMIN_MASK		(0x00000FFF)
-#define PSB_2D_CLIP_YMIN_CLRMASK	(0x00FFF000)
-#define PSB_2D_CLIP_YMIN_SHIFT		(0)
-
-/*
- * Pattern Control (PSB_2D_PAT_BH)
- */
-#define PSB_2D_PAT_HEIGHT_MASK		(0x0000001F)
-#define PSB_2D_PAT_HEIGHT_SHIFT		(0)
-#define PSB_2D_PAT_WIDTH_MASK		(0x000003E0)
-#define PSB_2D_PAT_WIDTH_SHIFT		(5)
-#define PSB_2D_PAT_YSTART_MASK		(0x00007C00)
-#define PSB_2D_PAT_YSTART_SHIFT		(10)
-#define PSB_2D_PAT_XSTART_MASK		(0x000F8000)
-#define PSB_2D_PAT_XSTART_SHIFT		(15)
-
-/*
- * 2D Control block (PSB_2D_CTRL_BH)
- */
-/* Present Flags */
-#define PSB_2D_SRCCK_CTRL		(0x00000001)
-#define PSB_2D_DSTCK_CTRL		(0x00000002)
-#define PSB_2D_ALPHA_CTRL		(0x00000004)
-/* Colour Key Colour (SRC/DST)*/
-#define PSB_2D_CK_COL_MASK		(0xFFFFFFFF)
-#define PSB_2D_CK_COL_CLRMASK		(0x00000000)
-#define PSB_2D_CK_COL_SHIFT		(0)
-/* Colour Key Mask (SRC/DST)*/
-#define PSB_2D_CK_MASK_MASK		(0xFFFFFFFF)
-#define PSB_2D_CK_MASK_CLRMASK		(0x00000000)
-#define PSB_2D_CK_MASK_SHIFT		(0)
-/* Alpha Control (Alpha/RGB)*/
-#define PSB_2D_GBLALPHA_MASK		(0x000FF000)
-#define PSB_2D_GBLALPHA_CLRMASK		(0xFFF00FFF)
-#define PSB_2D_GBLALPHA_SHIFT		(12)
-#define PSB_2D_SRCALPHA_OP_MASK		(0x00700000)
-#define PSB_2D_SRCALPHA_OP_CLRMASK	(0xFF8FFFFF)
-#define PSB_2D_SRCALPHA_OP_SHIFT	(20)
-#define PSB_2D_SRCALPHA_OP_ONE		(0x00000000)
-#define PSB_2D_SRCALPHA_OP_SRC		(0x00100000)
-#define PSB_2D_SRCALPHA_OP_DST		(0x00200000)
-#define PSB_2D_SRCALPHA_OP_SG		(0x00300000)
-#define PSB_2D_SRCALPHA_OP_DG		(0x00400000)
-#define PSB_2D_SRCALPHA_OP_GBL		(0x00500000)
-#define PSB_2D_SRCALPHA_OP_ZERO		(0x00600000)
-#define PSB_2D_SRCALPHA_INVERT		(0x00800000)
-#define PSB_2D_SRCALPHA_INVERT_CLR	(0xFF7FFFFF)
-#define PSB_2D_DSTALPHA_OP_MASK		(0x07000000)
-#define PSB_2D_DSTALPHA_OP_CLRMASK	(0xF8FFFFFF)
-#define PSB_2D_DSTALPHA_OP_SHIFT	(24)
-#define PSB_2D_DSTALPHA_OP_ONE		(0x00000000)
-#define PSB_2D_DSTALPHA_OP_SRC		(0x01000000)
-#define PSB_2D_DSTALPHA_OP_DST		(0x02000000)
-#define PSB_2D_DSTALPHA_OP_SG		(0x03000000)
-#define PSB_2D_DSTALPHA_OP_DG		(0x04000000)
-#define PSB_2D_DSTALPHA_OP_GBL		(0x05000000)
-#define PSB_2D_DSTALPHA_OP_ZERO		(0x06000000)
-#define PSB_2D_DSTALPHA_INVERT		(0x08000000)
-#define PSB_2D_DSTALPHA_INVERT_CLR	(0xF7FFFFFF)
-
-#define PSB_2D_PRE_MULTIPLICATION_ENABLE	(0x10000000)
-#define PSB_2D_PRE_MULTIPLICATION_CLRMASK	(0xEFFFFFFF)
-#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE		(0x20000000)
-#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK	(0xDFFFFFFF)
-
-/*
- *Source Offset (PSB_2D_SRC_OFF_BH)
- */
-#define PSB_2D_SRCOFF_XSTART_MASK	((0x00000FFF) << 12)
-#define PSB_2D_SRCOFF_XSTART_SHIFT	(12)
-#define PSB_2D_SRCOFF_YSTART_MASK	(0x00000FFF)
-#define PSB_2D_SRCOFF_YSTART_SHIFT	(0)
-
-/*
- * Mask Offset (PSB_2D_MASK_OFF_BH)
- */
-#define PSB_2D_MASKOFF_XSTART_MASK	((0x00000FFF) << 12)
-#define PSB_2D_MASKOFF_XSTART_SHIFT	(12)
-#define PSB_2D_MASKOFF_YSTART_MASK	(0x00000FFF)
-#define PSB_2D_MASKOFF_YSTART_SHIFT	(0)
-
-/*
- * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored
- */
-
-/*
- *Blit Rectangle (PSB_2D_BLIT_BH)
- */
-
-#define PSB_2D_ROT_MASK			(3 << 25)
-#define PSB_2D_ROT_CLRMASK		(~PSB_2D_ROT_MASK)
-#define PSB_2D_ROT_NONE			(0 << 25)
-#define PSB_2D_ROT_90DEGS		(1 << 25)
-#define PSB_2D_ROT_180DEGS		(2 << 25)
-#define PSB_2D_ROT_270DEGS		(3 << 25)
-
-#define PSB_2D_COPYORDER_MASK		(3 << 23)
-#define PSB_2D_COPYORDER_CLRMASK	(~PSB_2D_COPYORDER_MASK)
-#define PSB_2D_COPYORDER_TL2BR		(0 << 23)
-#define PSB_2D_COPYORDER_BR2TL		(1 << 23)
-#define PSB_2D_COPYORDER_TR2BL		(2 << 23)
-#define PSB_2D_COPYORDER_BL2TR		(3 << 23)
-
-#define PSB_2D_DSTCK_CLRMASK		(0xFF9FFFFF)
-#define PSB_2D_DSTCK_DISABLE		(0x00000000)
-#define PSB_2D_DSTCK_PASS		(0x00200000)
-#define PSB_2D_DSTCK_REJECT		(0x00400000)
-
-#define PSB_2D_SRCCK_CLRMASK		(0xFFE7FFFF)
-#define PSB_2D_SRCCK_DISABLE		(0x00000000)
-#define PSB_2D_SRCCK_PASS		(0x00080000)
-#define PSB_2D_SRCCK_REJECT		(0x00100000)
-
-#define PSB_2D_CLIP_ENABLE		(0x00040000)
-
-#define PSB_2D_ALPHA_ENABLE		(0x00020000)
-
-#define PSB_2D_PAT_CLRMASK		(0xFFFEFFFF)
-#define PSB_2D_PAT_MASK			(0x00010000)
-#define PSB_2D_USE_PAT			(0x00010000)
-#define PSB_2D_USE_FILL			(0x00000000)
-/*
- * Tungsten Graphics note on rop codes: If rop A and rop B are
- * identical, the mask surface will not be read and need not be
- * set up.
- */
-
-#define PSB_2D_ROP3B_MASK		(0x0000FF00)
-#define PSB_2D_ROP3B_CLRMASK		(0xFFFF00FF)
-#define PSB_2D_ROP3B_SHIFT		(8)
-/* rop code A */
-#define PSB_2D_ROP3A_MASK		(0x000000FF)
-#define PSB_2D_ROP3A_CLRMASK		(0xFFFFFF00)
-#define PSB_2D_ROP3A_SHIFT		(0)
-
-#define PSB_2D_ROP4_MASK		(0x0000FFFF)
-/*
- *	DWORD0:	(Only pass if Pattern control == Use Fill Colour)
- *	Fill Colour RGBA8888
- */
-#define PSB_2D_FILLCOLOUR_MASK		(0xFFFFFFFF)
-#define PSB_2D_FILLCOLOUR_SHIFT		(0)
-/*
- *	DWORD1: (Always Present)
- *	X Start (Dest)
- *	Y Start (Dest)
- */
-#define PSB_2D_DST_XSTART_MASK		(0x00FFF000)
-#define PSB_2D_DST_XSTART_CLRMASK	(0xFF000FFF)
-#define PSB_2D_DST_XSTART_SHIFT		(12)
-#define PSB_2D_DST_YSTART_MASK		(0x00000FFF)
-#define PSB_2D_DST_YSTART_CLRMASK	(0xFFFFF000)
-#define PSB_2D_DST_YSTART_SHIFT		(0)
-/*
- *	DWORD2: (Always Present)
- *	X Size (Dest)
- *	Y Size (Dest)
- */
-#define PSB_2D_DST_XSIZE_MASK		(0x00FFF000)
-#define PSB_2D_DST_XSIZE_CLRMASK	(0xFF000FFF)
-#define PSB_2D_DST_XSIZE_SHIFT		(12)
-#define PSB_2D_DST_YSIZE_MASK		(0x00000FFF)
-#define PSB_2D_DST_YSIZE_CLRMASK	(0xFFFFF000)
-#define PSB_2D_DST_YSIZE_SHIFT		(0)
-
-/*
- * Source Surface (PSB_2D_SRC_SURF_BH)
- */
-/*
- * WORD 0
- */
-
-#define PSB_2D_SRC_FORMAT_MASK		(0x00078000)
-#define PSB_2D_SRC_1_PAL		(0x00000000)
-#define PSB_2D_SRC_2_PAL		(0x00008000)
-#define PSB_2D_SRC_4_PAL		(0x00010000)
-#define PSB_2D_SRC_8_PAL		(0x00018000)
-#define PSB_2D_SRC_8_ALPHA		(0x00020000)
-#define PSB_2D_SRC_4_ALPHA		(0x00028000)
-#define PSB_2D_SRC_332RGB		(0x00030000)
-#define PSB_2D_SRC_4444ARGB		(0x00038000)
-#define PSB_2D_SRC_555RGB		(0x00040000)
-#define PSB_2D_SRC_1555ARGB		(0x00048000)
-#define PSB_2D_SRC_565RGB		(0x00050000)
-#define PSB_2D_SRC_0888ARGB		(0x00058000)
-#define PSB_2D_SRC_8888ARGB		(0x00060000)
-#define PSB_2D_SRC_8888UYVY		(0x00068000)
-#define PSB_2D_SRC_RESERVED		(0x00070000)
-#define PSB_2D_SRC_1555ARGB_LOOKUP	(0x00078000)
-
-
-#define PSB_2D_SRC_STRIDE_MASK		(0x00007FFF)
-#define PSB_2D_SRC_STRIDE_CLRMASK	(0xFFFF8000)
-#define PSB_2D_SRC_STRIDE_SHIFT		(0)
-/*
- *  WORD 1 - Base Address
- */
-#define PSB_2D_SRC_ADDR_MASK		(0x0FFFFFFC)
-#define PSB_2D_SRC_ADDR_CLRMASK		(0x00000003)
-#define PSB_2D_SRC_ADDR_SHIFT		(2)
-#define PSB_2D_SRC_ADDR_ALIGNSHIFT	(2)
-
-/*
- * Pattern Surface (PSB_2D_PAT_SURF_BH)
- */
-/*
- *  WORD 0
- */
-
-#define PSB_2D_PAT_FORMAT_MASK		(0x00078000)
-#define PSB_2D_PAT_1_PAL		(0x00000000)
-#define PSB_2D_PAT_2_PAL		(0x00008000)
-#define PSB_2D_PAT_4_PAL		(0x00010000)
-#define PSB_2D_PAT_8_PAL		(0x00018000)
-#define PSB_2D_PAT_8_ALPHA		(0x00020000)
-#define PSB_2D_PAT_4_ALPHA		(0x00028000)
-#define PSB_2D_PAT_332RGB		(0x00030000)
-#define PSB_2D_PAT_4444ARGB		(0x00038000)
-#define PSB_2D_PAT_555RGB		(0x00040000)
-#define PSB_2D_PAT_1555ARGB		(0x00048000)
-#define PSB_2D_PAT_565RGB		(0x00050000)
-#define PSB_2D_PAT_0888ARGB		(0x00058000)
-#define PSB_2D_PAT_8888ARGB		(0x00060000)
-
-#define PSB_2D_PAT_STRIDE_MASK		(0x00007FFF)
-#define PSB_2D_PAT_STRIDE_CLRMASK	(0xFFFF8000)
-#define PSB_2D_PAT_STRIDE_SHIFT		(0)
-/*
- *  WORD 1 - Base Address
- */
-#define PSB_2D_PAT_ADDR_MASK		(0x0FFFFFFC)
-#define PSB_2D_PAT_ADDR_CLRMASK		(0x00000003)
-#define PSB_2D_PAT_ADDR_SHIFT		(2)
-#define PSB_2D_PAT_ADDR_ALIGNSHIFT	(2)
-
-/*
- * Destination Surface (PSB_2D_DST_SURF_BH)
- */
-/*
- * WORD 0
- */
-
-#define PSB_2D_DST_FORMAT_MASK		(0x00078000)
-#define PSB_2D_DST_332RGB		(0x00030000)
-#define PSB_2D_DST_4444ARGB		(0x00038000)
-#define PSB_2D_DST_555RGB		(0x00040000)
-#define PSB_2D_DST_1555ARGB		(0x00048000)
-#define PSB_2D_DST_565RGB		(0x00050000)
-#define PSB_2D_DST_0888ARGB		(0x00058000)
-#define PSB_2D_DST_8888ARGB		(0x00060000)
-#define PSB_2D_DST_8888AYUV		(0x00070000)
-
-#define PSB_2D_DST_STRIDE_MASK		(0x00007FFF)
-#define PSB_2D_DST_STRIDE_CLRMASK	(0xFFFF8000)
-#define PSB_2D_DST_STRIDE_SHIFT		(0)
-/*
- * WORD 1 - Base Address
- */
-#define PSB_2D_DST_ADDR_MASK		(0x0FFFFFFC)
-#define PSB_2D_DST_ADDR_CLRMASK		(0x00000003)
-#define PSB_2D_DST_ADDR_SHIFT		(2)
-#define PSB_2D_DST_ADDR_ALIGNSHIFT	(2)
-
-/*
- * Mask Surface (PSB_2D_MASK_SURF_BH)
- */
-/*
- * WORD 0
- */
-#define PSB_2D_MASK_STRIDE_MASK		(0x00007FFF)
-#define PSB_2D_MASK_STRIDE_CLRMASK	(0xFFFF8000)
-#define PSB_2D_MASK_STRIDE_SHIFT	(0)
-/*
- *  WORD 1 - Base Address
- */
-#define PSB_2D_MASK_ADDR_MASK		(0x0FFFFFFC)
-#define PSB_2D_MASK_ADDR_CLRMASK	(0x00000003)
-#define PSB_2D_MASK_ADDR_SHIFT		(2)
-#define PSB_2D_MASK_ADDR_ALIGNSHIFT	(2)
-
-/*
- * Source Palette (PSB_2D_SRC_PAL_BH)
- */
-
-#define PSB_2D_SRCPAL_ADDR_SHIFT	(0)
-#define PSB_2D_SRCPAL_ADDR_CLRMASK	(0xF0000007)
-#define PSB_2D_SRCPAL_ADDR_MASK		(0x0FFFFFF8)
-#define PSB_2D_SRCPAL_BYTEALIGN		(1024)
-
-/*
- * Pattern Palette (PSB_2D_PAT_PAL_BH)
- */
-
-#define PSB_2D_PATPAL_ADDR_SHIFT	(0)
-#define PSB_2D_PATPAL_ADDR_CLRMASK	(0xF0000007)
-#define PSB_2D_PATPAL_ADDR_MASK		(0x0FFFFFF8)
-#define PSB_2D_PATPAL_BYTEALIGN		(1024)
-
-/*
- * Rop3 Codes (2 LS bytes)
- */
-
-#define PSB_2D_ROP3_SRCCOPY		(0xCCCC)
-#define PSB_2D_ROP3_PATCOPY		(0xF0F0)
-#define PSB_2D_ROP3_WHITENESS		(0xFFFF)
-#define PSB_2D_ROP3_BLACKNESS		(0x0000)
-#define PSB_2D_ROP3_SRC			(0xCC)
-#define PSB_2D_ROP3_PAT			(0xF0)
-#define PSB_2D_ROP3_DST			(0xAA)
-
-/*
- * Sizes.
- */
-
-#define PSB_SCENE_HW_COOKIE_SIZE	16
-#define PSB_TA_MEM_HW_COOKIE_SIZE	16
-
-/*
- * Scene stuff.
- */
-
-#define PSB_NUM_HW_SCENES		2
-
-/*
- * Scheduler completion actions.
- */
-
-#define PSB_RASTER_BLOCK		0
-#define PSB_RASTER			1
-#define PSB_RETURN			2
-#define PSB_TA				3
-
-/* Power management */
-#define PSB_PUNIT_PORT			0x04
-#define PSB_OSPMBA			0x78
-#define PSB_APMBA			0x7a
-#define PSB_APM_CMD			0x0
-#define PSB_APM_STS			0x04
-#define PSB_PWRGT_VID_ENC_MASK		0x30
-#define PSB_PWRGT_VID_DEC_MASK		0xc
-#define PSB_PWRGT_GL3_MASK		0xc0
-
-#define PSB_PM_SSC			0x20
-#define PSB_PM_SSS			0x30
-#define PSB_PWRGT_DISPLAY_MASK		0xc /*on a different BA than video/gfx*/
-#define MDFLD_PWRGT_DISPLAY_A_CNTR	0x0000000c
-#define MDFLD_PWRGT_DISPLAY_B_CNTR	0x0000c000
-#define MDFLD_PWRGT_DISPLAY_C_CNTR	0x00030000
-#define MDFLD_PWRGT_DISP_MIPI_CNTR	0x000c0000
-#define MDFLD_PWRGT_DISPLAY_CNTR    (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR) /* 0x000fc00c */
-/* Display SSS register bits are different in A0 vs. B0 */
-#define PSB_PWRGT_GFX_MASK		0x3
-#define MDFLD_PWRGT_DISPLAY_A_STS	0x000000c0
-#define MDFLD_PWRGT_DISPLAY_B_STS	0x00000300
-#define MDFLD_PWRGT_DISPLAY_C_STS	0x00000c00
-#define PSB_PWRGT_GFX_MASK_B0		0xc3
-#define MDFLD_PWRGT_DISPLAY_A_STS_B0	0x0000000c
-#define MDFLD_PWRGT_DISPLAY_B_STS_B0	0x0000c000
-#define MDFLD_PWRGT_DISPLAY_C_STS_B0	0x00030000
-#define MDFLD_PWRGT_DISP_MIPI_STS	0x000c0000
-#define MDFLD_PWRGT_DISPLAY_STS_A0    (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */
-#define MDFLD_PWRGT_DISPLAY_STS_B0    (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */
-#endif
diff --git a/drivers/staging/omapdrm/Makefile b/drivers/staging/omapdrm/Makefile
index 592cf69..d9cdc12 100644
--- a/drivers/staging/omapdrm/Makefile
+++ b/drivers/staging/omapdrm/Makefile
@@ -7,6 +7,7 @@
 omapdrm-y := omap_drv.o \
 	omap_debugfs.o \
 	omap_crtc.o \
+	omap_plane.o \
 	omap_encoder.o \
 	omap_connector.o \
 	omap_fb.o \
diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c
index cffdf5e..17ca163 100644
--- a/drivers/staging/omapdrm/omap_crtc.c
+++ b/drivers/staging/omapdrm/omap_crtc.c
@@ -27,196 +27,95 @@
 
 struct omap_crtc {
 	struct drm_crtc base;
-	struct omap_overlay *ovl;
-	struct omap_overlay_info info;
+	struct drm_plane *plane;
+	const char *name;
 	int id;
 
-	/* if there is a pending flip, this will be non-null: */
+	/* if there is a pending flip, these will be non-null: */
 	struct drm_pending_vblank_event *event;
+	struct drm_framebuffer *old_fb;
 };
 
-/* push changes down to dss2 */
-static int commit(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	struct omap_overlay *ovl = omap_crtc->ovl;
-	struct omap_overlay_info *info = &omap_crtc->info;
-	int ret;
-
-	DBG("%s", omap_crtc->ovl->name);
-	DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width,
-			info->out_height, info->screen_width);
-	DBG("%d,%d %08x", info->pos_x, info->pos_y, info->paddr);
-
-	/* NOTE: do we want to do this at all here, or just wait
-	 * for dpms(ON) since other CRTC's may not have their mode
-	 * set yet, so fb dimensions may still change..
-	 */
-	ret = ovl->set_overlay_info(ovl, info);
-	if (ret) {
-		dev_err(dev->dev, "could not set overlay info\n");
-		return ret;
-	}
-
-	/* our encoder doesn't necessarily get a commit() after this, in
-	 * particular in the dpms() and mode_set_base() cases, so force the
-	 * manager to update:
-	 *
-	 * could this be in the encoder somehow?
-	 */
-	if (ovl->manager) {
-		ret = ovl->manager->apply(ovl->manager);
-		if (ret) {
-			dev_err(dev->dev, "could not apply settings\n");
-			return ret;
-		}
-	}
-
-	if (info->enabled) {
-		omap_framebuffer_flush(crtc->fb, crtc->x, crtc->y,
-				crtc->fb->width, crtc->fb->height);
-	}
-
-	return 0;
-}
-
-/* update parameters that are dependent on the framebuffer dimensions and
- * position within the fb that this crtc scans out from. This is called
- * when framebuffer dimensions or x,y base may have changed, either due
- * to our mode, or a change in another crtc that is scanning out of the
- * same fb.
- */
-static void update_scanout(struct drm_crtc *crtc)
-{
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	dma_addr_t paddr;
-	unsigned int screen_width;
-
-	omap_framebuffer_get_buffer(crtc->fb, crtc->x, crtc->y,
-			NULL, &paddr, &screen_width);
-
-	DBG("%s: %d,%d: %08x (%d)", omap_crtc->ovl->name,
-			crtc->x, crtc->y, (u32)paddr, screen_width);
-
-	omap_crtc->info.paddr = paddr;
-	omap_crtc->info.screen_width = screen_width;
-}
-
 static void omap_crtc_gamma_set(struct drm_crtc *crtc,
 		u16 *red, u16 *green, u16 *blue, uint32_t start, uint32_t size)
 {
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	DBG("%s", omap_crtc->ovl->name);
+	/* not supported.. at least not yet */
 }
 
 static void omap_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	DBG("%s", omap_crtc->ovl->name);
+	omap_crtc->plane->funcs->destroy(omap_crtc->plane);
 	drm_crtc_cleanup(crtc);
 	kfree(omap_crtc);
 }
 
 static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
+	struct omap_drm_private *priv = crtc->dev->dev_private;
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	int i;
 
-	DBG("%s: %d", omap_crtc->ovl->name, mode);
+	WARN_ON(omap_plane_dpms(omap_crtc->plane, mode));
 
-	if (mode == DRM_MODE_DPMS_ON) {
-		update_scanout(crtc);
-		omap_crtc->info.enabled = true;
-	} else {
-		omap_crtc->info.enabled = false;
+	for (i = 0; i < priv->num_planes; i++) {
+		struct drm_plane *plane = priv->planes[i];
+		if (plane->crtc == crtc)
+			WARN_ON(omap_plane_dpms(plane, mode));
 	}
-
-	WARN_ON(commit(crtc));
 }
 
 static bool omap_crtc_mode_fixup(struct drm_crtc *crtc,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
+		struct drm_display_mode *mode,
+		struct drm_display_mode *adjusted_mode)
 {
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	DBG("%s", omap_crtc->ovl->name);
 	return true;
 }
 
 static int omap_crtc_mode_set(struct drm_crtc *crtc,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode,
-			       int x, int y,
-			       struct drm_framebuffer *old_fb)
+		struct drm_display_mode *mode,
+		struct drm_display_mode *adjusted_mode,
+		int x, int y,
+		struct drm_framebuffer *old_fb)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	struct drm_plane *plane = omap_crtc->plane;
 
-	DBG("%s: %d,%d: %dx%d", omap_crtc->ovl->name, x, y,
-			mode->hdisplay, mode->vdisplay);
-
-	/* just use adjusted mode */
-	mode = adjusted_mode;
-
-	omap_crtc->info.width = mode->hdisplay;
-	omap_crtc->info.height = mode->vdisplay;
-	omap_crtc->info.out_width = mode->hdisplay;
-	omap_crtc->info.out_height = mode->vdisplay;
-	omap_crtc->info.color_mode = OMAP_DSS_COLOR_RGB24U;
-	omap_crtc->info.rotation_type = OMAP_DSS_ROT_DMA;
-	omap_crtc->info.rotation = OMAP_DSS_ROT_0;
-	omap_crtc->info.global_alpha = 0xff;
-	omap_crtc->info.mirror = 0;
-	omap_crtc->info.mirror = 0;
-	omap_crtc->info.pos_x = 0;
-	omap_crtc->info.pos_y = 0;
-#if 0 /* re-enable when these are available in DSS2 driver */
-	omap_crtc->info.zorder = 3;        /* GUI in the front, video behind */
-	omap_crtc->info.min_x_decim = 1;
-	omap_crtc->info.max_x_decim = 1;
-	omap_crtc->info.min_y_decim = 1;
-	omap_crtc->info.max_y_decim = 1;
-#endif
-
-	update_scanout(crtc);
-
-	return 0;
+	return omap_plane_mode_set(plane, crtc, crtc->fb,
+			0, 0, mode->hdisplay, mode->vdisplay,
+			x << 16, y << 16,
+			mode->hdisplay << 16, mode->vdisplay << 16);
 }
 
 static void omap_crtc_prepare(struct drm_crtc *crtc)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	struct omap_overlay *ovl = omap_crtc->ovl;
-
-	DBG("%s", omap_crtc->ovl->name);
-
-	ovl->get_overlay_info(ovl, &omap_crtc->info);
-
+	DBG("%s", omap_crtc->name);
 	omap_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
 
 static void omap_crtc_commit(struct drm_crtc *crtc)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	DBG("%s", omap_crtc->ovl->name);
+	DBG("%s", omap_crtc->name);
 	omap_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
 }
 
 static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-		    struct drm_framebuffer *old_fb)
+		struct drm_framebuffer *old_fb)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	struct drm_plane *plane = omap_crtc->plane;
+	struct drm_display_mode *mode = &crtc->mode;
 
-	DBG("%s %d,%d: fb=%p", omap_crtc->ovl->name, x, y, old_fb);
-
-	update_scanout(crtc);
-
-	return commit(crtc);
+	return plane->funcs->update_plane(plane, crtc, crtc->fb,
+			0, 0, mode->hdisplay, mode->vdisplay,
+			x << 16, y << 16,
+			mode->hdisplay << 16, mode->vdisplay << 16);
 }
 
 static void omap_crtc_load_lut(struct drm_crtc *crtc)
 {
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	DBG("%s", omap_crtc->ovl->name);
 }
 
 static void page_flip_cb(void *arg)
@@ -225,15 +124,16 @@
 	struct drm_device *dev = crtc->dev;
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	struct drm_pending_vblank_event *event = omap_crtc->event;
+	struct drm_framebuffer *old_fb = omap_crtc->old_fb;
 	struct timeval now;
 	unsigned long flags;
 
 	WARN_ON(!event);
 
 	omap_crtc->event = NULL;
+	omap_crtc->old_fb = NULL;
 
-	update_scanout(crtc);
-	WARN_ON(commit(crtc));
+	omap_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb);
 
 	/* wakeup userspace */
 	/* TODO: this should happen *after* flip in vsync IRQ handler */
@@ -264,10 +164,11 @@
 		return -EINVAL;
 	}
 
-	crtc->fb = fb;
+	omap_crtc->old_fb = crtc->fb;
 	omap_crtc->event = event;
+	crtc->fb = fb;
 
-	omap_gem_op_async(omap_framebuffer_bo(fb), OMAP_GEM_READ,
+	omap_gem_op_async(omap_framebuffer_bo(fb, 0), OMAP_GEM_READ,
 			page_flip_cb, crtc);
 
 	return 0;
@@ -290,12 +191,6 @@
 	.load_lut = omap_crtc_load_lut,
 };
 
-struct omap_overlay *omap_crtc_get_overlay(struct drm_crtc *crtc)
-{
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	return omap_crtc->ovl;
-}
-
 /* initialize crtc */
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 		struct omap_overlay *ovl, int id)
@@ -310,9 +205,13 @@
 		goto fail;
 	}
 
-	omap_crtc->ovl = ovl;
-	omap_crtc->id = id;
 	crtc = &omap_crtc->base;
+
+	omap_crtc->plane = omap_plane_init(dev, ovl, (1 << id), true);
+	omap_crtc->plane->crtc = crtc;
+	omap_crtc->name = ovl->name;
+	omap_crtc->id = id;
+
 	drm_crtc_init(dev, crtc, &omap_crtc_funcs);
 	drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
 
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 602aa2d..3bbea9a 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -204,12 +204,6 @@
 	struct omap_overlay_manager *mgr = NULL;
 	struct drm_crtc *crtc;
 
-	if (ovl->manager) {
-		DBG("disconnecting %s from %s", ovl->name,
-					ovl->manager->name);
-		ovl->unset_manager(ovl);
-	}
-
 	/* find next best connector, ones with detected connection first
 	 */
 	while (*j < priv->num_connectors && !mgr) {
@@ -245,11 +239,6 @@
 		(*j)++;
 	}
 
-	if (mgr) {
-		DBG("connecting %s to %s", ovl->name, mgr->name);
-		ovl->set_manager(ovl, mgr);
-	}
-
 	crtc = omap_crtc_init(dev, ovl, priv->num_crtcs);
 
 	if (!crtc) {
@@ -265,6 +254,26 @@
 	return 0;
 }
 
+static int create_plane(struct drm_device *dev, struct omap_overlay *ovl,
+		unsigned int possible_crtcs)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	struct drm_plane *plane =
+			omap_plane_init(dev, ovl, possible_crtcs, false);
+
+	if (!plane) {
+		dev_err(dev->dev, "could not create plane: %s\n",
+				ovl->name);
+		return -ENOMEM;
+	}
+
+	BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes));
+
+	priv->planes[priv->num_planes++] = plane;
+
+	return 0;
+}
+
 static int match_dev_name(struct omap_dss_device *dssdev, void *data)
 {
 	return !strcmp(dssdev->name, data);
@@ -332,6 +341,12 @@
 				omap_dss_get_overlay(kms_pdata->ovl_ids[i]);
 			create_crtc(dev, ovl, &j, connected_connectors);
 		}
+
+		for (i = 0; i < kms_pdata->pln_cnt; i++) {
+			struct omap_overlay *ovl =
+				omap_dss_get_overlay(kms_pdata->pln_ids[i]);
+			create_plane(dev, ovl, (1 << priv->num_crtcs) - 1);
+		}
 	} else {
 		/* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try
 		 * to make educated guesses about everything else
@@ -353,6 +368,12 @@
 			create_crtc(dev, omap_dss_get_overlay(i),
 					&j, connected_connectors);
 		}
+
+		/* use any remaining overlays as drm planes */
+		for (; i < omap_dss_get_num_overlays(); i++) {
+			struct omap_overlay *ovl = omap_dss_get_overlay(i);
+			create_plane(dev, ovl, (1 << priv->num_crtcs) - 1);
+		}
 	}
 
 	/* for now keep the mapping of CRTCs and encoders static.. */
@@ -361,15 +382,7 @@
 		struct omap_overlay_manager *mgr =
 				omap_encoder_get_manager(encoder);
 
-		encoder->possible_crtcs = 0;
-
-		for (j = 0; j < priv->num_crtcs; j++) {
-			struct omap_overlay *ovl =
-					omap_crtc_get_overlay(priv->crtcs[j]);
-			if (ovl->manager == mgr) {
-				encoder->possible_crtcs |= (1 << j);
-			}
-		}
+		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
 
 		DBG("%s: possible_crtcs=%08x", mgr->name,
 					encoder->possible_crtcs);
@@ -377,8 +390,8 @@
 
 	dump_video_chains();
 
-	dev->mode_config.min_width = 256;
-	dev->mode_config.min_height = 256;
+	dev->mode_config.min_width = 32;
+	dev->mode_config.min_height = 32;
 
 	/* note: eventually will need some cpu_is_omapXYZ() type stuff here
 	 * to fill in these limits properly on different OMAP generations..
@@ -708,6 +721,18 @@
 	.close = drm_gem_vm_close,
 };
 
+static const struct file_operations omapdriver_fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.unlocked_ioctl = drm_ioctl,
+		.release = drm_release,
+		.mmap = omap_gem_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+		.read = drm_read,
+		.llseek = noop_llseek,
+};
+
 static struct drm_driver omap_drm_driver = {
 		.driver_features =
 				DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM,
@@ -738,17 +763,7 @@
 		.dumb_destroy = omap_gem_dumb_destroy,
 		.ioctls = ioctls,
 		.num_ioctls = DRM_OMAP_NUM_IOCTLS,
-		.fops = {
-				.owner = THIS_MODULE,
-				.open = drm_open,
-				.unlocked_ioctl = drm_ioctl,
-				.release = drm_release,
-				.mmap = omap_gem_mmap,
-				.poll = drm_poll,
-				.fasync = drm_fasync,
-				.read = drm_read,
-				.llseek = noop_llseek,
-		},
+		.fops = &omapdriver_fops,
 		.name = DRIVER_NAME,
 		.desc = DRIVER_DESC,
 		.date = DRIVER_DATE,
diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h
index 76c4251..61fe022 100644
--- a/drivers/staging/omapdrm/omap_drv.h
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
 #include "omap_drm.h"
 #include "omap_priv.h"
 
@@ -41,6 +42,8 @@
 struct omap_drm_private {
 	unsigned int num_crtcs;
 	struct drm_crtc *crtcs[8];
+	unsigned int num_planes;
+	struct drm_plane *planes[8];
 	unsigned int num_encoders;
 	struct drm_encoder *encoders[8];
 	unsigned int num_connectors;
@@ -61,7 +64,17 @@
 
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 		struct omap_overlay *ovl, int id);
-struct omap_overlay *omap_crtc_get_overlay(struct drm_crtc *crtc);
+
+struct drm_plane *omap_plane_init(struct drm_device *dev,
+		struct omap_overlay *ovl, unsigned int possible_crtcs,
+		bool priv);
+int omap_plane_dpms(struct drm_plane *plane, int mode);
+int omap_plane_mode_set(struct drm_plane *plane,
+		struct drm_crtc *crtc, struct drm_framebuffer *fb,
+		int crtc_x, int crtc_y,
+		unsigned int crtc_w, unsigned int crtc_h,
+		uint32_t src_x, uint32_t src_y,
+		uint32_t src_w, uint32_t src_h);
 
 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
 		struct omap_overlay_manager *mgr);
@@ -80,12 +93,14 @@
 		int x, int y, int w, int h);
 
 struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
-		struct drm_file *file, struct drm_mode_fb_cmd *mode_cmd);
+		struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd);
 struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
-		struct drm_mode_fb_cmd *mode_cmd, struct drm_gem_object *bo);
-struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb);
-int omap_framebuffer_get_buffer(struct drm_framebuffer *fb, int x, int y,
-		void **vaddr, dma_addr_t *paddr, unsigned int *screen_width);
+		struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
+struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p);
+int omap_framebuffer_pin(struct drm_framebuffer *fb);
+void omap_framebuffer_unpin(struct drm_framebuffer *fb);
+void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y,
+		struct omap_overlay_info *info);
 struct drm_connector *omap_framebuffer_get_next_connector(
 		struct drm_framebuffer *fb, struct drm_connector *from);
 void omap_framebuffer_flush(struct drm_framebuffer *fb,
@@ -132,4 +147,29 @@
 	return ALIGN(pitch, 8 * bytespp);
 }
 
+/* should these be made into common util helpers?
+ */
+
+static inline int objects_lookup(struct drm_device *dev,
+		struct drm_file *filp, uint32_t pixel_format,
+		struct drm_gem_object **bos, uint32_t *handles)
+{
+	int i, n = drm_format_num_planes(pixel_format);
+
+	for (i = 0; i < n; i++) {
+		bos[i] = drm_gem_object_lookup(dev, filp, handles[i]);
+		if (!bos[i]) {
+			goto fail;
+		}
+	}
+
+	return 0;
+
+fail:
+	while (--i > 0) {
+		drm_gem_object_unreference_unlocked(bos[i]);
+	}
+	return -ENOENT;
+}
+
 #endif /* __OMAP_DRV_H__ */
diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c
index 0b50c5b..d021a7e 100644
--- a/drivers/staging/omapdrm/omap_fb.c
+++ b/drivers/staging/omapdrm/omap_fb.c
@@ -22,18 +22,57 @@
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
 
-
 /*
  * framebuffer funcs
  */
 
+/* per-format info: */
+struct format {
+	enum omap_color_mode dss_format;
+	uint32_t pixel_format;
+	struct {
+		int stride_bpp;           /* this times width is stride */
+		int sub_y;                /* sub-sample in y dimension */
+	} planes[4];
+	bool yuv;
+};
+
+static const struct format formats[] = {
+	/* 16bpp [A]RGB: */
+	{ OMAP_DSS_COLOR_RGB16,       DRM_FORMAT_RGB565,   {{2, 1}}, false }, /* RGB16-565 */
+	{ OMAP_DSS_COLOR_RGB12U,      DRM_FORMAT_RGBX4444, {{2, 1}}, false }, /* RGB12x-4444 */
+	{ OMAP_DSS_COLOR_RGBX16,      DRM_FORMAT_XRGB4444, {{2, 1}}, false }, /* xRGB12-4444 */
+	{ OMAP_DSS_COLOR_RGBA16,      DRM_FORMAT_RGBA4444, {{2, 1}}, false }, /* RGBA12-4444 */
+	{ OMAP_DSS_COLOR_ARGB16,      DRM_FORMAT_ARGB4444, {{2, 1}}, false }, /* ARGB16-4444 */
+	{ OMAP_DSS_COLOR_XRGB16_1555, DRM_FORMAT_XRGB1555, {{2, 1}}, false }, /* xRGB15-1555 */
+	{ OMAP_DSS_COLOR_ARGB16_1555, DRM_FORMAT_ARGB1555, {{2, 1}}, false }, /* ARGB16-1555 */
+	/* 24bpp RGB: */
+	{ OMAP_DSS_COLOR_RGB24P,      DRM_FORMAT_RGB888,   {{3, 1}}, false }, /* RGB24-888 */
+	/* 32bpp [A]RGB: */
+	{ OMAP_DSS_COLOR_RGBX32,      DRM_FORMAT_RGBX8888, {{4, 1}}, false }, /* RGBx24-8888 */
+	{ OMAP_DSS_COLOR_RGB24U,      DRM_FORMAT_XRGB8888, {{4, 1}}, false }, /* xRGB24-8888 */
+	{ OMAP_DSS_COLOR_RGBA32,      DRM_FORMAT_RGBA8888, {{4, 1}}, false }, /* RGBA32-8888 */
+	{ OMAP_DSS_COLOR_ARGB32,      DRM_FORMAT_ARGB8888, {{4, 1}}, false }, /* ARGB32-8888 */
+	/* YUV: */
+	{ OMAP_DSS_COLOR_NV12,        DRM_FORMAT_NV12,     {{1, 1}, {1, 2}}, true },
+	{ OMAP_DSS_COLOR_YUV2,        DRM_FORMAT_YUYV,     {{2, 1}}, true },
+	{ OMAP_DSS_COLOR_UYVY,        DRM_FORMAT_UYVY,     {{2, 1}}, true },
+};
+
+/* per-plane info for the fb: */
+struct plane {
+	struct drm_gem_object *bo;
+	uint32_t pitch;
+	uint32_t offset;
+	dma_addr_t paddr;
+};
+
 #define to_omap_framebuffer(x) container_of(x, struct omap_framebuffer, base)
 
 struct omap_framebuffer {
 	struct drm_framebuffer base;
-	struct drm_gem_object *bo;
-	int size;
-	dma_addr_t paddr;
+	const struct format *format;
+	struct plane planes[4];
 };
 
 static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
@@ -41,22 +80,23 @@
 		unsigned int *handle)
 {
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
-    return drm_gem_handle_create(file_priv, omap_fb->bo, handle);
+	return drm_gem_handle_create(file_priv,
+			omap_fb->planes[0].bo, handle);
 }
 
 static void omap_framebuffer_destroy(struct drm_framebuffer *fb)
 {
-	struct drm_device *dev = fb->dev;
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+	int i, n = drm_format_num_planes(omap_fb->format->pixel_format);
 
 	DBG("destroy: FB ID: %d (%p)", fb->base.id, fb);
 
 	drm_framebuffer_cleanup(fb);
 
-	if (omap_fb->bo) {
-		if (omap_fb->paddr && omap_gem_put_paddr(omap_fb->bo))
-			dev_err(dev->dev, "could not unmap!\n");
-		drm_gem_object_unreference_unlocked(omap_fb->bo);
+	for (i = 0; i < n; i++) {
+		struct plane *plane = &omap_fb->planes[i];
+		if (plane->bo)
+			drm_gem_object_unreference_unlocked(plane->bo);
 	}
 
 	kfree(omap_fb);
@@ -83,37 +123,76 @@
 	.dirty = omap_framebuffer_dirty,
 };
 
-/* returns the buffer size */
-int omap_framebuffer_get_buffer(struct drm_framebuffer *fb, int x, int y,
-		void **vaddr, dma_addr_t *paddr, unsigned int *screen_width)
+/* pins buffer in preparation for scanout */
+int omap_framebuffer_pin(struct drm_framebuffer *fb)
 {
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
-	int bpp = fb->bits_per_pixel / 8;
-	unsigned long offset;
+	int ret, i, n = drm_format_num_planes(omap_fb->format->pixel_format);
 
-	offset = (x * bpp) + (y * fb->pitch);
-
-	if (vaddr) {
-		void *bo_vaddr = omap_gem_vaddr(omap_fb->bo);
-		/* note: we can only count on having a vaddr for buffers that
-		 * are allocated physically contiguously to begin with (ie.
-		 * dma_alloc_coherent()).  But this should be ok because it
-		 * is only used by legacy fbdev
-		 */
-		BUG_ON(IS_ERR_OR_NULL(bo_vaddr));
-		*vaddr = bo_vaddr + offset;
+	for (i = 0; i < n; i++) {
+		struct plane *plane = &omap_fb->planes[i];
+		ret = omap_gem_get_paddr(plane->bo, &plane->paddr, true);
+		if (ret)
+			goto fail;
 	}
 
-	*paddr = omap_fb->paddr + offset;
-	*screen_width = fb->pitch / bpp;
+	return 0;
 
-	return omap_fb->size - offset;
+fail:
+	while (--i > 0) {
+		struct plane *plane = &omap_fb->planes[i];
+		omap_gem_put_paddr(plane->bo);
+	}
+	return ret;
 }
 
-struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb)
+/* releases buffer when done with scanout */
+void omap_framebuffer_unpin(struct drm_framebuffer *fb)
 {
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
-	return omap_fb->bo;
+	int i, n = drm_format_num_planes(omap_fb->format->pixel_format);
+
+	for (i = 0; i < n; i++) {
+		struct plane *plane = &omap_fb->planes[i];
+		omap_gem_put_paddr(plane->bo);
+	}
+}
+
+/* update ovl info for scanout, handles cases of multi-planar fb's, etc.
+ */
+void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y,
+		struct omap_overlay_info *info)
+{
+	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+	const struct format *format = omap_fb->format;
+	struct plane *plane = &omap_fb->planes[0];
+	unsigned int offset;
+
+	offset = plane->offset +
+			(x * format->planes[0].stride_bpp) +
+			(y * plane->pitch / format->planes[0].sub_y);
+
+	info->color_mode   = format->dss_format;
+	info->paddr        = plane->paddr + offset;
+	info->screen_width = plane->pitch / format->planes[0].stride_bpp;
+
+	if (format->dss_format == OMAP_DSS_COLOR_NV12) {
+		plane = &omap_fb->planes[1];
+		offset = plane->offset +
+				(x * format->planes[1].stride_bpp) +
+				(y * plane->pitch / format->planes[1].sub_y);
+		info->p_uv_addr = plane->paddr + offset;
+	} else {
+		info->p_uv_addr = 0;
+	}
+}
+
+struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p)
+{
+	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+	if (p >= drm_format_num_planes(omap_fb->format->pixel_format))
+		return NULL;
+	return omap_fb->planes[p].bo;
 }
 
 /* iterate thru all the connectors, returning ones that are attached
@@ -171,39 +250,57 @@
 }
 
 struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
-		struct drm_file *file, struct drm_mode_fb_cmd *mode_cmd)
+		struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	struct drm_gem_object *bo;
+	struct drm_gem_object *bos[4];
 	struct drm_framebuffer *fb;
-	bo = drm_gem_object_lookup(dev, file, mode_cmd->handle);
-	if (!bo) {
-		return ERR_PTR(-ENOENT);
-	}
-	fb = omap_framebuffer_init(dev, mode_cmd, bo);
-	if (!fb) {
-		return ERR_PTR(-ENOMEM);
+	int ret;
+
+	ret = objects_lookup(dev, file, mode_cmd->pixel_format,
+			bos, mode_cmd->handles);
+	if (ret)
+		return ERR_PTR(ret);
+
+	fb = omap_framebuffer_init(dev, mode_cmd, bos);
+	if (IS_ERR(fb)) {
+		int i, n = drm_format_num_planes(mode_cmd->pixel_format);
+		for (i = 0; i < n; i++)
+			drm_gem_object_unreference_unlocked(bos[i]);
+		return fb;
 	}
 	return fb;
 }
 
 struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
-		struct drm_mode_fb_cmd *mode_cmd, struct drm_gem_object *bo)
+		struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
 {
 	struct omap_framebuffer *omap_fb;
 	struct drm_framebuffer *fb = NULL;
-	int size, ret;
+	const struct format *format = NULL;
+	int ret, i, n = drm_format_num_planes(mode_cmd->pixel_format);
 
-	DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%d)",
+	DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
 			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
-			mode_cmd->bpp);
+			(char *)&mode_cmd->pixel_format);
 
-	/* in case someone tries to feed us a completely bogus stride: */
-	mode_cmd->pitch = align_pitch(mode_cmd->pitch,
-			mode_cmd->width, mode_cmd->bpp);
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		if (formats[i].pixel_format == mode_cmd->pixel_format) {
+			format = &formats[i];
+			break;
+		}
+	}
+
+	if (!format) {
+		dev_err(dev->dev, "unsupported pixel format: %4.4s\n",
+				(char *)&mode_cmd->pixel_format);
+		ret = -EINVAL;
+		goto fail;
+	}
 
 	omap_fb = kzalloc(sizeof(*omap_fb), GFP_KERNEL);
 	if (!omap_fb) {
 		dev_err(dev->dev, "could not allocate fb\n");
+		ret = -ENOMEM;
 		goto fail;
 	}
 
@@ -216,19 +313,32 @@
 
 	DBG("create: FB ID: %d (%p)", fb->base.id, fb);
 
-	size = PAGE_ALIGN(mode_cmd->pitch * mode_cmd->height);
+	omap_fb->format = format;
 
-	if (size > bo->size) {
-		dev_err(dev->dev, "provided buffer object is too small!\n");
-		goto fail;
-	}
+	for (i = 0; i < n; i++) {
+		struct plane *plane = &omap_fb->planes[i];
+		int size, pitch = mode_cmd->pitches[i];
 
-	omap_fb->bo = bo;
-	omap_fb->size = size;
+		if (pitch < (mode_cmd->width * format->planes[i].stride_bpp)) {
+			dev_err(dev->dev, "provided buffer pitch is too small! %d < %d\n",
+					pitch, mode_cmd->width * format->planes[i].stride_bpp);
+			ret = -EINVAL;
+			goto fail;
+		}
 
-	if (omap_gem_get_paddr(bo, &omap_fb->paddr, true)) {
-		dev_err(dev->dev, "could not map (paddr)!\n");
-		goto fail;
+		size = pitch * mode_cmd->height / format->planes[i].sub_y;
+
+		if (size > (bos[i]->size - mode_cmd->offsets[i])) {
+			dev_err(dev->dev, "provided buffer object is too small! %d < %d\n",
+					bos[i]->size - mode_cmd->offsets[i], size);
+			ret = -EINVAL;
+			goto fail;
+		}
+
+		plane->bo     = bos[i];
+		plane->offset = mode_cmd->offsets[i];
+		plane->pitch  = mode_cmd->pitches[i];
+		plane->paddr  = pitch;
 	}
 
 	drm_helper_mode_fill_fb_struct(fb, mode_cmd);
@@ -239,5 +349,5 @@
 	if (fb) {
 		omap_framebuffer_destroy(fb);
 	}
-	return NULL;
+	return ERR_PTR(ret);
 }
diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c
index 093ae2f..96940bb 100644
--- a/drivers/staging/omapdrm/omap_fbdev.c
+++ b/drivers/staging/omapdrm/omap_fbdev.c
@@ -129,10 +129,8 @@
 	struct drm_framebuffer *fb = NULL;
 	union omap_gem_size gsize;
 	struct fb_info *fbi = NULL;
-	struct drm_mode_fb_cmd mode_cmd = {0};
+	struct drm_mode_fb_cmd2 mode_cmd = {0};
 	dma_addr_t paddr;
-	void __iomem *vaddr;
-	int size, screen_width;
 	int ret;
 
 	/* only doing ARGB32 since this is what is needed to alpha-blend
@@ -145,36 +143,56 @@
 			sizes->surface_height, sizes->surface_bpp,
 			sizes->fb_width, sizes->fb_height);
 
+	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+			sizes->surface_depth);
+
 	mode_cmd.width = sizes->surface_width;
 	mode_cmd.height = sizes->surface_height;
 
-	mode_cmd.bpp = sizes->surface_bpp;
-	mode_cmd.depth = sizes->surface_depth;
-
-	mode_cmd.pitch = align_pitch(
-			mode_cmd.width * ((mode_cmd.bpp + 7) / 8),
-			mode_cmd.width, mode_cmd.bpp);
+	mode_cmd.pitches[0] = align_pitch(
+			mode_cmd.width * ((sizes->surface_bpp + 7) / 8),
+			mode_cmd.width, sizes->surface_bpp);
 
 	fbdev->ywrap_enabled = priv->has_dmm && ywrap_enabled;
 	if (fbdev->ywrap_enabled) {
 		/* need to align pitch to page size if using DMM scrolling */
-		mode_cmd.pitch = ALIGN(mode_cmd.pitch, PAGE_SIZE);
+		mode_cmd.pitches[0] = ALIGN(mode_cmd.pitches[0], PAGE_SIZE);
 	}
 
 	/* allocate backing bo */
 	gsize = (union omap_gem_size){
-		.bytes = PAGE_ALIGN(mode_cmd.pitch * mode_cmd.height),
+		.bytes = PAGE_ALIGN(mode_cmd.pitches[0] * mode_cmd.height),
 	};
 	DBG("allocating %d bytes for fb %d", gsize.bytes, dev->primary->index);
 	fbdev->bo = omap_gem_new(dev, gsize, OMAP_BO_SCANOUT | OMAP_BO_WC);
 	if (!fbdev->bo) {
 		dev_err(dev->dev, "failed to allocate buffer object\n");
+		ret = -ENOMEM;
 		goto fail;
 	}
 
-	fb = omap_framebuffer_init(dev, &mode_cmd, fbdev->bo);
-	if (!fb) {
+	fb = omap_framebuffer_init(dev, &mode_cmd, &fbdev->bo);
+	if (IS_ERR(fb)) {
 		dev_err(dev->dev, "failed to allocate fb\n");
+		/* note: if fb creation failed, we can't rely on fb destroy
+		 * to unref the bo:
+		 */
+		drm_gem_object_unreference(fbdev->bo);
+		ret = PTR_ERR(fb);
+		goto fail;
+	}
+
+	/* note: this keeps the bo pinned.. which is perhaps not ideal,
+	 * but is needed as long as we use fb_mmap() to mmap to userspace
+	 * (since this happens using fix.smem_start).  Possibly we could
+	 * implement our own mmap using GEM mmap support to avoid this
+	 * (non-tiled buffer doesn't need to be pinned for fbcon to write
+	 * to it).  Then we just need to be sure that we are able to re-
+	 * pin it in case of an opps.
+	 */
+	ret = omap_gem_get_paddr(fbdev->bo, &paddr, true);
+	if (ret) {
+		dev_err(dev->dev, "could not map (paddr)!\n");
 		ret = -ENOMEM;
 		goto fail;
 	}
@@ -206,18 +224,15 @@
 		goto fail_unlock;
 	}
 
-	drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth);
+	drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
 	drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
 
-	size = omap_framebuffer_get_buffer(fb, 0, 0,
-			&vaddr, &paddr, &screen_width);
-
 	dev->mode_config.fb_base = paddr;
 
-	fbi->screen_base = vaddr;
-	fbi->screen_size = size;
+	fbi->screen_base = omap_gem_vaddr(fbdev->bo);
+	fbi->screen_size = fbdev->bo->size;
 	fbi->fix.smem_start = paddr;
-	fbi->fix.smem_len = size;
+	fbi->fix.smem_len = fbdev->bo->size;
 
 	/* if we have DMM, then we can use it for scrolling by just
 	 * shuffling pages around in DMM rather than doing sw blit.
@@ -362,11 +377,11 @@
 
 	fbdev = to_omap_fbdev(priv->fbdev);
 
-	kfree(fbdev);
-
 	/* this will free the backing object */
 	if (fbdev->fb)
 		fbdev->fb->funcs->destroy(fbdev->fb);
 
+	kfree(fbdev);
+
 	priv->fbdev = NULL;
 }
diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c
index e0ebd1d..b7d6f88 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -116,6 +116,9 @@
 	} *sync;
 };
 
+static int get_pages(struct drm_gem_object *obj, struct page ***pages);
+static uint64_t mmap_offset(struct drm_gem_object *obj);
+
 /* To deal with userspace mmap'ings of 2d tiled buffers, which (a) are
  * not necessarily pinned in TILER all the time, and (b) when they are
  * they are not necessarily page aligned, we reserve one or more small
@@ -149,7 +152,7 @@
 {
 	if (obj->dev->dev_mapping) {
 		size_t size = PAGE_SIZE * usergart[fmt].height;
-		loff_t off = omap_gem_mmap_offset(obj) +
+		loff_t off = mmap_offset(obj) +
 				(entry->obj_pgoff << PAGE_SHIFT);
 		unmap_mapping_range(obj->dev->dev_mapping, off, size, 1);
 	}
@@ -189,8 +192,6 @@
 	return obj->filp != NULL;
 }
 
-static int get_pages(struct drm_gem_object *obj, struct page ***pages);
-
 static DEFINE_SPINLOCK(sync_lock);
 
 /** ensure backing pages are allocated */
@@ -251,7 +252,7 @@
 }
 
 /** get mmap offset */
-uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
+static uint64_t mmap_offset(struct drm_gem_object *obj)
 {
 	if (!obj->map_list.map) {
 		/* Make it mmapable */
@@ -267,6 +268,15 @@
 	return (uint64_t)obj->map_list.hash.key << PAGE_SHIFT;
 }
 
+uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
+{
+	uint64_t offset;
+	mutex_lock(&obj->dev->struct_mutex);
+	offset = mmap_offset(obj);
+	mutex_unlock(&obj->dev->struct_mutex);
+	return offset;
+}
+
 /** get mmap size */
 size_t omap_gem_mmap_size(struct drm_gem_object *obj)
 {
@@ -1034,6 +1044,11 @@
 		drm_gem_free_mmap_offset(obj);
 	}
 
+	/* this means the object is still pinned.. which really should
+	 * not happen.  I think..
+	 */
+	WARN_ON(omap_obj->paddr_cnt > 0);
+
 	/* don't free externally allocated backing memory */
 	if (!(omap_obj->flags & OMAP_BO_EXT_MEM)) {
 		if (omap_obj->pages) {
diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c
new file mode 100644
index 0000000..9790912
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_plane.c
@@ -0,0 +1,344 @@
+/*
+ * drivers/staging/omapdrm/omap_plane.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob.clark@linaro.org>
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+
+/* some hackery because omapdss has an 'enum omap_plane' (which would be
+ * better named omap_plane_id).. and compiler seems unhappy about having
+ * both a 'struct omap_plane' and 'enum omap_plane'
+ */
+#define omap_plane _omap_plane
+
+/*
+ * plane funcs
+ */
+
+#define to_omap_plane(x) container_of(x, struct omap_plane, base)
+
+struct omap_plane {
+	struct drm_plane base;
+	struct omap_overlay *ovl;
+	struct omap_overlay_info info;
+
+	/* Source values, converted to integers because we don't support
+	 * fractional positions:
+	 */
+	unsigned int src_x, src_y;
+
+	/* last fb that we pinned: */
+	struct drm_framebuffer *pinned_fb;
+};
+
+
+/* push changes down to dss2 */
+static int commit(struct drm_plane *plane)
+{
+	struct drm_device *dev = plane->dev;
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+	struct omap_overlay *ovl = omap_plane->ovl;
+	struct omap_overlay_info *info = &omap_plane->info;
+	int ret;
+
+	DBG("%s", ovl->name);
+	DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width,
+			info->out_height, info->screen_width);
+	DBG("%d,%d %08x %08x", info->pos_x, info->pos_y,
+			info->paddr, info->p_uv_addr);
+
+	/* NOTE: do we want to do this at all here, or just wait
+	 * for dpms(ON) since other CRTC's may not have their mode
+	 * set yet, so fb dimensions may still change..
+	 */
+	ret = ovl->set_overlay_info(ovl, info);
+	if (ret) {
+		dev_err(dev->dev, "could not set overlay info\n");
+		return ret;
+	}
+
+	/* our encoder doesn't necessarily get a commit() after this, in
+	 * particular in the dpms() and mode_set_base() cases, so force the
+	 * manager to update:
+	 *
+	 * could this be in the encoder somehow?
+	 */
+	if (ovl->manager) {
+		ret = ovl->manager->apply(ovl->manager);
+		if (ret) {
+			dev_err(dev->dev, "could not apply settings\n");
+			return ret;
+		}
+	}
+
+	if (ovl->is_enabled(ovl)) {
+		omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y,
+				info->out_width, info->out_height);
+	}
+
+	return 0;
+}
+
+/* when CRTC that we are attached to has potentially changed, this checks
+ * if we are attached to proper manager, and if necessary updates.
+ */
+static void update_manager(struct drm_plane *plane)
+{
+	struct omap_drm_private *priv = plane->dev->dev_private;
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+	struct omap_overlay *ovl = omap_plane->ovl;
+	struct omap_overlay_manager *mgr = NULL;
+	int i;
+
+	if (plane->crtc) {
+		for (i = 0; i < priv->num_encoders; i++) {
+			struct drm_encoder *encoder = priv->encoders[i];
+			if (encoder->crtc == plane->crtc) {
+				mgr = omap_encoder_get_manager(encoder);
+				break;
+			}
+		}
+	}
+
+	if (ovl->manager != mgr) {
+		bool enabled = ovl->is_enabled(ovl);
+
+		/* don't switch things around with enabled overlays: */
+		if (enabled)
+			omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+
+		if (ovl->manager) {
+			DBG("disconnecting %s from %s", ovl->name,
+					ovl->manager->name);
+			ovl->unset_manager(ovl);
+		}
+
+		if (mgr) {
+			DBG("connecting %s to %s", ovl->name, mgr->name);
+			ovl->set_manager(ovl, mgr);
+		}
+
+		if (enabled && mgr)
+			omap_plane_dpms(plane, DRM_MODE_DPMS_ON);
+	}
+}
+
+/* update which fb (if any) is pinned for scanout */
+static int update_pin(struct drm_plane *plane, struct drm_framebuffer *fb)
+{
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+	int ret = 0;
+
+	if (omap_plane->pinned_fb != fb) {
+		if (omap_plane->pinned_fb)
+			omap_framebuffer_unpin(omap_plane->pinned_fb);
+		omap_plane->pinned_fb = fb;
+		if (fb)
+			ret = omap_framebuffer_pin(fb);
+	}
+
+	return ret;
+}
+
+/* update parameters that are dependent on the framebuffer dimensions and
+ * position within the fb that this plane scans out from. This is called
+ * when framebuffer or x,y base may have changed.
+ */
+static void update_scanout(struct drm_plane *plane)
+{
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+	struct omap_overlay_info *info = &omap_plane->info;
+	int ret;
+
+	ret = update_pin(plane, plane->fb);
+	if (ret) {
+		dev_err(plane->dev->dev,
+			"could not pin fb: %d\n", ret);
+		omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+		return;
+	}
+
+	omap_framebuffer_update_scanout(plane->fb,
+			omap_plane->src_x, omap_plane->src_y, info);
+
+	DBG("%s: %d,%d: %08x %08x (%d)", omap_plane->ovl->name,
+			omap_plane->src_x, omap_plane->src_y,
+			(u32)info->paddr, (u32)info->p_uv_addr,
+			info->screen_width);
+}
+
+int omap_plane_mode_set(struct drm_plane *plane,
+		struct drm_crtc *crtc, struct drm_framebuffer *fb,
+		int crtc_x, int crtc_y,
+		unsigned int crtc_w, unsigned int crtc_h,
+		uint32_t src_x, uint32_t src_y,
+		uint32_t src_w, uint32_t src_h)
+{
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+
+	/* src values are in Q16 fixed point, convert to integer: */
+	src_x = src_x >> 16;
+	src_y = src_y >> 16;
+	src_w = src_w >> 16;
+	src_h = src_h >> 16;
+
+	omap_plane->info.pos_x = crtc_x;
+	omap_plane->info.pos_y = crtc_y;
+	omap_plane->info.out_width = crtc_w;
+	omap_plane->info.out_height = crtc_h;
+	omap_plane->info.width = src_w;
+	omap_plane->info.height = src_h;
+	omap_plane->src_x = src_x;
+	omap_plane->src_y = src_y;
+
+	/* note: this is done after this fxn returns.. but if we need
+	 * to do a commit/update_scanout, etc before this returns we
+	 * need the current value.
+	 */
+	plane->fb = fb;
+	plane->crtc = crtc;
+
+	update_scanout(plane);
+	update_manager(plane);
+
+	return 0;
+}
+
+static int omap_plane_update(struct drm_plane *plane,
+		struct drm_crtc *crtc, struct drm_framebuffer *fb,
+		int crtc_x, int crtc_y,
+		unsigned int crtc_w, unsigned int crtc_h,
+		uint32_t src_x, uint32_t src_y,
+		uint32_t src_w, uint32_t src_h)
+{
+	omap_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h,
+			src_x, src_y, src_w, src_h);
+	return omap_plane_dpms(plane, DRM_MODE_DPMS_ON);
+}
+
+static int omap_plane_disable(struct drm_plane *plane)
+{
+	return omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+}
+
+static void omap_plane_destroy(struct drm_plane *plane)
+{
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+	DBG("%s", omap_plane->ovl->name);
+	omap_plane_disable(plane);
+	drm_plane_cleanup(plane);
+	kfree(omap_plane);
+}
+
+int omap_plane_dpms(struct drm_plane *plane, int mode)
+{
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+	struct omap_overlay *ovl = omap_plane->ovl;
+	int r;
+
+	DBG("%s: %d", omap_plane->ovl->name, mode);
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		update_scanout(plane);
+		r = commit(plane);
+		if (!r)
+			r = ovl->enable(ovl);
+	} else {
+		r = ovl->disable(ovl);
+		update_pin(plane, NULL);
+	}
+
+	return r;
+}
+
+static const struct drm_plane_funcs omap_plane_funcs = {
+		.update_plane = omap_plane_update,
+		.disable_plane = omap_plane_disable,
+		.destroy = omap_plane_destroy,
+};
+
+static const uint32_t formats[] = {
+		DRM_FORMAT_RGB565,
+		DRM_FORMAT_RGBX4444,
+		DRM_FORMAT_XRGB4444,
+		DRM_FORMAT_RGBA4444,
+		DRM_FORMAT_ABGR4444,
+		DRM_FORMAT_XRGB1555,
+		DRM_FORMAT_ARGB1555,
+		DRM_FORMAT_RGB888,
+		DRM_FORMAT_RGBX8888,
+		DRM_FORMAT_XRGB8888,
+		DRM_FORMAT_RGBA8888,
+		DRM_FORMAT_ARGB8888,
+		DRM_FORMAT_NV12,
+		DRM_FORMAT_YUYV,
+		DRM_FORMAT_UYVY,
+};
+
+/* initialize plane */
+struct drm_plane *omap_plane_init(struct drm_device *dev,
+		struct omap_overlay *ovl, unsigned int possible_crtcs,
+		bool priv)
+{
+	struct drm_plane *plane = NULL;
+	struct omap_plane *omap_plane;
+
+	DBG("%s: possible_crtcs=%08x, priv=%d", ovl->name,
+			possible_crtcs, priv);
+
+	omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
+	if (!omap_plane) {
+		dev_err(dev->dev, "could not allocate plane\n");
+		goto fail;
+	}
+
+	omap_plane->ovl = ovl;
+	plane = &omap_plane->base;
+
+	drm_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs,
+			formats, ARRAY_SIZE(formats), priv);
+
+	/* get our starting configuration, set defaults for parameters
+	 * we don't currently use, etc:
+	 */
+	ovl->get_overlay_info(ovl, &omap_plane->info);
+	omap_plane->info.rotation_type = OMAP_DSS_ROT_DMA;
+	omap_plane->info.rotation = OMAP_DSS_ROT_0;
+	omap_plane->info.global_alpha = 0xff;
+	omap_plane->info.mirror = 0;
+	omap_plane->info.mirror = 0;
+
+	/* Set defaults depending on whether we are a CRTC or overlay
+	 * layer.
+	 * TODO add ioctl to give userspace an API to change this.. this
+	 * will come in a subsequent patch.
+	 */
+	if (priv)
+		omap_plane->info.zorder = 0;
+	else
+		omap_plane->info.zorder = 1;
+
+	update_manager(plane);
+
+	return plane;
+
+fail:
+	if (plane) {
+		omap_plane_destroy(plane);
+	}
+	return NULL;
+}
diff --git a/drivers/staging/omapdrm/omap_priv.h b/drivers/staging/omapdrm/omap_priv.h
index c324709..ef64414 100644
--- a/drivers/staging/omapdrm/omap_priv.h
+++ b/drivers/staging/omapdrm/omap_priv.h
@@ -27,14 +27,22 @@
  * pipes/overlays/CRTCs are used.. if this is not provided, then instead the
  * first CONFIG_DRM_OMAP_NUM_CRTCS are used, and they are each connected to
  * one manager, with priority given to managers that are connected to
- * detected devices.  This should be a good default behavior for most cases,
- * but yet there still might be times when you wish to do something different.
+ * detected devices.  Remaining overlays are used as video planes.  This
+ * should be a good default behavior for most cases, but yet there still
+ * might be times when you wish to do something different.
  */
 struct omap_kms_platform_data {
+	/* overlays to use as CRTCs: */
 	int ovl_cnt;
 	const int *ovl_ids;
+
+	/* overlays to use as video planes: */
+	int pln_cnt;
+	const int *pln_ids;
+
 	int mgr_cnt;
 	const int *mgr_ids;
+
 	int dev_cnt;
 	const char **dev_names;
 };
diff --git a/drivers/staging/pohmelfs/Kconfig b/drivers/staging/pohmelfs/Kconfig
deleted file mode 100644
index 8d53b1a..0000000
--- a/drivers/staging/pohmelfs/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-config POHMELFS
-	tristate "POHMELFS filesystem support"
-	depends on NET
-	select CONNECTOR
-	select CRYPTO
-	select CRYPTO_BLKCIPHER
-	select CRYPTO_HMAC
-	help
-	  POHMELFS stands for Parallel Optimized Host Message Exchange Layered
-	  File System.  This is a network filesystem which supports coherent
-	  caching of data and metadata on clients.
-
-config POHMELFS_DEBUG
-	bool "POHMELFS debugging"
-	depends on POHMELFS
-	default n
-	help
-	  Turns on excessive POHMELFS debugging facilities.
-	  You usually do not want to slow things down noticeably and get really
-	  lots of kernel messages in syslog.
diff --git a/drivers/staging/pohmelfs/Makefile b/drivers/staging/pohmelfs/Makefile
deleted file mode 100644
index 196561c..0000000
--- a/drivers/staging/pohmelfs/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_POHMELFS)	+= pohmelfs.o
-
-pohmelfs-y := inode.o config.o dir.o net.o path_entry.o trans.o crypto.o lock.o mcache.o
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
deleted file mode 100644
index b6c42cb..0000000
--- a/drivers/staging/pohmelfs/config.c
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/connector.h>
-#include <linux/crypto.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/string.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-
-#include "netfs.h"
-
-/*
- * Global configuration list.
- * Each client can be asked to get one of them.
- *
- * Allows to provide remote server address (ipv4/v6/whatever), port
- * and so on via kernel connector.
- */
-
-static struct cb_id pohmelfs_cn_id = {.idx = POHMELFS_CN_IDX, .val = POHMELFS_CN_VAL};
-static LIST_HEAD(pohmelfs_config_list);
-static DEFINE_MUTEX(pohmelfs_config_lock);
-
-static inline int pohmelfs_config_eql(struct pohmelfs_ctl *sc, struct pohmelfs_ctl *ctl)
-{
-	if (sc->idx == ctl->idx && sc->type == ctl->type &&
-			sc->proto == ctl->proto &&
-			sc->addrlen == ctl->addrlen &&
-			!memcmp(&sc->addr, &ctl->addr, ctl->addrlen))
-		return 1;
-
-	return 0;
-}
-
-static struct pohmelfs_config_group *pohmelfs_find_config_group(unsigned int idx)
-{
-	struct pohmelfs_config_group *g, *group = NULL;
-
-	list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
-		if (g->idx == idx) {
-			group = g;
-			break;
-		}
-	}
-
-	return group;
-}
-
-static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned int idx)
-{
-	struct pohmelfs_config_group *g;
-
-	g = pohmelfs_find_config_group(idx);
-	if (g)
-		return g;
-
-	g = kzalloc(sizeof(struct pohmelfs_config_group), GFP_KERNEL);
-	if (!g)
-		return NULL;
-
-	INIT_LIST_HEAD(&g->config_list);
-	g->idx = idx;
-	g->num_entry = 0;
-
-	list_add_tail(&g->group_entry, &pohmelfs_config_list);
-
-	return g;
-}
-
-static inline void pohmelfs_insert_config_entry(struct pohmelfs_sb *psb, struct pohmelfs_config *dst)
-{
-	struct pohmelfs_config *tmp;
-
-	INIT_LIST_HEAD(&dst->config_entry);
-
-	list_for_each_entry(tmp, &psb->state_list, config_entry) {
-		if (dst->state.ctl.prio > tmp->state.ctl.prio)
-			list_add_tail(&dst->config_entry, &tmp->config_entry);
-	}
-	if (list_empty(&dst->config_entry))
-		list_add_tail(&dst->config_entry, &psb->state_list);
-}
-
-static int pohmelfs_move_config_entry(struct pohmelfs_sb *psb,
-		struct pohmelfs_config *dst, struct pohmelfs_config *new)
-{
-	if ((dst->state.ctl.prio == new->state.ctl.prio) &&
-		(dst->state.ctl.perm == new->state.ctl.perm))
-		return 0;
-
-	dprintk("%s: dst: prio: %d, perm: %x, new: prio: %d, perm: %d.\n",
-			__func__, dst->state.ctl.prio, dst->state.ctl.perm,
-			new->state.ctl.prio, new->state.ctl.perm);
-	dst->state.ctl.prio = new->state.ctl.prio;
-	dst->state.ctl.perm = new->state.ctl.perm;
-
-	list_del_init(&dst->config_entry);
-	pohmelfs_insert_config_entry(psb, dst);
-	return 0;
-}
-
-/*
- * pohmelfs_copy_config() is used to copy new state configs from the
- * config group (controlled by the netlink messages) into the superblock.
- * This happens either at startup time where no transactions can access
- * the list of the configs (and thus list of the network states), or at
- * run-time, where it is protected by the psb->state_lock.
- */
-int pohmelfs_copy_config(struct pohmelfs_sb *psb)
-{
-	struct pohmelfs_config_group *g;
-	struct pohmelfs_config *c, *dst;
-	int err = -ENODEV;
-
-	mutex_lock(&pohmelfs_config_lock);
-
-	g = pohmelfs_find_config_group(psb->idx);
-	if (!g)
-		goto out_unlock;
-
-	/*
-	 * Run over all entries in given config group and try to create and
-	 * initialize those, which do not exist in superblock list.
-	 * Skip all existing entries.
-	 */
-
-	list_for_each_entry(c, &g->config_list, config_entry) {
-		err = 0;
-		list_for_each_entry(dst, &psb->state_list, config_entry) {
-			if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) {
-				err = pohmelfs_move_config_entry(psb, dst, c);
-				if (!err)
-					err = -EEXIST;
-				break;
-			}
-		}
-
-		if (err)
-			continue;
-
-		dst = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
-		if (!dst) {
-			err = -ENOMEM;
-			break;
-		}
-
-		memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl));
-
-		pohmelfs_insert_config_entry(psb, dst);
-
-		err = pohmelfs_state_init_one(psb, dst);
-		if (err) {
-			list_del(&dst->config_entry);
-			kfree(dst);
-		}
-
-		err = 0;
-	}
-
-out_unlock:
-	mutex_unlock(&pohmelfs_config_lock);
-
-	return err;
-}
-
-int pohmelfs_copy_crypto(struct pohmelfs_sb *psb)
-{
-	struct pohmelfs_config_group *g;
-	int err = -ENOENT;
-
-	mutex_lock(&pohmelfs_config_lock);
-	g = pohmelfs_find_config_group(psb->idx);
-	if (!g)
-		goto err_out_exit;
-
-	if (g->hash_string) {
-		err = -ENOMEM;
-		psb->hash_string = kstrdup(g->hash_string, GFP_KERNEL);
-		if (!psb->hash_string)
-			goto err_out_exit;
-		psb->hash_strlen = g->hash_strlen;
-	}
-
-	if (g->cipher_string) {
-		psb->cipher_string = kstrdup(g->cipher_string, GFP_KERNEL);
-		if (!psb->cipher_string)
-			goto err_out_free_hash_string;
-		psb->cipher_strlen = g->cipher_strlen;
-	}
-
-	if (g->hash_keysize) {
-		psb->hash_key = kmemdup(g->hash_key, g->hash_keysize,
-					GFP_KERNEL);
-		if (!psb->hash_key)
-			goto err_out_free_cipher_string;
-		psb->hash_keysize = g->hash_keysize;
-	}
-
-	if (g->cipher_keysize) {
-		psb->cipher_key = kmemdup(g->cipher_key, g->cipher_keysize,
-					  GFP_KERNEL);
-		if (!psb->cipher_key)
-			goto err_out_free_hash;
-		psb->cipher_keysize = g->cipher_keysize;
-	}
-
-	mutex_unlock(&pohmelfs_config_lock);
-
-	return 0;
-
-err_out_free_hash:
-	kfree(psb->hash_key);
-err_out_free_cipher_string:
-	kfree(psb->cipher_string);
-err_out_free_hash_string:
-	kfree(psb->hash_string);
-err_out_exit:
-	mutex_unlock(&pohmelfs_config_lock);
-	return err;
-}
-
-static int pohmelfs_send_reply(int err, int msg_num, int action, struct cn_msg *msg, struct pohmelfs_ctl *ctl)
-{
-	struct pohmelfs_cn_ack *ack;
-
-	ack = kzalloc(sizeof(struct pohmelfs_cn_ack), GFP_KERNEL);
-	if (!ack)
-		return -ENOMEM;
-
-	memcpy(&ack->msg, msg, sizeof(struct cn_msg));
-
-	if (action == POHMELFS_CTLINFO_ACK)
-		memcpy(&ack->ctl, ctl, sizeof(struct pohmelfs_ctl));
-
-	ack->msg.len = sizeof(struct pohmelfs_cn_ack) - sizeof(struct cn_msg);
-	ack->msg.ack = msg->ack + 1;
-	ack->error = err;
-	ack->msg_num = msg_num;
-
-	cn_netlink_send(&ack->msg, 0, GFP_KERNEL);
-	kfree(ack);
-	return 0;
-}
-
-static int pohmelfs_cn_disp(struct cn_msg *msg)
-{
-	struct pohmelfs_config_group *g;
-	struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
-	struct pohmelfs_config *c, *tmp;
-	int err = 0, i = 1;
-
-	if (msg->len != sizeof(struct pohmelfs_ctl))
-		return -EBADMSG;
-
-	mutex_lock(&pohmelfs_config_lock);
-
-	g = pohmelfs_find_config_group(ctl->idx);
-	if (!g) {
-		pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL);
-		goto out_unlock;
-	}
-
-	list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
-		struct pohmelfs_ctl *sc = &c->state.ctl;
-		if (pohmelfs_send_reply(err, g->num_entry - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
-			err = -ENOMEM;
-			goto out_unlock;
-		}
-		i += 1;
-	}
-
- out_unlock:
-	mutex_unlock(&pohmelfs_config_lock);
-	return err;
-}
-
-static int pohmelfs_cn_dump(struct cn_msg *msg)
-{
-	struct pohmelfs_config_group *g;
-	struct pohmelfs_config *c, *tmp;
-	int err = 0, i = 1;
-	int total_msg = 0;
-
-	if (msg->len != sizeof(struct pohmelfs_ctl))
-		return -EBADMSG;
-
-	mutex_lock(&pohmelfs_config_lock);
-
-	list_for_each_entry(g, &pohmelfs_config_list, group_entry)
-		total_msg += g->num_entry;
-	if (total_msg == 0) {
-		if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
-			err = -ENOMEM;
-		goto out_unlock;
-	}
-
-	list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
-		list_for_each_entry_safe(c, tmp, &g->config_list,
-					 config_entry) {
-			struct pohmelfs_ctl *sc = &c->state.ctl;
-			if (pohmelfs_send_reply(err, total_msg - i,
-						POHMELFS_CTLINFO_ACK, msg,
-						sc)) {
-				err = -ENOMEM;
-				goto out_unlock;
-			}
-			i += 1;
-		}
-	}
-
-out_unlock:
-	mutex_unlock(&pohmelfs_config_lock);
-	return err;
-}
-
-static int pohmelfs_cn_flush(struct cn_msg *msg)
-{
-	struct pohmelfs_config_group *g;
-	struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
-	struct pohmelfs_config *c, *tmp;
-	int err = 0;
-
-	if (msg->len != sizeof(struct pohmelfs_ctl))
-		return -EBADMSG;
-
-	mutex_lock(&pohmelfs_config_lock);
-
-	if (ctl->idx != POHMELFS_NULL_IDX) {
-		g = pohmelfs_find_config_group(ctl->idx);
-
-		if (!g)
-			goto out_unlock;
-
-		list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
-			list_del(&c->config_entry);
-			g->num_entry--;
-			kfree(c);
-		}
-	} else {
-		list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
-			list_for_each_entry_safe(c, tmp, &g->config_list,
-						 config_entry) {
-				list_del(&c->config_entry);
-				g->num_entry--;
-				kfree(c);
-			}
-		}
-	}
-
-out_unlock:
-	mutex_unlock(&pohmelfs_config_lock);
-	pohmelfs_cn_dump(msg);
-
-	return err;
-}
-
-static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new)
-{
-	old->perm = new->perm;
-	old->prio = new->prio;
-	return 0;
-}
-
-static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
-{
-	struct pohmelfs_config_group *g;
-	struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
-	struct pohmelfs_config *c, *tmp;
-	int err = 0;
-
-	if (msg->len != sizeof(struct pohmelfs_ctl))
-		return -EBADMSG;
-
-	mutex_lock(&pohmelfs_config_lock);
-
-	g = pohmelfs_find_create_config_group(ctl->idx);
-	if (!g) {
-		err = -ENOMEM;
-		goto out_unlock;
-	}
-
-	list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
-		struct pohmelfs_ctl *sc = &c->state.ctl;
-
-		if (pohmelfs_config_eql(sc, ctl)) {
-			if (action == POHMELFS_FLAGS_ADD) {
-				err = -EEXIST;
-				goto out_unlock;
-			} else if (action == POHMELFS_FLAGS_DEL) {
-				list_del(&c->config_entry);
-				g->num_entry--;
-				kfree(c);
-				goto out_unlock;
-			} else if (action == POHMELFS_FLAGS_MODIFY) {
-				err = pohmelfs_modify_config(sc, ctl);
-				goto out_unlock;
-			} else {
-				err = -EEXIST;
-				goto out_unlock;
-			}
-		}
-	}
-	if (action == POHMELFS_FLAGS_DEL) {
-		err = -EBADMSG;
-		goto out_unlock;
-	}
-
-	c = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
-	if (!c) {
-		err = -ENOMEM;
-		goto out_unlock;
-	}
-	memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
-	g->num_entry++;
-
-	list_add_tail(&c->config_entry, &g->config_list);
-
- out_unlock:
-	mutex_unlock(&pohmelfs_config_lock);
-	if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
-		err = -ENOMEM;
-
-	return err;
-}
-
-static int pohmelfs_crypto_hash_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
-{
-	char *algo = (char *)c->data;
-	u8 *key = (u8 *)(algo + c->strlen);
-
-	if (g->hash_string)
-		return -EEXIST;
-
-	g->hash_string = kstrdup(algo, GFP_KERNEL);
-	if (!g->hash_string)
-		return -ENOMEM;
-	g->hash_strlen = c->strlen;
-	g->hash_keysize = c->keysize;
-
-	g->hash_key = kmemdup(key, c->keysize, GFP_KERNEL);
-	if (!g->hash_key) {
-		kfree(g->hash_string);
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
-{
-	char *algo = (char *)c->data;
-	u8 *key = (u8 *)(algo + c->strlen);
-
-	if (g->cipher_string)
-		return -EEXIST;
-
-	g->cipher_string = kstrdup(algo, GFP_KERNEL);
-	if (!g->cipher_string)
-		return -ENOMEM;
-	g->cipher_strlen = c->strlen;
-	g->cipher_keysize = c->keysize;
-
-	g->cipher_key = kmemdup(key, c->keysize, GFP_KERNEL);
-	if (!g->cipher_key) {
-		kfree(g->cipher_string);
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static int pohmelfs_cn_crypto(struct cn_msg *msg)
-{
-	struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
-	struct pohmelfs_config_group *g;
-	int err = 0;
-
-	dprintk("%s: idx: %u, strlen: %u, type: %u, keysize: %u, algo: %s.\n",
-			__func__, crypto->idx, crypto->strlen, crypto->type,
-			crypto->keysize, (char *)crypto->data);
-
-	mutex_lock(&pohmelfs_config_lock);
-	g = pohmelfs_find_create_config_group(crypto->idx);
-	if (!g) {
-		err = -ENOMEM;
-		goto out_unlock;
-	}
-
-	switch (crypto->type) {
-	case POHMELFS_CRYPTO_HASH:
-			err = pohmelfs_crypto_hash_init(g, crypto);
-			break;
-	case POHMELFS_CRYPTO_CIPHER:
-			err = pohmelfs_crypto_cipher_init(g, crypto);
-			break;
-	default:
-			err = -ENOTSUPP;
-			break;
-	}
-
-out_unlock:
-	mutex_unlock(&pohmelfs_config_lock);
-	if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
-		err = -ENOMEM;
-
-	return err;
-}
-
-static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
-{
-	int err;
-
-	if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
-		return;
-
-	switch (msg->flags) {
-	case POHMELFS_FLAGS_ADD:
-	case POHMELFS_FLAGS_DEL:
-	case POHMELFS_FLAGS_MODIFY:
-			err = pohmelfs_cn_ctl(msg, msg->flags);
-			break;
-	case POHMELFS_FLAGS_FLUSH:
-			err = pohmelfs_cn_flush(msg);
-			break;
-	case POHMELFS_FLAGS_SHOW:
-			err = pohmelfs_cn_disp(msg);
-			break;
-	case POHMELFS_FLAGS_DUMP:
-			err = pohmelfs_cn_dump(msg);
-			break;
-	case POHMELFS_FLAGS_CRYPTO:
-			err = pohmelfs_cn_crypto(msg);
-			break;
-	default:
-			err = -ENOSYS;
-			break;
-	}
-}
-
-int pohmelfs_config_check(struct pohmelfs_config *config, int idx)
-{
-	struct pohmelfs_ctl *ctl = &config->state.ctl;
-	struct pohmelfs_config *tmp;
-	int err = -ENOENT;
-	struct pohmelfs_ctl *sc;
-	struct pohmelfs_config_group *g;
-
-	mutex_lock(&pohmelfs_config_lock);
-
-	g = pohmelfs_find_config_group(ctl->idx);
-	if (g) {
-		list_for_each_entry(tmp, &g->config_list, config_entry) {
-			sc = &tmp->state.ctl;
-
-			if (pohmelfs_config_eql(sc, ctl)) {
-				err = 0;
-				break;
-			}
-		}
-	}
-
-	mutex_unlock(&pohmelfs_config_lock);
-
-	return err;
-}
-
-int __init pohmelfs_config_init(void)
-{
-	/* XXX remove (void *) cast when vanilla connector got synced */
-	return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", (void *)pohmelfs_cn_callback);
-}
-
-void pohmelfs_config_exit(void)
-{
-	struct pohmelfs_config *c, *tmp;
-	struct pohmelfs_config_group *g, *gtmp;
-
-	cn_del_callback(&pohmelfs_cn_id);
-
-	mutex_lock(&pohmelfs_config_lock);
-	list_for_each_entry_safe(g, gtmp, &pohmelfs_config_list, group_entry) {
-		list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
-			list_del(&c->config_entry);
-			kfree(c);
-		}
-
-		list_del(&g->group_entry);
-
-		kfree(g->hash_string);
-
-		kfree(g->cipher_string);
-
-		kfree(g);
-	}
-	mutex_unlock(&pohmelfs_config_lock);
-}
diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c
deleted file mode 100644
index ad92771..0000000
--- a/drivers/staging/pohmelfs/crypto.c
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/crypto.h>
-#include <linux/highmem.h>
-#include <linux/kthread.h>
-#include <linux/pagemap.h>
-#include <linux/scatterlist.h>
-#include <linux/slab.h>
-
-#include "netfs.h"
-
-static struct crypto_hash *pohmelfs_init_hash(struct pohmelfs_sb *psb)
-{
-	int err;
-	struct crypto_hash *hash;
-
-	hash = crypto_alloc_hash(psb->hash_string, 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(hash)) {
-		err = PTR_ERR(hash);
-		dprintk("%s: idx: %u: failed to allocate hash '%s', err: %d.\n",
-				__func__, psb->idx, psb->hash_string, err);
-		goto err_out_exit;
-	}
-
-	psb->crypto_attached_size = crypto_hash_digestsize(hash);
-
-	if (!psb->hash_keysize)
-		return hash;
-
-	err = crypto_hash_setkey(hash, psb->hash_key, psb->hash_keysize);
-	if (err) {
-		dprintk("%s: idx: %u: failed to set key for hash '%s', err: %d.\n",
-				__func__, psb->idx, psb->hash_string, err);
-		goto err_out_free;
-	}
-
-	return hash;
-
-err_out_free:
-	crypto_free_hash(hash);
-err_out_exit:
-	return ERR_PTR(err);
-}
-
-static struct crypto_ablkcipher *pohmelfs_init_cipher(struct pohmelfs_sb *psb)
-{
-	int err = -EINVAL;
-	struct crypto_ablkcipher *cipher;
-
-	if (!psb->cipher_keysize)
-		goto err_out_exit;
-
-	cipher = crypto_alloc_ablkcipher(psb->cipher_string, 0, 0);
-	if (IS_ERR(cipher)) {
-		err = PTR_ERR(cipher);
-		dprintk("%s: idx: %u: failed to allocate cipher '%s', err: %d.\n",
-				__func__, psb->idx, psb->cipher_string, err);
-		goto err_out_exit;
-	}
-
-	crypto_ablkcipher_clear_flags(cipher, ~0);
-
-	err = crypto_ablkcipher_setkey(cipher, psb->cipher_key, psb->cipher_keysize);
-	if (err) {
-		dprintk("%s: idx: %u: failed to set key for cipher '%s', err: %d.\n",
-				__func__, psb->idx, psb->cipher_string, err);
-		goto err_out_free;
-	}
-
-	return cipher;
-
-err_out_free:
-	crypto_free_ablkcipher(cipher);
-err_out_exit:
-	return ERR_PTR(err);
-}
-
-int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
-{
-	int err;
-
-	e->page_num = 0;
-
-	e->size = PAGE_SIZE;
-	e->data = kmalloc(e->size, GFP_KERNEL);
-	if (!e->data) {
-		err = -ENOMEM;
-		goto err_out_exit;
-	}
-
-	if (psb->hash_string) {
-		e->hash = pohmelfs_init_hash(psb);
-		if (IS_ERR(e->hash)) {
-			err = PTR_ERR(e->hash);
-			e->hash = NULL;
-			goto err_out_free;
-		}
-	}
-
-	if (psb->cipher_string) {
-		e->cipher = pohmelfs_init_cipher(psb);
-		if (IS_ERR(e->cipher)) {
-			err = PTR_ERR(e->cipher);
-			e->cipher = NULL;
-			goto err_out_free_hash;
-		}
-	}
-
-	return 0;
-
-err_out_free_hash:
-	crypto_free_hash(e->hash);
-err_out_free:
-	kfree(e->data);
-err_out_exit:
-	return err;
-}
-
-void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e)
-{
-	crypto_free_hash(e->hash);
-	crypto_free_ablkcipher(e->cipher);
-	kfree(e->data);
-}
-
-static void pohmelfs_crypto_complete(struct crypto_async_request *req, int err)
-{
-	struct pohmelfs_crypto_completion *c = req->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
-	c->error = err;
-	complete(&c->complete);
-}
-
-static int pohmelfs_crypto_process(struct ablkcipher_request *req,
-		struct scatterlist *sg_dst, struct scatterlist *sg_src,
-		void *iv, int enc, unsigned long timeout)
-{
-	struct pohmelfs_crypto_completion complete;
-	int err;
-
-	init_completion(&complete.complete);
-	complete.error = -EINPROGRESS;
-
-	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-					pohmelfs_crypto_complete, &complete);
-
-	ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
-
-	if (enc)
-		err = crypto_ablkcipher_encrypt(req);
-	else
-		err = crypto_ablkcipher_decrypt(req);
-
-	switch (err) {
-	case -EINPROGRESS:
-	case -EBUSY:
-		err = wait_for_completion_interruptible_timeout(&complete.complete,
-					timeout);
-		if (!err)
-			err = -ETIMEDOUT;
-		else if (err > 0)
-			err = complete.error;
-		break;
-	default:
-		break;
-	}
-
-	return err;
-}
-
-int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 cmd_iv,
-		void *data, struct page *page, unsigned int size)
-{
-	int err;
-	struct scatterlist sg;
-
-	if (!e->cipher && !e->hash)
-		return 0;
-
-	dprintk("%s: eng: %p, iv: %llx, data: %p, page: %p/%lu, size: %u.\n",
-		__func__, e, cmd_iv, data, page, (page) ? page->index : 0, size);
-
-	if (data) {
-		sg_init_one(&sg, data, size);
-	} else {
-		sg_init_table(&sg, 1);
-		sg_set_page(&sg, page, size, 0);
-	}
-
-	if (e->cipher) {
-		struct ablkcipher_request *req = e->data + crypto_hash_digestsize(e->hash);
-		u8 iv[32];
-
-		memset(iv, 0, sizeof(iv));
-		memcpy(iv, &cmd_iv, sizeof(cmd_iv));
-
-		ablkcipher_request_set_tfm(req, e->cipher);
-
-		err = pohmelfs_crypto_process(req, &sg, &sg, iv, 0, e->timeout);
-		if (err)
-			goto err_out_exit;
-	}
-
-	if (e->hash) {
-		struct hash_desc desc;
-		void *dst = e->data + e->size/2;
-
-		desc.tfm = e->hash;
-		desc.flags = 0;
-
-		err = crypto_hash_init(&desc);
-		if (err)
-			goto err_out_exit;
-
-		err = crypto_hash_update(&desc, &sg, size);
-		if (err)
-			goto err_out_exit;
-
-		err = crypto_hash_final(&desc, dst);
-		if (err)
-			goto err_out_exit;
-
-		err = !!memcmp(dst, e->data, crypto_hash_digestsize(e->hash));
-
-		if (err) {
-#ifdef CONFIG_POHMELFS_DEBUG
-			unsigned int i;
-			unsigned char *recv = e->data, *calc = dst;
-
-			dprintk("%s: eng: %p, hash: %p, cipher: %p: iv : %llx, hash mismatch (recv/calc): ",
-					__func__, e, e->hash, e->cipher, cmd_iv);
-			for (i = 0; i < crypto_hash_digestsize(e->hash); ++i) {
-#if 0
-				dprintka("%02x ", recv[i]);
-				if (recv[i] != calc[i]) {
-					dprintka("| calc byte: %02x.\n", calc[i]);
-					break;
-				}
-#else
-				dprintka("%02x/%02x ", recv[i], calc[i]);
-#endif
-			}
-			dprintk("\n");
-#endif
-			goto err_out_exit;
-		} else {
-			dprintk("%s: eng: %p, hash: %p, cipher: %p: hashes matched.\n",
-					__func__, e, e->hash, e->cipher);
-		}
-	}
-
-	dprintk("%s: eng: %p, size: %u, hash: %p, cipher: %p: completed.\n",
-			__func__, e, e->size, e->hash, e->cipher);
-
-	return 0;
-
-err_out_exit:
-	dprintk("%s: eng: %p, hash: %p, cipher: %p: err: %d.\n",
-			__func__, e, e->hash, e->cipher, err);
-	return err;
-}
-
-static int pohmelfs_trans_iter(struct netfs_trans *t, struct pohmelfs_crypto_engine *e,
-		int (*iterator) (struct pohmelfs_crypto_engine *e,
-				  struct scatterlist *dst,
-				  struct scatterlist *src))
-{
-	void *data = t->iovec.iov_base + sizeof(struct netfs_cmd) + t->psb->crypto_attached_size;
-	unsigned int size = t->iovec.iov_len - sizeof(struct netfs_cmd) - t->psb->crypto_attached_size;
-	struct netfs_cmd *cmd = data;
-	unsigned int sz, pages = t->attached_pages, i, csize, cmd_cmd, dpage_idx;
-	struct scatterlist sg_src, sg_dst;
-	int err;
-
-	while (size) {
-		cmd = data;
-		cmd_cmd = __be16_to_cpu(cmd->cmd);
-		csize = __be32_to_cpu(cmd->size);
-		cmd->iv = __cpu_to_be64(e->iv);
-
-		if (cmd_cmd == NETFS_READ_PAGES || cmd_cmd == NETFS_READ_PAGE)
-			csize = __be16_to_cpu(cmd->ext);
-
-		sz = csize + __be16_to_cpu(cmd->cpad) + sizeof(struct netfs_cmd);
-
-		dprintk("%s: size: %u, sz: %u, cmd_size: %u, cmd_cpad: %u.\n",
-				__func__, size, sz, __be32_to_cpu(cmd->size), __be16_to_cpu(cmd->cpad));
-
-		data += sz;
-		size -= sz;
-
-		sg_init_one(&sg_src, cmd->data, sz - sizeof(struct netfs_cmd));
-		sg_init_one(&sg_dst, cmd->data, sz - sizeof(struct netfs_cmd));
-
-		err = iterator(e, &sg_dst, &sg_src);
-		if (err)
-			return err;
-	}
-
-	if (!pages)
-		return 0;
-
-	dpage_idx = 0;
-	for (i = 0; i < t->page_num; ++i) {
-		struct page *page = t->pages[i];
-		struct page *dpage = e->pages[dpage_idx];
-
-		if (!page)
-			continue;
-
-		sg_init_table(&sg_src, 1);
-		sg_init_table(&sg_dst, 1);
-		sg_set_page(&sg_src, page, page_private(page), 0);
-		sg_set_page(&sg_dst, dpage, page_private(page), 0);
-
-		err = iterator(e, &sg_dst, &sg_src);
-		if (err)
-			return err;
-
-		pages--;
-		if (!pages)
-			break;
-		dpage_idx++;
-	}
-
-	return 0;
-}
-
-static int pohmelfs_encrypt_iterator(struct pohmelfs_crypto_engine *e,
-		struct scatterlist *sg_dst, struct scatterlist *sg_src)
-{
-	struct ablkcipher_request *req = e->data;
-	u8 iv[32];
-
-	memset(iv, 0, sizeof(iv));
-
-	memcpy(iv, &e->iv, sizeof(e->iv));
-
-	return pohmelfs_crypto_process(req, sg_dst, sg_src, iv, 1, e->timeout);
-}
-
-static int pohmelfs_encrypt(struct pohmelfs_crypto_thread *tc)
-{
-	struct netfs_trans *t = tc->trans;
-	struct pohmelfs_crypto_engine *e = &tc->eng;
-	struct ablkcipher_request *req = e->data;
-
-	memset(req, 0, sizeof(struct ablkcipher_request));
-	ablkcipher_request_set_tfm(req, e->cipher);
-
-	e->iv = pohmelfs_gen_iv(t);
-
-	return pohmelfs_trans_iter(t, e, pohmelfs_encrypt_iterator);
-}
-
-static int pohmelfs_hash_iterator(struct pohmelfs_crypto_engine *e,
-		struct scatterlist *sg_dst, struct scatterlist *sg_src)
-{
-	return crypto_hash_update(e->data, sg_src, sg_src->length);
-}
-
-static int pohmelfs_hash(struct pohmelfs_crypto_thread *tc)
-{
-	struct pohmelfs_crypto_engine *e = &tc->eng;
-	struct hash_desc *desc = e->data;
-	unsigned char *dst = tc->trans->iovec.iov_base + sizeof(struct netfs_cmd);
-	int err;
-
-	desc->tfm = e->hash;
-	desc->flags = 0;
-
-	err = crypto_hash_init(desc);
-	if (err)
-		return err;
-
-	err = pohmelfs_trans_iter(tc->trans, e, pohmelfs_hash_iterator);
-	if (err)
-		return err;
-
-	err = crypto_hash_final(desc, dst);
-	if (err)
-		return err;
-
-	{
-		unsigned int i;
-		dprintk("%s: ", __func__);
-		for (i = 0; i < tc->psb->crypto_attached_size; ++i)
-			dprintka("%02x ", dst[i]);
-		dprintka("\n");
-	}
-
-	return 0;
-}
-
-static void pohmelfs_crypto_pages_free(struct pohmelfs_crypto_engine *e)
-{
-	unsigned int i;
-
-	for (i = 0; i < e->page_num; ++i)
-		__free_page(e->pages[i]);
-	kfree(e->pages);
-}
-
-static int pohmelfs_crypto_pages_alloc(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
-{
-	unsigned int i;
-
-	e->pages = kmalloc(psb->trans_max_pages * sizeof(struct page *), GFP_KERNEL);
-	if (!e->pages)
-		return -ENOMEM;
-
-	for (i = 0; i < psb->trans_max_pages; ++i) {
-		e->pages[i] = alloc_page(GFP_KERNEL);
-		if (!e->pages[i])
-			break;
-	}
-
-	e->page_num = i;
-	if (!e->page_num)
-		goto err_out_free;
-
-	return 0;
-
-err_out_free:
-	kfree(e->pages);
-	return -ENOMEM;
-}
-
-static void pohmelfs_sys_crypto_exit_one(struct pohmelfs_crypto_thread *t)
-{
-	struct pohmelfs_sb *psb = t->psb;
-
-	if (t->thread)
-		kthread_stop(t->thread);
-
-	mutex_lock(&psb->crypto_thread_lock);
-	list_del(&t->thread_entry);
-	psb->crypto_thread_num--;
-	mutex_unlock(&psb->crypto_thread_lock);
-
-	pohmelfs_crypto_engine_exit(&t->eng);
-	pohmelfs_crypto_pages_free(&t->eng);
-	kfree(t);
-}
-
-static int pohmelfs_crypto_finish(struct netfs_trans *t, struct pohmelfs_sb *psb, int err)
-{
-	struct netfs_cmd *cmd = t->iovec.iov_base;
-	netfs_convert_cmd(cmd);
-
-	if (likely(!err))
-		err = netfs_trans_finish_send(t, psb);
-
-	t->result = err;
-	netfs_trans_put(t);
-
-	return err;
-}
-
-void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th)
-{
-	struct pohmelfs_sb *psb = th->psb;
-
-	th->page = NULL;
-	th->trans = NULL;
-
-	mutex_lock(&psb->crypto_thread_lock);
-	list_move_tail(&th->thread_entry, &psb->crypto_ready_list);
-	mutex_unlock(&psb->crypto_thread_lock);
-	wake_up(&psb->wait);
-}
-
-static int pohmelfs_crypto_thread_trans(struct pohmelfs_crypto_thread *t)
-{
-	struct netfs_trans *trans;
-	int err = 0;
-
-	trans = t->trans;
-	trans->eng = NULL;
-
-	if (t->eng.hash) {
-		err = pohmelfs_hash(t);
-		if (err)
-			goto out_complete;
-	}
-
-	if (t->eng.cipher) {
-		err = pohmelfs_encrypt(t);
-		if (err)
-			goto out_complete;
-		trans->eng = &t->eng;
-	}
-
-out_complete:
-	t->page = NULL;
-	t->trans = NULL;
-
-	if (!trans->eng)
-		pohmelfs_crypto_thread_make_ready(t);
-
-	pohmelfs_crypto_finish(trans, t->psb, err);
-	return err;
-}
-
-static int pohmelfs_crypto_thread_page(struct pohmelfs_crypto_thread *t)
-{
-	struct pohmelfs_crypto_engine *e = &t->eng;
-	struct page *page = t->page;
-	int err;
-
-	WARN_ON(!PageChecked(page));
-
-	err = pohmelfs_crypto_process_input_data(e, e->iv, NULL, page, t->size);
-	if (!err)
-		SetPageUptodate(page);
-	else
-		SetPageError(page);
-	unlock_page(page);
-	page_cache_release(page);
-
-	pohmelfs_crypto_thread_make_ready(t);
-
-	return err;
-}
-
-static int pohmelfs_crypto_thread_func(void *data)
-{
-	struct pohmelfs_crypto_thread *t = data;
-
-	while (!kthread_should_stop()) {
-		wait_event_interruptible(t->wait, kthread_should_stop() ||
-				t->trans || t->page);
-
-		if (kthread_should_stop())
-			break;
-
-		if (!t->trans && !t->page)
-			continue;
-
-		dprintk("%s: thread: %p, trans: %p, page: %p.\n",
-				__func__, t, t->trans, t->page);
-
-		if (t->trans)
-			pohmelfs_crypto_thread_trans(t);
-		else if (t->page)
-			pohmelfs_crypto_thread_page(t);
-	}
-
-	return 0;
-}
-
-static void pohmelfs_crypto_flush(struct pohmelfs_sb *psb, struct list_head *head)
-{
-	while (!list_empty(head)) {
-		struct pohmelfs_crypto_thread *t = NULL;
-
-		mutex_lock(&psb->crypto_thread_lock);
-		if (!list_empty(head)) {
-			t = list_first_entry(head, struct pohmelfs_crypto_thread, thread_entry);
-			list_del_init(&t->thread_entry);
-		}
-		mutex_unlock(&psb->crypto_thread_lock);
-
-		if (t)
-			pohmelfs_sys_crypto_exit_one(t);
-	}
-}
-
-static void pohmelfs_sys_crypto_exit(struct pohmelfs_sb *psb)
-{
-	while (!list_empty(&psb->crypto_active_list) || !list_empty(&psb->crypto_ready_list)) {
-		dprintk("%s: crypto_thread_num: %u.\n", __func__, psb->crypto_thread_num);
-		pohmelfs_crypto_flush(psb, &psb->crypto_active_list);
-		pohmelfs_crypto_flush(psb, &psb->crypto_ready_list);
-	}
-}
-
-static int pohmelfs_sys_crypto_init(struct pohmelfs_sb *psb)
-{
-	unsigned int i;
-	struct pohmelfs_crypto_thread *t;
-	struct pohmelfs_config *c;
-	struct netfs_state *st;
-	int err;
-
-	list_for_each_entry(c, &psb->state_list, config_entry) {
-		st = &c->state;
-
-		err = pohmelfs_crypto_engine_init(&st->eng, psb);
-		if (err)
-			goto err_out_exit;
-
-		dprintk("%s: st: %p, eng: %p, hash: %p, cipher: %p.\n",
-				__func__, st, &st->eng, &st->eng.hash, &st->eng.cipher);
-	}
-
-	for (i = 0; i < psb->crypto_thread_num; ++i) {
-		err = -ENOMEM;
-		t = kzalloc(sizeof(struct pohmelfs_crypto_thread), GFP_KERNEL);
-		if (!t)
-			goto err_out_free_state_engines;
-
-		init_waitqueue_head(&t->wait);
-
-		t->psb = psb;
-		t->trans = NULL;
-		t->eng.thread = t;
-
-		err = pohmelfs_crypto_engine_init(&t->eng, psb);
-		if (err)
-			goto err_out_free_state_engines;
-
-		err = pohmelfs_crypto_pages_alloc(&t->eng, psb);
-		if (err)
-			goto err_out_free;
-
-		t->thread = kthread_run(pohmelfs_crypto_thread_func, t,
-				"pohmelfs-crypto-%d-%d", psb->idx, i);
-		if (IS_ERR(t->thread)) {
-			err = PTR_ERR(t->thread);
-			t->thread = NULL;
-			goto err_out_free;
-		}
-
-		if (t->eng.cipher)
-			psb->crypto_align_size = crypto_ablkcipher_blocksize(t->eng.cipher);
-
-		mutex_lock(&psb->crypto_thread_lock);
-		list_add_tail(&t->thread_entry, &psb->crypto_ready_list);
-		mutex_unlock(&psb->crypto_thread_lock);
-	}
-
-	psb->crypto_thread_num = i;
-	return 0;
-
-err_out_free:
-	pohmelfs_sys_crypto_exit_one(t);
-err_out_free_state_engines:
-	list_for_each_entry(c, &psb->state_list, config_entry) {
-		st = &c->state;
-		pohmelfs_crypto_engine_exit(&st->eng);
-	}
-err_out_exit:
-	pohmelfs_sys_crypto_exit(psb);
-	return err;
-}
-
-void pohmelfs_crypto_exit(struct pohmelfs_sb *psb)
-{
-	pohmelfs_sys_crypto_exit(psb);
-
-	kfree(psb->hash_string);
-	kfree(psb->cipher_string);
-}
-
-static int pohmelfs_crypt_init_complete(struct page **pages, unsigned int page_num,
-		void *private, int err)
-{
-	struct pohmelfs_sb *psb = private;
-
-	psb->flags = -err;
-	dprintk("%s: err: %d.\n", __func__, err);
-
-	wake_up(&psb->wait);
-
-	return err;
-}
-
-static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb)
-{
-	struct netfs_trans *t;
-	struct netfs_crypto_capabilities *cap;
-	struct netfs_cmd *cmd;
-	char *str;
-	int err = -ENOMEM, size;
-
-	size = sizeof(struct netfs_crypto_capabilities) +
-		psb->cipher_strlen + psb->hash_strlen + 2; /* 0 bytes */
-
-	t = netfs_trans_alloc(psb, size, 0, 0);
-	if (!t)
-		goto err_out_exit;
-
-	t->complete = pohmelfs_crypt_init_complete;
-	t->private = psb;
-
-	cmd = netfs_trans_current(t);
-	cap = (struct netfs_crypto_capabilities *)(cmd + 1);
-	str = (char *)(cap + 1);
-
-	cmd->cmd = NETFS_CAPABILITIES;
-	cmd->id = POHMELFS_CRYPTO_CAPABILITIES;
-	cmd->size = size;
-	cmd->start = 0;
-	cmd->ext = 0;
-	cmd->csize = 0;
-
-	netfs_convert_cmd(cmd);
-	netfs_trans_update(cmd, t, size);
-
-	cap->hash_strlen = psb->hash_strlen;
-	if (cap->hash_strlen) {
-		sprintf(str, "%s", psb->hash_string);
-		str += cap->hash_strlen;
-	}
-
-	cap->cipher_strlen = psb->cipher_strlen;
-	cap->cipher_keysize = psb->cipher_keysize;
-	if (cap->cipher_strlen)
-		sprintf(str, "%s", psb->cipher_string);
-
-	netfs_convert_crypto_capabilities(cap);
-
-	psb->flags = ~0;
-	err = netfs_trans_finish(t, psb);
-	if (err)
-		goto err_out_exit;
-
-	err = wait_event_interruptible_timeout(psb->wait, (psb->flags != ~0),
-			psb->wait_on_page_timeout);
-	if (!err)
-		err = -ETIMEDOUT;
-	else if (err > 0)
-		err = -psb->flags;
-
-	if (!err)
-		psb->perform_crypto = 1;
-	psb->flags = 0;
-
-	/*
-	 * At this point NETFS_CAPABILITIES response command
-	 * should setup superblock in a way, which is acceptable
-	 * for both client and server, so if server refuses connection,
-	 * it will send error in transaction response.
-	 */
-
-	if (err)
-		goto err_out_exit;
-
-	return 0;
-
-err_out_exit:
-	return err;
-}
-
-int pohmelfs_crypto_init(struct pohmelfs_sb *psb)
-{
-	int err;
-
-	if (!psb->cipher_string && !psb->hash_string)
-		return 0;
-
-	err = pohmelfs_crypto_init_handshake(psb);
-	if (err)
-		return err;
-
-	err = pohmelfs_sys_crypto_init(psb);
-	if (err)
-		return err;
-
-	return 0;
-}
-
-static int pohmelfs_crypto_thread_get(struct pohmelfs_sb *psb,
-		int (*action)(struct pohmelfs_crypto_thread *t, void *data), void *data)
-{
-	struct pohmelfs_crypto_thread *t = NULL;
-	int err;
-
-	while (!t) {
-		err = wait_event_interruptible_timeout(psb->wait,
-				!list_empty(&psb->crypto_ready_list),
-				psb->wait_on_page_timeout);
-
-		t = NULL;
-		err = 0;
-		mutex_lock(&psb->crypto_thread_lock);
-		if (!list_empty(&psb->crypto_ready_list)) {
-			t = list_entry(psb->crypto_ready_list.prev,
-					struct pohmelfs_crypto_thread,
-					thread_entry);
-
-			list_move_tail(&t->thread_entry,
-					&psb->crypto_active_list);
-
-			action(t, data);
-			wake_up(&t->wait);
-
-		}
-		mutex_unlock(&psb->crypto_thread_lock);
-	}
-
-	return err;
-}
-
-static int pohmelfs_trans_crypt_action(struct pohmelfs_crypto_thread *t, void *data)
-{
-	struct netfs_trans *trans = data;
-
-	netfs_trans_get(trans);
-	t->trans = trans;
-
-	dprintk("%s: t: %p, gen: %u, thread: %p.\n", __func__, trans, trans->gen, t);
-	return 0;
-}
-
-int pohmelfs_trans_crypt(struct netfs_trans *trans, struct pohmelfs_sb *psb)
-{
-	if ((!psb->hash_string && !psb->cipher_string) || !psb->perform_crypto) {
-		netfs_trans_get(trans);
-		return pohmelfs_crypto_finish(trans, psb, 0);
-	}
-
-	return pohmelfs_crypto_thread_get(psb, pohmelfs_trans_crypt_action, trans);
-}
-
-struct pohmelfs_crypto_input_action_data {
-	struct page			*page;
-	struct pohmelfs_crypto_engine	*e;
-	u64				iv;
-	unsigned int			size;
-};
-
-static int pohmelfs_crypt_input_page_action(struct pohmelfs_crypto_thread *t, void *data)
-{
-	struct pohmelfs_crypto_input_action_data *act = data;
-
-	memcpy(t->eng.data, act->e->data, t->psb->crypto_attached_size);
-
-	t->size = act->size;
-	t->eng.iv = act->iv;
-
-	t->page = act->page;
-	return 0;
-}
-
-int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
-		struct page *page, unsigned int size, u64 iv)
-{
-	struct inode *inode = page->mapping->host;
-	struct pohmelfs_crypto_input_action_data act;
-	int err = -ENOENT;
-
-	act.page = page;
-	act.e = e;
-	act.size = size;
-	act.iv = iv;
-
-	err = pohmelfs_crypto_thread_get(POHMELFS_SB(inode->i_sb),
-			pohmelfs_crypt_input_page_action, &act);
-	if (err)
-		goto err_out_exit;
-
-	return 0;
-
-err_out_exit:
-	SetPageUptodate(page);
-	page_cache_release(page);
-
-	return err;
-}
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
deleted file mode 100644
index 2ee4491..0000000
--- a/drivers/staging/pohmelfs/dir.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/jhash.h>
-#include <linux/namei.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-
-#include "netfs.h"
-
-static int pohmelfs_cmp_hash(struct pohmelfs_name *n, u32 hash)
-{
-	if (n->hash > hash)
-		return -1;
-	if (n->hash < hash)
-		return 1;
-
-	return 0;
-}
-
-static struct pohmelfs_name *pohmelfs_search_hash_unprecise(struct pohmelfs_inode *pi, u32 hash)
-{
-	struct rb_node *n = pi->hash_root.rb_node;
-	struct pohmelfs_name *tmp = NULL;
-	int cmp;
-
-	while (n) {
-		tmp = rb_entry(n, struct pohmelfs_name, hash_node);
-
-		cmp = pohmelfs_cmp_hash(tmp, hash);
-		if (cmp < 0)
-			n = n->rb_left;
-		else if (cmp > 0)
-			n = n->rb_right;
-		else
-			break;
-
-	}
-
-	return tmp;
-}
-
-struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash)
-{
-	struct pohmelfs_name *tmp;
-
-	tmp = pohmelfs_search_hash_unprecise(pi, hash);
-	if (tmp && (tmp->hash == hash))
-		return tmp;
-
-	return NULL;
-}
-
-static void __pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
-{
-	rb_erase(&node->hash_node, &parent->hash_root);
-}
-
-/*
- * Remove name cache entry from its caches and free it.
- */
-static void pohmelfs_name_free(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
-{
-	__pohmelfs_name_del(parent, node);
-	list_del(&node->sync_create_entry);
-	kfree(node);
-}
-
-static struct pohmelfs_name *pohmelfs_insert_hash(struct pohmelfs_inode *pi,
-		struct pohmelfs_name *new)
-{
-	struct rb_node **n = &pi->hash_root.rb_node, *parent = NULL;
-	struct pohmelfs_name *ret = NULL, *tmp;
-	int cmp;
-
-	while (*n) {
-		parent = *n;
-
-		tmp = rb_entry(parent, struct pohmelfs_name, hash_node);
-
-		cmp = pohmelfs_cmp_hash(tmp, new->hash);
-		if (cmp < 0)
-			n = &parent->rb_left;
-		else if (cmp > 0)
-			n = &parent->rb_right;
-		else {
-			ret = tmp;
-			break;
-		}
-	}
-
-	if (ret) {
-		printk("%s: exist: parent: %llu, ino: %llu, hash: %x, len: %u, data: '%s', "
-					"new: ino: %llu, hash: %x, len: %u, data: '%s'.\n",
-				__func__, pi->ino,
-				ret->ino, ret->hash, ret->len, ret->data,
-				new->ino, new->hash, new->len, new->data);
-		ret->ino = new->ino;
-		return ret;
-	}
-
-	rb_link_node(&new->hash_node, parent, n);
-	rb_insert_color(&new->hash_node, &pi->hash_root);
-
-	return NULL;
-}
-
-/*
- * Free name cache for given inode.
- */
-void pohmelfs_free_names(struct pohmelfs_inode *parent)
-{
-	struct rb_node *rb_node;
-	struct pohmelfs_name *n;
-
-	for (rb_node = rb_first(&parent->hash_root); rb_node;) {
-		n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
-		rb_node = rb_next(rb_node);
-
-		pohmelfs_name_free(parent, n);
-	}
-}
-
-static void pohmelfs_fix_offset(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
-{
-	parent->total_len -= node->len;
-}
-
-/*
- * Free name cache entry helper.
- */
-void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
-{
-	pohmelfs_fix_offset(parent, node);
-	pohmelfs_name_free(parent, node);
-}
-
-/*
- * Insert new name cache entry into all hash cache.
- */
-static int pohmelfs_insert_name(struct pohmelfs_inode *parent, struct pohmelfs_name *n)
-{
-	struct pohmelfs_name *name;
-
-	name = pohmelfs_insert_hash(parent, n);
-	if (name)
-		return -EEXIST;
-
-	parent->total_len += n->len;
-	list_add_tail(&n->sync_create_entry, &parent->sync_create_list);
-
-	return 0;
-}
-
-/*
- * Allocate new name cache entry.
- */
-static struct pohmelfs_name *pohmelfs_name_alloc(unsigned int len)
-{
-	struct pohmelfs_name *n;
-
-	n = kzalloc(sizeof(struct pohmelfs_name) + len, GFP_KERNEL);
-	if (!n)
-		return NULL;
-
-	INIT_LIST_HEAD(&n->sync_create_entry);
-
-	n->data = (char *)(n+1);
-
-	return n;
-}
-
-/*
- * Add new name entry into directory's cache.
- */
-static int pohmelfs_add_dir(struct pohmelfs_sb *psb, struct pohmelfs_inode *parent,
-		struct pohmelfs_inode *npi, struct qstr *str, unsigned int mode, int link)
-{
-	int err = -ENOMEM;
-	struct pohmelfs_name *n;
-
-	n = pohmelfs_name_alloc(str->len + 1);
-	if (!n)
-		goto err_out_exit;
-
-	n->ino = npi->ino;
-	n->mode = mode;
-	n->len = str->len;
-	n->hash = str->hash;
-	sprintf(n->data, "%s", str->name);
-
-	mutex_lock(&parent->offset_lock);
-	err = pohmelfs_insert_name(parent, n);
-	mutex_unlock(&parent->offset_lock);
-
-	if (err) {
-		if (err != -EEXIST)
-			goto err_out_free;
-		kfree(n);
-	}
-
-	return 0;
-
-err_out_free:
-	kfree(n);
-err_out_exit:
-	return err;
-}
-
-/*
- * Create new inode for given parameters (name, inode info, parent).
- * This does not create object on the server, it will be synced there during writeback.
- */
-struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
-		struct pohmelfs_inode *parent, struct qstr *str,
-		struct netfs_inode_info *info, int link)
-{
-	struct inode *new = NULL;
-	struct pohmelfs_inode *npi;
-	int err = -EEXIST;
-
-	dprintk("%s: creating inode: parent: %llu, ino: %llu, str: %p.\n",
-			__func__, (parent) ? parent->ino : 0, info->ino, str);
-
-	err = -ENOMEM;
-	new = iget_locked(psb->sb, info->ino);
-	if (!new)
-		goto err_out_exit;
-
-	npi = POHMELFS_I(new);
-	npi->ino = info->ino;
-	err = 0;
-
-	if (new->i_state & I_NEW) {
-		dprintk("%s: filling VFS inode: %lu/%llu.\n",
-				__func__, new->i_ino, info->ino);
-		pohmelfs_fill_inode(new, info);
-
-		if (S_ISDIR(info->mode)) {
-			struct qstr s;
-
-			s.name = ".";
-			s.len = 1;
-			s.hash = jhash(s.name, s.len, 0);
-
-			err = pohmelfs_add_dir(psb, npi, npi, &s, info->mode, 0);
-			if (err)
-				goto err_out_put;
-
-			s.name = "..";
-			s.len = 2;
-			s.hash = jhash(s.name, s.len, 0);
-
-			err = pohmelfs_add_dir(psb, npi, (parent) ? parent : npi, &s,
-					(parent) ? parent->vfs_inode.i_mode : npi->vfs_inode.i_mode, 0);
-			if (err)
-				goto err_out_put;
-		}
-	}
-
-	if (str) {
-		if (parent) {
-			err = pohmelfs_add_dir(psb, parent, npi, str, info->mode, link);
-
-			dprintk("%s: %s inserted name: '%s', new_offset: %llu, ino: %llu, parent: %llu.\n",
-					__func__, (err) ? "unsuccessfully" : "successfully",
-					str->name, parent->total_len, info->ino, parent->ino);
-
-			if (err && err != -EEXIST)
-				goto err_out_put;
-		}
-	}
-
-	if (new->i_state & I_NEW) {
-		if (parent)
-			mark_inode_dirty(&parent->vfs_inode);
-		mark_inode_dirty(new);
-	}
-
-	set_bit(NETFS_INODE_OWNED, &npi->state);
-	npi->lock_type = POHMELFS_WRITE_LOCK;
-	unlock_new_inode(new);
-
-	return npi;
-
-err_out_put:
-	printk("%s: putting inode: %p, npi: %p, error: %d.\n", __func__, new, npi, err);
-	iput(new);
-err_out_exit:
-	return ERR_PTR(err);
-}
-
-static int pohmelfs_remote_sync_complete(struct page **pages, unsigned int page_num,
-		void *private, int err)
-{
-	struct pohmelfs_inode *pi = private;
-	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-
-	dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
-
-	if (err)
-		pi->error = err;
-	wake_up(&psb->wait);
-	pohmelfs_put_inode(pi);
-
-	return err;
-}
-
-/*
- * Receive directory content from the server.
- * This should be only done for objects, which were not created locally,
- * and which were not synced previously.
- */
-static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi)
-{
-	struct inode *inode = &pi->vfs_inode;
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	long ret = psb->wait_on_page_timeout;
-	int err;
-
-	dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n",
-		__func__, pi->ino, pi->state, test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state));
-
-	if (test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state))
-		return 0;
-
-	if (!igrab(inode)) {
-		err = -ENOENT;
-		goto err_out_exit;
-	}
-
-	err = pohmelfs_meta_command(pi, NETFS_READDIR, NETFS_TRANS_SINGLE_DST,
-			pohmelfs_remote_sync_complete, pi, 0);
-	if (err)
-		goto err_out_exit;
-
-	pi->error = 0;
-	ret = wait_event_interruptible_timeout(psb->wait,
-			test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret);
-	dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error);
-	if (ret <= 0) {
-		err = ret;
-		if (!err)
-			err = -ETIMEDOUT;
-		goto err_out_exit;
-	}
-
-	if (pi->error)
-		return pi->error;
-
-	return 0;
-
-err_out_exit:
-	clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-
-	return err;
-}
-
-static int pohmelfs_dir_open(struct inode *inode, struct file *file)
-{
-	file->private_data = NULL;
-	return 0;
-}
-
-/*
- * VFS readdir callback. Syncs directory content from server if needed,
- * and provides direntry info to the userspace.
- */
-static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir)
-{
-	struct inode *inode = file->f_path.dentry->d_inode;
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	struct pohmelfs_name *n;
-	struct rb_node *rb_node;
-	int err = 0, mode;
-	u64 len;
-
-	dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n",
-			__func__, pi->ino, (u64)file->f_pos,
-			(unsigned long)file->private_data);
-#if 0
-	err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
-	if (err)
-		return err;
-#endif
-	err = pohmelfs_sync_remote_dir(pi);
-	if (err)
-		return err;
-
-	if (file->private_data && (file->private_data == (void *)(unsigned long)file->f_pos))
-		return 0;
-
-	mutex_lock(&pi->offset_lock);
-	n = pohmelfs_search_hash_unprecise(pi, (unsigned long)file->private_data);
-
-	while (n) {
-		mode = (n->mode >> 12) & 15;
-
-		dprintk("%s: offset: %llu, parent ino: %llu, name: '%s', len: %u, ino: %llu, "
-				"mode: %o/%o, fpos: %llu, hash: %08x.\n",
-				__func__, file->f_pos, pi->ino, n->data, n->len,
-				n->ino, n->mode, mode, file->f_pos, n->hash);
-
-		file->private_data = (void *)(unsigned long)n->hash;
-
-		len = n->len;
-		err = filldir(dirent, n->data, n->len, file->f_pos, n->ino, mode);
-
-		if (err < 0) {
-			dprintk("%s: err: %d.\n", __func__, err);
-			err = 0;
-			break;
-		}
-
-		file->f_pos += len;
-
-		rb_node = rb_next(&n->hash_node);
-
-		if (!rb_node || (rb_node == &n->hash_node)) {
-			file->private_data = (void *)(unsigned long)file->f_pos;
-			break;
-		}
-
-		n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
-	}
-	mutex_unlock(&pi->offset_lock);
-
-	return err;
-}
-
-static loff_t pohmelfs_dir_lseek(struct file *file, loff_t offset, int origin)
-{
-	file->f_pos = offset;
-	file->private_data = NULL;
-	return offset;
-}
-
-const struct file_operations pohmelfs_dir_fops = {
-	.open = pohmelfs_dir_open,
-	.read = generic_read_dir,
-	.llseek = pohmelfs_dir_lseek,
-	.readdir = pohmelfs_readdir,
-};
-
-/*
- * Lookup single object on server.
- */
-static int pohmelfs_lookup_single(struct pohmelfs_inode *parent,
-		struct qstr *str, u64 ino)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(parent->vfs_inode.i_sb);
-	long ret = msecs_to_jiffies(5000);
-	int err;
-
-	set_bit(NETFS_COMMAND_PENDING, &parent->state);
-	err = pohmelfs_meta_command_data(parent, parent->ino, NETFS_LOOKUP,
-			(char *)str->name, NETFS_TRANS_SINGLE_DST, NULL, NULL, ino);
-	if (err)
-		goto err_out_exit;
-
-	err = 0;
-	ret = wait_event_interruptible_timeout(psb->wait,
-			!test_bit(NETFS_COMMAND_PENDING, &parent->state), ret);
-	if (ret <= 0) {
-		err = ret;
-		if (!err)
-			err = -ETIMEDOUT;
-	}
-
-	if (err)
-		goto err_out_exit;
-
-	return 0;
-
-err_out_exit:
-	clear_bit(NETFS_COMMAND_PENDING, &parent->state);
-
-	printk("%s: failed: parent: %llu, ino: %llu, name: '%s', err: %d.\n",
-			__func__, parent->ino, ino, str->name, err);
-
-	return err;
-}
-
-/*
- * VFS lookup callback.
- * We first try to get inode number from local name cache, if we have one,
- * then inode can be found in inode cache. If there is no inode or no object in
- * local cache, try to lookup it on server. This only should be done for directories,
- * which were not created locally, otherwise remote server does not know about dir at all,
- * so no need to try to know that.
- */
-struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
-	struct pohmelfs_inode *parent = POHMELFS_I(dir);
-	struct pohmelfs_name *n;
-	struct inode *inode = NULL;
-	unsigned long ino = 0;
-	int err, lock_type = POHMELFS_READ_LOCK, need_lock = 1;
-	struct qstr str = dentry->d_name;
-
-	if ((nd->intent.open.flags & O_ACCMODE) != O_RDONLY)
-		lock_type = POHMELFS_WRITE_LOCK;
-
-	if (test_bit(NETFS_INODE_OWNED, &parent->state)) {
-		if (lock_type == parent->lock_type)
-			need_lock = 0;
-		if ((lock_type == POHMELFS_READ_LOCK) && (parent->lock_type == POHMELFS_WRITE_LOCK))
-			need_lock = 0;
-	}
-
-	if ((lock_type == POHMELFS_READ_LOCK) && !test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state))
-		need_lock = 1;
-
-	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-	mutex_lock(&parent->offset_lock);
-	n = pohmelfs_search_hash(parent, str.hash);
-	if (n)
-		ino = n->ino;
-	mutex_unlock(&parent->offset_lock);
-
-	dprintk("%s: start ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx, need_lock: %d.\n",
-			__func__, ino, inode, str.name, str.hash, parent->state, need_lock);
-
-	if (ino) {
-		inode = ilookup(dir->i_sb, ino);
-		if (inode)
-			goto out;
-	}
-
-	dprintk("%s: no inode dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n",
-			__func__, dir, parent->ino,
-			str.name, str.len, parent->state, ino);
-
-	if (!ino) {
-		if (!need_lock)
-			goto out;
-	}
-
-	err = pohmelfs_data_lock(parent, 0, ~0, lock_type);
-	if (err)
-		goto out;
-
-	err = pohmelfs_lookup_single(parent, &str, ino);
-	if (err)
-		goto out;
-
-	if (!ino) {
-		mutex_lock(&parent->offset_lock);
-		n = pohmelfs_search_hash(parent, str.hash);
-		if (n)
-			ino = n->ino;
-		mutex_unlock(&parent->offset_lock);
-	}
-
-	if (ino) {
-		inode = ilookup(dir->i_sb, ino);
-		dprintk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n",
-				__func__, ino, inode, str.name, str.hash);
-		if (!inode) {
-			dprintk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n",
-				__func__, ino, str.name, str.hash);
-			/* return NULL; */
-			return ERR_PTR(-EACCES);
-		}
-	} else {
-		printk("%s: No inode number : name: '%s', hash: %x.\n",
-			__func__, str.name, str.hash);
-	}
-out:
-	return d_splice_alias(inode, dentry);
-}
-
-/*
- * Create new object in local cache. Object will be synced to server
- * during writeback for given inode.
- */
-struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
-	struct pohmelfs_inode *parent, struct qstr *str, u64 start, umode_t mode)
-{
-	struct pohmelfs_inode *npi;
-	int err = -ENOMEM;
-	struct netfs_inode_info info;
-
-	dprintk("%s: name: '%s', mode: %ho, start: %llu.\n",
-			__func__, str->name, mode, start);
-
-	info.mode = mode;
-	info.ino = start;
-
-	if (!start)
-		info.ino = pohmelfs_new_ino(psb);
-
-	info.nlink = S_ISDIR(mode) ? 2 : 1;
-	info.uid = current_fsuid();
-	info.gid = current_fsgid();
-	info.size = 0;
-	info.blocksize = 512;
-	info.blocks = 0;
-	info.rdev = 0;
-	info.version = 0;
-
-	npi = pohmelfs_new_inode(psb, parent, str, &info, !!start);
-	if (IS_ERR(npi)) {
-		err = PTR_ERR(npi);
-		goto err_out_unlock;
-	}
-
-	return npi;
-
-err_out_unlock:
-	dprintk("%s: err: %d.\n", __func__, err);
-	return ERR_PTR(err);
-}
-
-/*
- * Create local object and bind it to dentry.
- */
-static int pohmelfs_create_entry(struct inode *dir, struct dentry *dentry,
-				 u64 start, umode_t mode)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
-	struct pohmelfs_inode *npi, *parent;
-	struct qstr str = dentry->d_name;
-	int err;
-
-	parent = POHMELFS_I(dir);
-
-	err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
-	if (err)
-		return err;
-
-	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-	npi = pohmelfs_create_entry_local(psb, parent, &str, start, mode);
-	if (IS_ERR(npi))
-		return PTR_ERR(npi);
-
-	d_instantiate(dentry, &npi->vfs_inode);
-
-	dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
-			__func__, parent->ino, npi->ino, dentry->d_name.name,
-			(signed)dir->i_nlink, (signed)npi->vfs_inode.i_nlink);
-
-	return 0;
-}
-
-/*
- * VFS create and mkdir callbacks.
- */
-static int pohmelfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
-		struct nameidata *nd)
-{
-	return pohmelfs_create_entry(dir, dentry, 0, mode);
-}
-
-static int pohmelfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
-{
-	int err;
-
-	inode_inc_link_count(dir);
-	err = pohmelfs_create_entry(dir, dentry, 0, mode | S_IFDIR);
-	if (err)
-		inode_dec_link_count(dir);
-
-	return err;
-}
-
-static int pohmelfs_remove_entry(struct inode *dir, struct dentry *dentry)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
-	struct inode *inode = dentry->d_inode;
-	struct pohmelfs_inode *parent = POHMELFS_I(dir), *pi = POHMELFS_I(inode);
-	struct pohmelfs_name *n;
-	int err = -ENOENT;
-	struct qstr str = dentry->d_name;
-
-	err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
-	if (err)
-		return err;
-
-	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-	dprintk("%s: dir_ino: %llu, inode: %llu, name: '%s', nlink: %d.\n",
-			__func__, parent->ino, pi->ino,
-			str.name, (signed)inode->i_nlink);
-
-	BUG_ON(!inode);
-
-	mutex_lock(&parent->offset_lock);
-	n = pohmelfs_search_hash(parent, str.hash);
-	if (n) {
-		pohmelfs_fix_offset(parent, n);
-		if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
-			pohmelfs_remove_child(pi, n);
-
-		pohmelfs_name_free(parent, n);
-		err = 0;
-	}
-	mutex_unlock(&parent->offset_lock);
-
-	if (!err) {
-		psb->avail_size += inode->i_size;
-
-		pohmelfs_inode_del_inode(psb, pi);
-
-		mark_inode_dirty(dir);
-
-		inode->i_ctime = dir->i_ctime;
-		if (inode->i_nlink)
-			inode_dec_link_count(inode);
-	}
-
-	return err;
-}
-
-/*
- * Unlink and rmdir VFS callbacks.
- */
-static int pohmelfs_unlink(struct inode *dir, struct dentry *dentry)
-{
-	return pohmelfs_remove_entry(dir, dentry);
-}
-
-static int pohmelfs_rmdir(struct inode *dir, struct dentry *dentry)
-{
-	int err;
-	struct inode *inode = dentry->d_inode;
-
-	dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
-			__func__, POHMELFS_I(dir)->ino, POHMELFS_I(inode)->ino,
-			dentry->d_name.name, (signed)dir->i_nlink, (signed)inode->i_nlink);
-
-	err = pohmelfs_remove_entry(dir, dentry);
-	if (!err) {
-		inode_dec_link_count(dir);
-		inode_dec_link_count(inode);
-	}
-
-	return err;
-}
-
-/*
- * Link creation is synchronous.
- * I'm lazy.
- * Earth is somewhat round.
- */
-static int pohmelfs_create_link(struct pohmelfs_inode *parent, struct qstr *obj,
-		struct pohmelfs_inode *target, struct qstr *tstr)
-{
-	struct super_block *sb = parent->vfs_inode.i_sb;
-	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-	struct netfs_cmd *cmd;
-	struct netfs_trans *t;
-	void *data;
-	int err, parent_len, target_len = 0, cur_len, path_size = 0;
-
-	err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
-	if (err)
-		return err;
-
-	err = sb->s_op->write_inode(&parent->vfs_inode, 0);
-	if (err)
-		goto err_out_exit;
-
-	if (tstr)
-		target_len = tstr->len;
-
-	parent_len = pohmelfs_path_length(parent);
-	if (target)
-		target_len += pohmelfs_path_length(target);
-
-	if (parent_len < 0) {
-		err = parent_len;
-		goto err_out_exit;
-	}
-
-	if (target_len < 0) {
-		err = target_len;
-		goto err_out_exit;
-	}
-
-	t = netfs_trans_alloc(psb, parent_len + target_len + obj->len + 2, 0, 0);
-	if (!t) {
-		err = -ENOMEM;
-		goto err_out_exit;
-	}
-	cur_len = netfs_trans_cur_len(t);
-
-	cmd = netfs_trans_current(t);
-	if (IS_ERR(cmd)) {
-		err = PTR_ERR(cmd);
-		goto err_out_free;
-	}
-
-	data = (void *)(cmd + 1);
-	cur_len -= sizeof(struct netfs_cmd);
-
-	err = pohmelfs_construct_path_string(parent, data, parent_len);
-	if (err > 0) {
-		/* Do not place null-byte before the slash */
-		path_size = err - 1;
-		cur_len -= path_size;
-
-		err = snprintf(data + path_size, cur_len, "/%s|", obj->name);
-
-		path_size += err;
-		cur_len -= err;
-
-		cmd->ext = path_size - 1; /* No | symbol */
-
-		if (target) {
-			err = pohmelfs_construct_path_string(target, data + path_size, target_len);
-			if (err > 0) {
-				path_size += err;
-				cur_len -= err;
-			}
-		}
-	}
-
-	if (err < 0)
-		goto err_out_free;
-
-	cmd->start = 0;
-
-	if (!target && tstr) {
-		if (tstr->len > cur_len - 1) {
-			err = -ENAMETOOLONG;
-			goto err_out_free;
-		}
-
-		err = snprintf(data + path_size, cur_len, "%s", tstr->name) + 1; /* 0-byte */
-		path_size += err;
-		cur_len -= err;
-		cmd->start = 1;
-	}
-
-	dprintk("%s: parent: %llu, obj: '%s', target_inode: %llu, target_str: '%s', full: '%s'.\n",
-			__func__, parent->ino, obj->name, (target) ? target->ino : 0, (tstr) ? tstr->name : NULL,
-			(char *)data);
-
-	cmd->cmd = NETFS_LINK;
-	cmd->size = path_size;
-	cmd->id = parent->ino;
-
-	netfs_convert_cmd(cmd);
-
-	netfs_trans_update(cmd, t, path_size);
-
-	err = netfs_trans_finish(t, psb);
-	if (err)
-		goto err_out_exit;
-
-	return 0;
-
-err_out_free:
-	t->result = err;
-	netfs_trans_put(t);
-err_out_exit:
-	return err;
-}
-
-/*
- *  VFS hard and soft link callbacks.
- */
-static int pohmelfs_link(struct dentry *old_dentry, struct inode *dir,
-	struct dentry *dentry)
-{
-	struct inode *inode = old_dentry->d_inode;
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	int err;
-	struct qstr str = dentry->d_name;
-
-	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-	err = inode->i_sb->s_op->write_inode(inode, 0);
-	if (err)
-		return err;
-
-	err = pohmelfs_create_link(POHMELFS_I(dir), &str, pi, NULL);
-	if (err)
-		return err;
-
-	return pohmelfs_create_entry(dir, dentry, pi->ino, inode->i_mode);
-}
-
-static int pohmelfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
-{
-	struct qstr sym_str;
-	struct qstr str = dentry->d_name;
-	struct inode *inode;
-	int err;
-
-	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
-
-	sym_str.name = symname;
-	sym_str.len = strlen(symname);
-
-	err = pohmelfs_create_link(POHMELFS_I(dir), &str, NULL, &sym_str);
-	if (err)
-		goto err_out_exit;
-
-	err = pohmelfs_create_entry(dir, dentry, 0, S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
-	if (err)
-		goto err_out_exit;
-
-	inode = dentry->d_inode;
-
-	err = page_symlink(inode, symname, sym_str.len + 1);
-	if (err)
-		goto err_out_put;
-
-	return 0;
-
-err_out_put:
-	iput(inode);
-err_out_exit:
-	return err;
-}
-
-static int pohmelfs_send_rename(struct pohmelfs_inode *pi, struct pohmelfs_inode *parent,
-		struct qstr *str)
-{
-	int path_len, err, total_len = 0, inode_len, parent_len;
-	char *path;
-	struct netfs_trans *t;
-	struct netfs_cmd *cmd;
-	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-
-	parent_len = pohmelfs_path_length(parent);
-	inode_len = pohmelfs_path_length(pi);
-
-	if (parent_len < 0 || inode_len < 0)
-		return -EINVAL;
-
-	path_len = parent_len + inode_len + str->len + 3;
-
-	t = netfs_trans_alloc(psb, path_len, 0, 0);
-	if (!t)
-		return -ENOMEM;
-
-	cmd = netfs_trans_current(t);
-	path = (char *)(cmd + 1);
-
-	err = pohmelfs_construct_path_string(pi, path, inode_len);
-	if (err < 0)
-		goto err_out_unlock;
-
-	cmd->ext = err;
-
-	path += err;
-	total_len += err;
-	path_len -= err;
-
-	*path = '|';
-	path++;
-	total_len++;
-	path_len--;
-
-	err = pohmelfs_construct_path_string(parent, path, parent_len);
-	if (err < 0)
-		goto err_out_unlock;
-
-	/*
-	 * Do not place a null-byte before the final slash and the name.
-	 */
-	err--;
-	path += err;
-	total_len += err;
-	path_len -= err;
-
-	err = snprintf(path, path_len - 1, "/%s", str->name);
-
-	total_len += err + 1; /* 0 symbol */
-	path_len -= err + 1;
-
-	cmd->cmd = NETFS_RENAME;
-	cmd->id = pi->ino;
-	cmd->start = parent->ino;
-	cmd->size = total_len;
-
-	netfs_convert_cmd(cmd);
-
-	netfs_trans_update(cmd, t, total_len);
-
-	return netfs_trans_finish(t, psb);
-
-err_out_unlock:
-	netfs_trans_free(t);
-	return err;
-}
-
-static int pohmelfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-			struct inode *new_dir, struct dentry *new_dentry)
-{
-	struct inode *inode = old_dentry->d_inode;
-	struct pohmelfs_inode *old_parent, *pi, *new_parent;
-	struct qstr str = new_dentry->d_name;
-	struct pohmelfs_name *n;
-	unsigned int old_hash;
-	int err = -ENOENT;
-
-	pi = POHMELFS_I(inode);
-	old_parent = POHMELFS_I(old_dir);
-
-	if (new_dir)
-		new_dir->i_sb->s_op->write_inode(new_dir, 0);
-
-	old_hash = jhash(old_dentry->d_name.name, old_dentry->d_name.len, 0);
-	str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
-
-	str.len = new_dentry->d_name.len;
-	str.name = new_dentry->d_name.name;
-	str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
-
-	if (new_dir) {
-		new_parent = POHMELFS_I(new_dir);
-		err = -ENOTEMPTY;
-
-		if (S_ISDIR(inode->i_mode) &&
-				new_parent->total_len <= 3)
-			goto err_out_exit;
-	} else {
-		new_parent = old_parent;
-	}
-
-	dprintk("%s: ino: %llu, parent: %llu, name: '%s' -> parent: %llu, name: '%s', i_size: %llu.\n",
-			__func__, pi->ino, old_parent->ino, old_dentry->d_name.name,
-			new_parent->ino, new_dentry->d_name.name, inode->i_size);
-
-	if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state) &&
-			test_bit(NETFS_INODE_OWNED, &pi->state)) {
-		err = pohmelfs_send_rename(pi, new_parent, &str);
-		if (err)
-			goto err_out_exit;
-	}
-
-	n = pohmelfs_name_alloc(str.len + 1);
-	if (!n)
-		goto err_out_exit;
-
-	mutex_lock(&new_parent->offset_lock);
-	n->ino = pi->ino;
-	n->mode = inode->i_mode;
-	n->len = str.len;
-	n->hash = str.hash;
-	sprintf(n->data, "%s", str.name);
-
-	err = pohmelfs_insert_name(new_parent, n);
-	mutex_unlock(&new_parent->offset_lock);
-
-	if (err)
-		goto err_out_exit;
-
-	mutex_lock(&old_parent->offset_lock);
-	n = pohmelfs_search_hash(old_parent, old_hash);
-	if (n)
-		pohmelfs_name_del(old_parent, n);
-	mutex_unlock(&old_parent->offset_lock);
-
-	mark_inode_dirty(inode);
-	mark_inode_dirty(&new_parent->vfs_inode);
-
-	WARN_ON_ONCE(list_empty(&inode->i_dentry));
-
-	return 0;
-
-err_out_exit:
-
-	clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-
-	return err;
-}
-
-/*
- * POHMELFS directory inode operations.
- */
-const struct inode_operations pohmelfs_dir_inode_ops = {
-	.link		= pohmelfs_link,
-	.symlink	= pohmelfs_symlink,
-	.unlink		= pohmelfs_unlink,
-	.mkdir		= pohmelfs_mkdir,
-	.rmdir		= pohmelfs_rmdir,
-	.create		= pohmelfs_create,
-	.lookup 	= pohmelfs_lookup,
-	.setattr	= pohmelfs_setattr,
-	.rename		= pohmelfs_rename,
-};
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
deleted file mode 100644
index 807e3f3..0000000
--- a/drivers/staging/pohmelfs/inode.c
+++ /dev/null
@@ -1,2055 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/backing-dev.h>
-#include <linux/crypto.h>
-#include <linux/fs.h>
-#include <linux/jhash.h>
-#include <linux/hash.h>
-#include <linux/ktime.h>
-#include <linux/mm.h>
-#include <linux/mount.h>
-#include <linux/pagemap.h>
-#include <linux/pagevec.h>
-#include <linux/parser.h>
-#include <linux/swap.h>
-#include <linux/slab.h>
-#include <linux/statfs.h>
-#include <linux/writeback.h>
-#include <linux/prefetch.h>
-
-#include "netfs.h"
-
-#define POHMELFS_MAGIC_NUM	0x504f482e
-
-static struct kmem_cache *pohmelfs_inode_cache;
-static atomic_t psb_bdi_num = ATOMIC_INIT(0);
-
-/*
- * Removes inode from all trees, drops local name cache and removes all queued
- * requests for object removal.
- */
-void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi)
-{
-	mutex_lock(&pi->offset_lock);
-	pohmelfs_free_names(pi);
-	mutex_unlock(&pi->offset_lock);
-
-	dprintk("%s: deleted stuff in ino: %llu.\n", __func__, pi->ino);
-}
-
-/*
- * Sync inode to server.
- * Returns zero in success and negative error value otherwise.
- * It will gather path to root directory into structures containing
- * creation mode, permissions and names, so that the whole path
- * to given inode could be created using only single network command.
- */
-int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans)
-{
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	int err = -ENOMEM, size;
-	struct netfs_cmd *cmd;
-	void *data;
-	int cur_len = netfs_trans_cur_len(trans);
-
-	if (unlikely(cur_len < 0))
-		return -ETOOSMALL;
-
-	cmd = netfs_trans_current(trans);
-	cur_len -= sizeof(struct netfs_cmd);
-
-	data = (void *)(cmd + 1);
-
-	err = pohmelfs_construct_path_string(pi, data, cur_len);
-	if (err < 0)
-		goto err_out_exit;
-
-	size = err;
-
-	cmd->start = i_size_read(inode);
-	cmd->cmd = NETFS_CREATE;
-	cmd->size = size;
-	cmd->id = pi->ino;
-	cmd->ext = inode->i_mode;
-
-	netfs_convert_cmd(cmd);
-
-	netfs_trans_update(cmd, trans, size);
-
-	return 0;
-
-err_out_exit:
-	printk("%s: completed ino: %llu, err: %d.\n", __func__, pi->ino, err);
-	return err;
-}
-
-static int pohmelfs_write_trans_complete(struct page **pages, unsigned int page_num,
-		void *private, int err)
-{
-	unsigned i;
-
-	dprintk("%s: pages: %lu-%lu, page_num: %u, err: %d.\n",
-			__func__, pages[0]->index, pages[page_num-1]->index,
-			page_num, err);
-
-	for (i = 0; i < page_num; i++) {
-		struct page *page = pages[i];
-
-		if (!page)
-			continue;
-
-		end_page_writeback(page);
-
-		if (err < 0) {
-			SetPageError(page);
-			set_page_dirty(page);
-		}
-
-		unlock_page(page);
-		page_cache_release(page);
-
-		/* dprintk("%s: %3u/%u: page: %p.\n", __func__, i, page_num, page); */
-	}
-	return err;
-}
-
-static int pohmelfs_inode_has_dirty_pages(struct address_space *mapping, pgoff_t index)
-{
-	int ret;
-	struct page *page;
-
-	rcu_read_lock();
-	ret = radix_tree_gang_lookup_tag(&mapping->page_tree,
-				(void **)&page, index, 1, PAGECACHE_TAG_DIRTY);
-	rcu_read_unlock();
-	return ret;
-}
-
-static int pohmelfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
-{
-	struct inode *inode = mapping->host;
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	int err = 0;
-	int done = 0;
-	int nr_pages;
-	pgoff_t index;
-	pgoff_t end;		/* Inclusive */
-	int scanned = 0;
-	int range_whole = 0;
-
-	if (wbc->range_cyclic) {
-		index = mapping->writeback_index; /* Start from prev offset */
-		end = -1;
-	} else {
-		index = wbc->range_start >> PAGE_CACHE_SHIFT;
-		end = wbc->range_end >> PAGE_CACHE_SHIFT;
-		if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
-			range_whole = 1;
-		scanned = 1;
-	}
-retry:
-	while (!done && (index <= end)) {
-		unsigned int i = min(end - index, (pgoff_t)psb->trans_max_pages);
-		int path_len;
-		struct netfs_trans *trans;
-
-		err = pohmelfs_inode_has_dirty_pages(mapping, index);
-		if (!err)
-			break;
-
-		err = pohmelfs_path_length(pi);
-		if (err < 0)
-			break;
-
-		path_len = err;
-
-		if (path_len <= 2) {
-			err = -ENOENT;
-			break;
-		}
-
-		trans = netfs_trans_alloc(psb, path_len, 0, i);
-		if (!trans) {
-			err = -ENOMEM;
-			break;
-		}
-		trans->complete = &pohmelfs_write_trans_complete;
-
-		trans->page_num = nr_pages = find_get_pages_tag(mapping, &index,
-				PAGECACHE_TAG_DIRTY, trans->page_num,
-				trans->pages);
-
-		dprintk("%s: t: %p, nr_pages: %u, end: %lu, index: %lu, max: %u.\n",
-				__func__, trans, nr_pages, end, index, trans->page_num);
-
-		if (!nr_pages)
-			goto err_out_reset;
-
-		err = pohmelfs_write_inode_create(inode, trans);
-		if (err)
-			goto err_out_reset;
-
-		err = 0;
-		scanned = 1;
-
-		for (i = 0; i < trans->page_num; i++) {
-			struct page *page = trans->pages[i];
-
-			lock_page(page);
-
-			if (unlikely(page->mapping != mapping))
-				goto out_continue;
-
-			if (!wbc->range_cyclic && page->index > end) {
-				done = 1;
-				goto out_continue;
-			}
-
-			if (wbc->sync_mode != WB_SYNC_NONE)
-				wait_on_page_writeback(page);
-
-			if (PageWriteback(page) ||
-			    !clear_page_dirty_for_io(page)) {
-				dprintk("%s: not clear for io page: %p, writeback: %d.\n",
-						__func__, page, PageWriteback(page));
-				goto out_continue;
-			}
-
-			set_page_writeback(page);
-
-			trans->attached_size += page_private(page);
-			trans->attached_pages++;
-#if 0
-			dprintk("%s: %u/%u added trans: %p, gen: %u, page: %p, [High: %d], size: %lu, idx: %lu.\n",
-					__func__, i, trans->page_num, trans, trans->gen, page,
-					!!PageHighMem(page), page_private(page), page->index);
-#endif
-			wbc->nr_to_write--;
-
-			if (wbc->nr_to_write <= 0)
-				done = 1;
-
-			continue;
-out_continue:
-			unlock_page(page);
-			trans->pages[i] = NULL;
-		}
-
-		err = netfs_trans_finish(trans, psb);
-		if (err)
-			break;
-
-		continue;
-
-err_out_reset:
-		trans->result = err;
-		netfs_trans_reset(trans);
-		netfs_trans_put(trans);
-		break;
-	}
-
-	if (!scanned && !done) {
-		/*
-		 * We hit the last page and there is more work to be done: wrap
-		 * back to the start of the file
-		 */
-		scanned = 1;
-		index = 0;
-		goto retry;
-	}
-
-	if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
-		mapping->writeback_index = index;
-
-	return err;
-}
-
-/*
- * Inode writeback creation completion callback.
- * Only invoked for just created inodes, which do not have pages attached,
- * like dirs and empty files.
- */
-static int pohmelfs_write_inode_complete(struct page **pages, unsigned int page_num,
-		void *private, int err)
-{
-	struct inode *inode = private;
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-
-	if (inode) {
-		if (err) {
-			mark_inode_dirty(inode);
-			clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-		} else {
-			set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-		}
-
-		pohmelfs_put_inode(pi);
-	}
-
-	return err;
-}
-
-int pohmelfs_write_create_inode(struct pohmelfs_inode *pi)
-{
-	struct netfs_trans *t;
-	struct inode *inode = &pi->vfs_inode;
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	int err;
-
-	if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
-		return 0;
-
-	dprintk("%s: started ino: %llu.\n", __func__, pi->ino);
-
-	err = pohmelfs_path_length(pi);
-	if (err < 0)
-		goto err_out_exit;
-
-	t = netfs_trans_alloc(psb, err + 1, 0, 0);
-	if (!t) {
-		err = -ENOMEM;
-		goto err_out_exit;
-	}
-	t->complete = pohmelfs_write_inode_complete;
-	t->private = igrab(inode);
-	if (!t->private) {
-		err = -ENOENT;
-		goto err_out_put;
-	}
-
-	err = pohmelfs_write_inode_create(inode, t);
-	if (err)
-		goto err_out_put;
-
-	netfs_trans_finish(t, POHMELFS_SB(inode->i_sb));
-
-	return 0;
-
-err_out_put:
-	t->result = err;
-	netfs_trans_put(t);
-err_out_exit:
-	return err;
-}
-
-/*
- * Sync all not-yet-created children in given directory to the server.
- */
-static int pohmelfs_write_inode_create_children(struct inode *inode)
-{
-	struct pohmelfs_inode *parent = POHMELFS_I(inode);
-	struct super_block *sb = inode->i_sb;
-	struct pohmelfs_name *n;
-
-	while (!list_empty(&parent->sync_create_list)) {
-		n = NULL;
-		mutex_lock(&parent->offset_lock);
-		if (!list_empty(&parent->sync_create_list)) {
-			n = list_first_entry(&parent->sync_create_list,
-				struct pohmelfs_name, sync_create_entry);
-			list_del_init(&n->sync_create_entry);
-		}
-		mutex_unlock(&parent->offset_lock);
-
-		if (!n)
-			break;
-
-		inode = ilookup(sb, n->ino);
-
-		dprintk("%s: parent: %llu, ino: %llu, inode: %p.\n",
-				__func__, parent->ino, n->ino, inode);
-
-		if (inode && (inode->i_state & I_DIRTY)) {
-			struct pohmelfs_inode *pi = POHMELFS_I(inode);
-			pohmelfs_write_create_inode(pi);
-			/* pohmelfs_meta_command(pi, NETFS_INODE_INFO, 0, NULL, NULL, 0); */
-			iput(inode);
-		}
-	}
-
-	return 0;
-}
-
-/*
- * Removes given child from given inode on server.
- */
-int pohmelfs_remove_child(struct pohmelfs_inode *pi, struct pohmelfs_name *n)
-{
-	return pohmelfs_meta_command_data(pi, pi->ino, NETFS_REMOVE, NULL, 0, NULL, NULL, 0);
-}
-
-/*
- * Writeback for given inode.
- */
-static int pohmelfs_write_inode(struct inode *inode,
-				struct writeback_control *wbc)
-{
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-
-	pohmelfs_write_create_inode(pi);
-	pohmelfs_write_inode_create_children(inode);
-
-	return 0;
-}
-
-/*
- * It is not exported, sorry...
- */
-static inline wait_queue_head_t *page_waitqueue(struct page *page)
-{
-	const struct zone *zone = page_zone(page);
-
-	return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
-}
-
-static int pohmelfs_wait_on_page_locked(struct page *page)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(page->mapping->host->i_sb);
-	long ret = psb->wait_on_page_timeout;
-	DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
-	int err = 0;
-
-	if (!PageLocked(page))
-		return 0;
-
-	for (;;) {
-		prepare_to_wait(page_waitqueue(page),
-				&wait.wait, TASK_INTERRUPTIBLE);
-
-		dprintk("%s: page: %p, locked: %d, uptodate: %d, error: %d, flags: %lx.\n",
-				__func__, page, PageLocked(page), PageUptodate(page),
-				PageError(page), page->flags);
-
-		if (!PageLocked(page))
-			break;
-
-		if (!signal_pending(current)) {
-			ret = schedule_timeout(ret);
-			if (!ret)
-				break;
-			continue;
-		}
-		ret = -ERESTARTSYS;
-		break;
-	}
-	finish_wait(page_waitqueue(page), &wait.wait);
-
-	if (!ret)
-		err = -ETIMEDOUT;
-
-
-	if (!err)
-		SetPageUptodate(page);
-
-	if (err)
-		printk("%s: page: %p, uptodate: %d, locked: %d, err: %d.\n",
-			__func__, page, PageUptodate(page), PageLocked(page), err);
-
-	return err;
-}
-
-static int pohmelfs_read_page_complete(struct page **pages, unsigned int page_num,
-		void *private, int err)
-{
-	struct page *page = private;
-
-	if (PageChecked(page))
-		return err;
-
-	if (err < 0) {
-		dprintk("%s: page: %p, err: %d.\n", __func__, page, err);
-		SetPageError(page);
-	}
-
-	unlock_page(page);
-
-	return err;
-}
-
-/*
- * Read a page from remote server.
- * Function will wait until page is unlocked.
- */
-static int pohmelfs_readpage(struct file *file, struct page *page)
-{
-	struct inode *inode = page->mapping->host;
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	struct netfs_trans *t;
-	struct netfs_cmd *cmd;
-	int err, path_len;
-	void *data;
-	u64 isize;
-
-	err = pohmelfs_data_lock(pi, page->index << PAGE_CACHE_SHIFT,
-			PAGE_SIZE, POHMELFS_READ_LOCK);
-	if (err)
-		goto err_out_exit;
-
-	isize = i_size_read(inode);
-	if (isize <= page->index << PAGE_CACHE_SHIFT) {
-		SetPageUptodate(page);
-		unlock_page(page);
-		return 0;
-	}
-
-	path_len = pohmelfs_path_length(pi);
-	if (path_len < 0) {
-		err = path_len;
-		goto err_out_exit;
-	}
-
-	t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
-	if (!t) {
-		err = -ENOMEM;
-		goto err_out_exit;
-	}
-
-	t->complete = pohmelfs_read_page_complete;
-	t->private = page;
-
-	cmd = netfs_trans_current(t);
-	data = (void *)(cmd + 1);
-
-	err = pohmelfs_construct_path_string(pi, data, path_len);
-	if (err < 0)
-		goto err_out_free;
-
-	path_len = err;
-
-	cmd->id = pi->ino;
-	cmd->start = page->index;
-	cmd->start <<= PAGE_CACHE_SHIFT;
-	cmd->size = PAGE_CACHE_SIZE + path_len;
-	cmd->cmd = NETFS_READ_PAGE;
-	cmd->ext = path_len;
-
-	dprintk("%s: path: '%s', page: %p, ino: %llu, start: %llu, size: %lu.\n",
-			__func__, (char *)data, page, pi->ino, cmd->start, PAGE_CACHE_SIZE);
-
-	netfs_convert_cmd(cmd);
-	netfs_trans_update(cmd, t, path_len);
-
-	err = netfs_trans_finish(t, psb);
-	if (err)
-		goto err_out_return;
-
-	return pohmelfs_wait_on_page_locked(page);
-
-err_out_free:
-	t->result = err;
-	netfs_trans_put(t);
-err_out_exit:
-	SetPageError(page);
-	if (PageLocked(page))
-		unlock_page(page);
-err_out_return:
-	printk("%s: page: %p, start: %lu, size: %lu, err: %d.\n",
-		__func__, page, page->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE, err);
-
-	return err;
-}
-
-/*
- * Write begin/end magic.
- * Allocates a page and writes inode if it was not synced to server before.
- */
-static int pohmelfs_write_begin(struct file *file, struct address_space *mapping,
-		loff_t pos, unsigned len, unsigned flags,
-		struct page **pagep, void **fsdata)
-{
-	struct inode *inode = mapping->host;
-	struct page *page;
-	pgoff_t index;
-	unsigned start, end;
-	int err;
-
-	*pagep = NULL;
-
-	index = pos >> PAGE_CACHE_SHIFT;
-	start = pos & (PAGE_CACHE_SIZE - 1);
-	end = start + len;
-
-	page = grab_cache_page(mapping, index);
-#if 0
-	dprintk("%s: page: %p pos: %llu, len: %u, index: %lu, start: %u, end: %u, uptodate: %d.\n",
-			__func__, page,	pos, len, index, start, end, PageUptodate(page));
-#endif
-	if (!page) {
-		err = -ENOMEM;
-		goto err_out_exit;
-	}
-
-	while (!PageUptodate(page)) {
-		if (start && test_bit(NETFS_INODE_REMOTE_SYNCED, &POHMELFS_I(inode)->state)) {
-			err = pohmelfs_readpage(file, page);
-			if (err)
-				goto err_out_exit;
-
-			lock_page(page);
-			continue;
-		}
-
-		if (len != PAGE_CACHE_SIZE) {
-			void *kaddr = kmap_atomic(page, KM_USER0);
-
-			memset(kaddr + start, 0, PAGE_CACHE_SIZE - start);
-			flush_dcache_page(page);
-			kunmap_atomic(kaddr, KM_USER0);
-		}
-		SetPageUptodate(page);
-	}
-
-	set_page_private(page, end);
-
-	*pagep = page;
-
-	return 0;
-
-err_out_exit:
-	page_cache_release(page);
-	*pagep = NULL;
-
-	return err;
-}
-
-static int pohmelfs_write_end(struct file *file, struct address_space *mapping,
-			loff_t pos, unsigned len, unsigned copied,
-			struct page *page, void *fsdata)
-{
-	struct inode *inode = mapping->host;
-
-	if (copied != len) {
-		unsigned from = pos & (PAGE_CACHE_SIZE - 1);
-		void *kaddr = kmap_atomic(page, KM_USER0);
-
-		memset(kaddr + from + copied, 0, len - copied);
-		flush_dcache_page(page);
-		kunmap_atomic(kaddr, KM_USER0);
-	}
-
-	SetPageUptodate(page);
-	set_page_dirty(page);
-#if 0
-	dprintk("%s: page: %p [U: %d, D: %d, L: %d], pos: %llu, len: %u, copied: %u.\n",
-			__func__, page,
-			PageUptodate(page), PageDirty(page), PageLocked(page),
-			pos, len, copied);
-#endif
-	flush_dcache_page(page);
-
-	unlock_page(page);
-	page_cache_release(page);
-
-	if (pos + copied > inode->i_size) {
-		struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-
-		psb->avail_size -= pos + copied - inode->i_size;
-
-		i_size_write(inode, pos + copied);
-	}
-
-	return copied;
-}
-
-static int pohmelfs_readpages_trans_complete(struct page **__pages, unsigned int page_num,
-		void *private, int err)
-{
-	struct pohmelfs_inode *pi = private;
-	unsigned int i, num;
-	struct page **pages, *page = (struct page *)__pages;
-	loff_t index = page->index;
-
-	pages = kzalloc(sizeof(void *) * page_num, GFP_NOIO);
-	if (!pages)
-		return -ENOMEM;
-
-	num = find_get_pages_contig(pi->vfs_inode.i_mapping, index, page_num, pages);
-	if (num <= 0) {
-		err = num;
-		goto err_out_free;
-	}
-
-	for (i = 0; i < num; ++i) {
-		page = pages[i];
-
-		if (err)
-			printk("%s: %u/%u: page: %p, index: %lu, uptodate: %d, locked: %d, err: %d.\n",
-				__func__, i, num, page, page->index,
-				PageUptodate(page), PageLocked(page), err);
-
-		if (!PageChecked(page)) {
-			if (err < 0)
-				SetPageError(page);
-			unlock_page(page);
-		}
-		page_cache_release(page);
-		page_cache_release(page);
-	}
-
-err_out_free:
-	kfree(pages);
-	return err;
-}
-
-static int pohmelfs_send_readpages(struct pohmelfs_inode *pi, struct page *first, unsigned int num)
-{
-	struct netfs_trans *t;
-	struct netfs_cmd *cmd;
-	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-	int err, path_len;
-	void *data;
-
-	err = pohmelfs_data_lock(pi, first->index << PAGE_CACHE_SHIFT,
-			num * PAGE_SIZE, POHMELFS_READ_LOCK);
-	if (err)
-		goto err_out_exit;
-
-	path_len = pohmelfs_path_length(pi);
-	if (path_len < 0) {
-		err = path_len;
-		goto err_out_exit;
-	}
-
-	t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
-	if (!t) {
-		err = -ENOMEM;
-		goto err_out_exit;
-	}
-
-	cmd = netfs_trans_current(t);
-	data = (void *)(cmd + 1);
-
-	t->complete = pohmelfs_readpages_trans_complete;
-	t->private = pi;
-	t->page_num = num;
-	t->pages = (struct page **)first;
-
-	err = pohmelfs_construct_path_string(pi, data, path_len);
-	if (err < 0)
-		goto err_out_put;
-
-	path_len = err;
-
-	cmd->cmd = NETFS_READ_PAGES;
-	cmd->start = first->index;
-	cmd->start <<= PAGE_CACHE_SHIFT;
-	cmd->size = (num << 8 | PAGE_CACHE_SHIFT);
-	cmd->id = pi->ino;
-	cmd->ext = path_len;
-
-	dprintk("%s: t: %p, gen: %u, path: '%s', path_len: %u, "
-			"start: %lu, num: %u.\n",
-			__func__, t, t->gen, (char *)data, path_len,
-			first->index, num);
-
-	netfs_convert_cmd(cmd);
-	netfs_trans_update(cmd, t, path_len);
-
-	return netfs_trans_finish(t, psb);
-
-err_out_put:
-	netfs_trans_free(t);
-err_out_exit:
-	pohmelfs_readpages_trans_complete((struct page **)first, num, pi, err);
-	return err;
-}
-
-#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
-
-static int pohmelfs_readpages(struct file *file, struct address_space *mapping,
-			struct list_head *pages, unsigned nr_pages)
-{
-	unsigned int page_idx, num = 0;
-	struct page *page = NULL, *first = NULL;
-
-	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
-		page = list_to_page(pages);
-
-		prefetchw(&page->flags);
-		list_del(&page->lru);
-
-		if (!add_to_page_cache_lru(page, mapping,
-					page->index, GFP_KERNEL)) {
-
-			if (!num) {
-				num = 1;
-				first = page;
-				continue;
-			}
-
-			dprintk("%s: added to lru page: %p, page_index: %lu, first_index: %lu.\n",
-					__func__, page, page->index, first->index);
-
-			if (unlikely(first->index + num != page->index) || (num > 500)) {
-				pohmelfs_send_readpages(POHMELFS_I(mapping->host),
-						first, num);
-				first = page;
-				num = 0;
-			}
-
-			num++;
-		}
-	}
-	pohmelfs_send_readpages(POHMELFS_I(mapping->host), first, num);
-
-	/*
-	 * This will be sync read, so when last page is processed,
-	 * all previous are alerady unlocked and ready to be used.
-	 */
-	return 0;
-}
-
-/*
- * Small address space operations for POHMELFS.
- */
-const struct address_space_operations pohmelfs_aops = {
-	.readpage		= pohmelfs_readpage,
-	.readpages		= pohmelfs_readpages,
-	.writepages		= pohmelfs_writepages,
-	.write_begin		= pohmelfs_write_begin,
-	.write_end		= pohmelfs_write_end,
-	.set_page_dirty 	= __set_page_dirty_nobuffers,
-};
-
-static void pohmelfs_i_callback(struct rcu_head *head)
-{
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	kmem_cache_free(pohmelfs_inode_cache, POHMELFS_I(inode));
-}
-
-/*
- * ->destroy_inode() callback. Deletes inode from the caches
- *  and frees private data.
- */
-static void pohmelfs_destroy_inode(struct inode *inode)
-{
-	struct super_block *sb = inode->i_sb;
-	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-
-	/* pohmelfs_data_unlock(pi, 0, inode->i_size, POHMELFS_READ_LOCK); */
-
-	pohmelfs_inode_del_inode(psb, pi);
-
-	dprintk("%s: pi: %p, inode: %p, ino: %llu.\n",
-		__func__, pi, &pi->vfs_inode, pi->ino);
-	atomic_long_dec(&psb->total_inodes);
-	call_rcu(&inode->i_rcu, pohmelfs_i_callback);
-}
-
-/*
- * ->alloc_inode() callback. Allocates inode and initializes private data.
- */
-static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
-{
-	struct pohmelfs_inode *pi;
-
-	pi = kmem_cache_alloc(pohmelfs_inode_cache, GFP_NOIO);
-	if (!pi)
-		return NULL;
-
-	pi->hash_root = RB_ROOT;
-	mutex_init(&pi->offset_lock);
-
-	INIT_LIST_HEAD(&pi->sync_create_list);
-
-	INIT_LIST_HEAD(&pi->inode_entry);
-
-	pi->lock_type = 0;
-	pi->state = 0;
-	pi->total_len = 0;
-	pi->drop_count = 0;
-
-	dprintk("%s: pi: %p, inode: %p.\n", __func__, pi, &pi->vfs_inode);
-
-	atomic_long_inc(&POHMELFS_SB(sb)->total_inodes);
-
-	return &pi->vfs_inode;
-}
-
-/*
- * We want fsync() to work on POHMELFS.
- */
-static int pohmelfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
-{
-	struct inode *inode = file->f_mapping->host;
-	int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
-	if (!err) {
-		mutex_lock(&inode->i_mutex);
-		err = sync_inode_metadata(inode, 1);
-		mutex_unlock(&inode->i_mutex);
-	}
-	return err;
-}
-
-ssize_t pohmelfs_write(struct file *file, const char __user *buf,
-		size_t len, loff_t *ppos)
-{
-	struct address_space *mapping = file->f_mapping;
-	struct inode *inode = mapping->host;
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
-	struct kiocb kiocb;
-	ssize_t ret;
-	loff_t pos = *ppos;
-
-	init_sync_kiocb(&kiocb, file);
-	kiocb.ki_pos = pos;
-	kiocb.ki_left = len;
-
-	dprintk("%s: len: %zu, pos: %llu.\n", __func__, len, pos);
-
-	mutex_lock(&inode->i_mutex);
-	ret = pohmelfs_data_lock(pi, pos, len, POHMELFS_WRITE_LOCK);
-	if (ret)
-		goto err_out_unlock;
-
-	ret = __generic_file_aio_write(&kiocb, &iov, 1, &kiocb.ki_pos);
-	*ppos = kiocb.ki_pos;
-
-	mutex_unlock(&inode->i_mutex);
-	WARN_ON(ret < 0);
-
-	if (ret > 0) {
-		ssize_t err;
-
-		err = generic_write_sync(file, pos, ret);
-		if (err < 0)
-			ret = err;
-		WARN_ON(ret < 0);
-	}
-
-	return ret;
-
-err_out_unlock:
-	mutex_unlock(&inode->i_mutex);
-	return ret;
-}
-
-static const struct file_operations pohmelfs_file_ops = {
-	.open		= generic_file_open,
-	.fsync		= pohmelfs_fsync,
-
-	.llseek		= generic_file_llseek,
-
-	.read		= do_sync_read,
-	.aio_read	= generic_file_aio_read,
-
-	.mmap		= generic_file_mmap,
-
-	.splice_read	= generic_file_splice_read,
-	.splice_write	= generic_file_splice_write,
-
-	.write		= pohmelfs_write,
-	.aio_write	= generic_file_aio_write,
-};
-
-const struct inode_operations pohmelfs_symlink_inode_operations = {
-	.readlink	= generic_readlink,
-	.follow_link	= page_follow_link_light,
-	.put_link	= page_put_link,
-};
-
-int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
-{
-	int err;
-
-	err = inode_change_ok(inode, attr);
-	if (err) {
-		dprintk("%s: ino: %llu, inode changes are not allowed.\n", __func__, POHMELFS_I(inode)->ino);
-		goto err_out_exit;
-	}
-
-	if ((attr->ia_valid & ATTR_SIZE) &&
-	    attr->ia_size != i_size_read(inode)) {
-		err = vmtruncate(inode, attr->ia_size);
-		if (err) {
-			dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
-			goto err_out_exit;
-		}
-	}
-
-	setattr_copy(inode, attr);
-	mark_inode_dirty(inode);
-
-	dprintk("%s: ino: %llu, mode: %o -> %o, uid: %u -> %u, gid: %u -> %u, size: %llu -> %llu.\n",
-			__func__, POHMELFS_I(inode)->ino, inode->i_mode, attr->ia_mode,
-			inode->i_uid, attr->ia_uid, inode->i_gid, attr->ia_gid, inode->i_size, attr->ia_size);
-
-	return 0;
-
-err_out_exit:
-	return err;
-}
-
-int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr)
-{
-	struct inode *inode = dentry->d_inode;
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	int err;
-
-	err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
-	if (err)
-		goto err_out_exit;
-
-	err = security_inode_setattr(dentry, attr);
-	if (err)
-		goto err_out_exit;
-
-	err = pohmelfs_setattr_raw(inode, attr);
-	if (err)
-		goto err_out_exit;
-
-	return 0;
-
-err_out_exit:
-	return err;
-}
-
-static int pohmelfs_send_xattr_req(struct pohmelfs_inode *pi, u64 id, u64 start,
-		const char *name, const void *value, size_t attrsize, int command)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-	int err, path_len, namelen = strlen(name) + 1; /* 0-byte */
-	struct netfs_trans *t;
-	struct netfs_cmd *cmd;
-	void *data;
-
-	dprintk("%s: id: %llu, start: %llu, name: '%s', attrsize: %zu, cmd: %d.\n",
-			__func__, id, start, name, attrsize, command);
-
-	path_len = pohmelfs_path_length(pi);
-	if (path_len < 0) {
-		err = path_len;
-		goto err_out_exit;
-	}
-
-	t = netfs_trans_alloc(psb, namelen + path_len + attrsize, 0, 0);
-	if (!t) {
-		err = -ENOMEM;
-		goto err_out_exit;
-	}
-
-	cmd = netfs_trans_current(t);
-	data = cmd + 1;
-
-	path_len = pohmelfs_construct_path_string(pi, data, path_len);
-	if (path_len < 0) {
-		err = path_len;
-		goto err_out_put;
-	}
-	data += path_len;
-
-	/*
-	 * 'name' is a NUL-terminated string already and
-	 * 'namelen' includes 0-byte.
-	 */
-	memcpy(data, name, namelen);
-	data += namelen;
-
-	memcpy(data, value, attrsize);
-
-	cmd->cmd = command;
-	cmd->id = id;
-	cmd->start = start;
-	cmd->size = attrsize + namelen + path_len;
-	cmd->ext = path_len;
-	cmd->csize = 0;
-	cmd->cpad = 0;
-
-	netfs_convert_cmd(cmd);
-	netfs_trans_update(cmd, t, namelen + path_len + attrsize);
-
-	return netfs_trans_finish(t, psb);
-
-err_out_put:
-	t->result = err;
-	netfs_trans_put(t);
-err_out_exit:
-	return err;
-}
-
-static int pohmelfs_setxattr(struct dentry *dentry, const char *name,
-		const void *value, size_t attrsize, int flags)
-{
-	struct inode *inode = dentry->d_inode;
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-
-	if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
-		return -EOPNOTSUPP;
-
-	return pohmelfs_send_xattr_req(pi, flags, attrsize, name,
-			value, attrsize, NETFS_XATTR_SET);
-}
-
-static ssize_t pohmelfs_getxattr(struct dentry *dentry, const char *name,
-		void *value, size_t attrsize)
-{
-	struct inode *inode = dentry->d_inode;
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	struct pohmelfs_mcache *m;
-	int err;
-	long timeout = psb->mcache_timeout;
-
-	if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
-		return -EOPNOTSUPP;
-
-	m = pohmelfs_mcache_alloc(psb, 0, attrsize, value);
-	if (IS_ERR(m))
-		return PTR_ERR(m);
-
-	dprintk("%s: ino: %llu, name: '%s', size: %zu.\n",
-			__func__, pi->ino, name, attrsize);
-
-	err = pohmelfs_send_xattr_req(pi, m->gen, attrsize, name, value, 0, NETFS_XATTR_GET);
-	if (err)
-		goto err_out_put;
-
-	do {
-		err = wait_for_completion_timeout(&m->complete, timeout);
-		if (err) {
-			err = m->err;
-			break;
-		}
-
-		/*
-		 * This loop is a bit ugly, since it waits until reference counter
-		 * hits 1 and then puts the object here. Main goal is to prevent race with
-		 * the network thread, when it can start processing the given request, i.e.
-		 * increase its reference counter but yet not complete it, while
-		 * we will exit from ->getxattr() with timeout, and although request
-		 * will not be freed (its reference counter was increased by network
-		 * thread), data pointer provided by user may be released, so we will
-		 * overwrite an already freed area in the network thread.
-		 *
-		 * Now after timeout we remove request from the cache, so it can not be
-		 * found by network thread, and wait for its reference counter to hit 1,
-		 * i.e. if network thread already started to process this request, we wait
-		 * for it to finish, and then free object locally. If reference counter is
-		 * already 1, i.e. request is not used by anyone else, we can free it without
-		 * problem.
-		 */
-		err = -ETIMEDOUT;
-		timeout = HZ;
-
-		pohmelfs_mcache_remove_locked(psb, m);
-	} while (atomic_read(&m->refcnt) != 1);
-
-	pohmelfs_mcache_put(psb, m);
-
-	dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
-
-	return err;
-
-err_out_put:
-	pohmelfs_mcache_put(psb, m);
-	return err;
-}
-
-static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-{
-	struct inode *inode = dentry->d_inode;
-#if 0
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-	int err;
-
-	err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
-	if (err)
-		return err;
-	dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n",
-			__func__, pi->ino, inode->i_mode, inode->i_uid,
-			inode->i_gid, inode->i_size);
-#endif
-
-	generic_fillattr(inode, stat);
-	return 0;
-}
-
-const struct inode_operations pohmelfs_file_inode_operations = {
-	.setattr	= pohmelfs_setattr,
-	.getattr	= pohmelfs_getattr,
-	.setxattr	= pohmelfs_setxattr,
-	.getxattr	= pohmelfs_getxattr,
-};
-
-/*
- * Fill inode data: mode, size, operation callbacks and so on...
- */
-void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info)
-{
-	inode->i_mode = info->mode;
-	set_nlink(inode, info->nlink);
-	inode->i_uid = info->uid;
-	inode->i_gid = info->gid;
-	inode->i_blocks = info->blocks;
-	inode->i_rdev = info->rdev;
-	inode->i_size = info->size;
-	inode->i_version = info->version;
-	inode->i_blkbits = ffs(info->blocksize);
-
-	dprintk("%s: inode: %p, num: %lu/%llu inode is regular: %d, dir: %d, link: %d, mode: %o, size: %llu.\n",
-			__func__, inode, inode->i_ino, info->ino,
-			S_ISREG(inode->i_mode), S_ISDIR(inode->i_mode),
-			S_ISLNK(inode->i_mode), inode->i_mode, inode->i_size);
-
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
-
-	/*
-	 * i_mapping is a pointer to i_data during inode initialization.
-	 */
-	inode->i_data.a_ops = &pohmelfs_aops;
-
-	if (S_ISREG(inode->i_mode)) {
-		inode->i_fop = &pohmelfs_file_ops;
-		inode->i_op = &pohmelfs_file_inode_operations;
-	} else if (S_ISDIR(inode->i_mode)) {
-		inode->i_fop = &pohmelfs_dir_fops;
-		inode->i_op = &pohmelfs_dir_inode_ops;
-	} else if (S_ISLNK(inode->i_mode)) {
-		inode->i_op = &pohmelfs_symlink_inode_operations;
-		inode->i_fop = &pohmelfs_file_ops;
-	} else {
-		inode->i_fop = &generic_ro_fops;
-	}
-}
-
-static int pohmelfs_drop_inode(struct inode *inode)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	struct pohmelfs_inode *pi = POHMELFS_I(inode);
-
-	spin_lock(&psb->ino_lock);
-	list_del_init(&pi->inode_entry);
-	spin_unlock(&psb->ino_lock);
-
-	return generic_drop_inode(inode);
-}
-
-static struct pohmelfs_inode *pohmelfs_get_inode_from_list(struct pohmelfs_sb *psb,
-		struct list_head *head, unsigned int *count)
-{
-	struct pohmelfs_inode *pi = NULL;
-
-	spin_lock(&psb->ino_lock);
-	if (!list_empty(head)) {
-		pi = list_entry(head->next, struct pohmelfs_inode,
-					inode_entry);
-		list_del_init(&pi->inode_entry);
-		*count = pi->drop_count;
-		pi->drop_count = 0;
-	}
-	spin_unlock(&psb->ino_lock);
-
-	return pi;
-}
-
-static void pohmelfs_flush_transactions(struct pohmelfs_sb *psb)
-{
-	struct pohmelfs_config *c;
-
-	mutex_lock(&psb->state_lock);
-	list_for_each_entry(c, &psb->state_list, config_entry) {
-		pohmelfs_state_flush_transactions(&c->state);
-	}
-	mutex_unlock(&psb->state_lock);
-}
-
-/*
- * ->put_super() callback. Invoked before superblock is destroyed,
- *  so it has to clean all private data.
- */
-static void pohmelfs_put_super(struct super_block *sb)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-	struct pohmelfs_inode *pi;
-	unsigned int count = 0;
-	unsigned int in_drop_list = 0;
-	struct inode *inode, *tmp;
-
-	dprintk("%s.\n", __func__);
-
-	/*
-	 * Kill pending transactions, which could affect inodes in-flight.
-	 */
-	pohmelfs_flush_transactions(psb);
-
-	while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count))) {
-		inode = &pi->vfs_inode;
-
-		dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
-				__func__, pi->ino, pi, inode, count);
-
-		if (atomic_read(&inode->i_count) != count) {
-			printk("%s: ino: %llu, pi: %p, inode: %p, count: %u, i_count: %d.\n",
-					__func__, pi->ino, pi, inode, count,
-					atomic_read(&inode->i_count));
-			count = atomic_read(&inode->i_count);
-			in_drop_list++;
-		}
-
-		while (count--)
-			iput(&pi->vfs_inode);
-	}
-
-	list_for_each_entry_safe(inode, tmp, &sb->s_inodes, i_sb_list) {
-		pi = POHMELFS_I(inode);
-
-		dprintk("%s: ino: %llu, pi: %p, inode: %p, i_count: %u.\n",
-				__func__, pi->ino, pi, inode, atomic_read(&inode->i_count));
-
-		/*
-		 * These are special inodes, they were created during
-		 * directory reading or lookup, and were not bound to dentry,
-		 * so they live here with reference counter being 1 and prevent
-		 * umount from succeed since it believes that they are busy.
-		 */
-		count = atomic_read(&inode->i_count);
-		if (count) {
-			list_del_init(&inode->i_sb_list);
-			while (count--)
-				iput(&pi->vfs_inode);
-		}
-	}
-
-	psb->trans_scan_timeout = psb->drop_scan_timeout = 0;
-	cancel_delayed_work_sync(&psb->dwork);
-	cancel_delayed_work_sync(&psb->drop_dwork);
-	flush_scheduled_work();
-
-	dprintk("%s: stopped workqueues.\n", __func__);
-
-	pohmelfs_crypto_exit(psb);
-	pohmelfs_state_exit(psb);
-
-	bdi_destroy(&psb->bdi);
-
-	kfree(psb);
-	sb->s_fs_info = NULL;
-}
-
-static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf)
-{
-	struct super_block *sb = dentry->d_sb;
-	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-
-	/*
-	 * There are no filesystem size limits yet.
-	 */
-	memset(buf, 0, sizeof(struct kstatfs));
-
-	buf->f_type = POHMELFS_MAGIC_NUM; /* 'POH.' */
-	buf->f_bsize = sb->s_blocksize;
-	buf->f_files = psb->ino;
-	buf->f_namelen = 255;
-	buf->f_files = atomic_long_read(&psb->total_inodes);
-	buf->f_bfree = buf->f_bavail = psb->avail_size >> PAGE_SHIFT;
-	buf->f_blocks = psb->total_size >> PAGE_SHIFT;
-
-	dprintk("%s: total: %llu, avail: %llu, inodes: %llu, bsize: %lu.\n",
-		__func__, psb->total_size, psb->avail_size, buf->f_files, sb->s_blocksize);
-
-	return 0;
-}
-
-static int pohmelfs_show_options(struct seq_file *seq, struct dentry *root)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(root->d_sb);
-
-	seq_printf(seq, ",idx=%u", psb->idx);
-	seq_printf(seq, ",trans_scan_timeout=%u", jiffies_to_msecs(psb->trans_scan_timeout));
-	seq_printf(seq, ",drop_scan_timeout=%u", jiffies_to_msecs(psb->drop_scan_timeout));
-	seq_printf(seq, ",wait_on_page_timeout=%u", jiffies_to_msecs(psb->wait_on_page_timeout));
-	seq_printf(seq, ",trans_retries=%u", psb->trans_retries);
-	seq_printf(seq, ",crypto_thread_num=%u", psb->crypto_thread_num);
-	seq_printf(seq, ",trans_max_pages=%u", psb->trans_max_pages);
-	seq_printf(seq, ",mcache_timeout=%u", jiffies_to_msecs(psb->mcache_timeout));
-	if (psb->crypto_fail_unsupported)
-		seq_printf(seq, ",crypto_fail_unsupported");
-
-	return 0;
-}
-
-enum {
-	pohmelfs_opt_idx,
-	pohmelfs_opt_crypto_thread_num,
-	pohmelfs_opt_trans_max_pages,
-	pohmelfs_opt_crypto_fail_unsupported,
-
-	/* Remountable options */
-	pohmelfs_opt_trans_scan_timeout,
-	pohmelfs_opt_drop_scan_timeout,
-	pohmelfs_opt_wait_on_page_timeout,
-	pohmelfs_opt_trans_retries,
-	pohmelfs_opt_mcache_timeout,
-};
-
-static struct match_token pohmelfs_tokens[] = {
-	{pohmelfs_opt_idx, "idx=%u"},
-	{pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"},
-	{pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"},
-	{pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"},
-	{pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"},
-	{pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"},
-	{pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"},
-	{pohmelfs_opt_trans_retries, "trans_retries=%u"},
-	{pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"},
-};
-
-static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb, int remount)
-{
-	char *p;
-	substring_t args[MAX_OPT_ARGS];
-	int option, err;
-
-	if (!options)
-		return 0;
-
-	while ((p = strsep(&options, ",")) != NULL) {
-		int token;
-		if (!*p)
-			continue;
-
-		token = match_token(p, pohmelfs_tokens, args);
-
-		err = match_int(&args[0], &option);
-		if (err)
-			return err;
-
-		if (remount && token <= pohmelfs_opt_crypto_fail_unsupported)
-			continue;
-
-		switch (token) {
-		case pohmelfs_opt_idx:
-			psb->idx = option;
-			break;
-		case pohmelfs_opt_trans_scan_timeout:
-			psb->trans_scan_timeout = msecs_to_jiffies(option);
-			break;
-		case pohmelfs_opt_drop_scan_timeout:
-			psb->drop_scan_timeout = msecs_to_jiffies(option);
-			break;
-		case pohmelfs_opt_wait_on_page_timeout:
-			psb->wait_on_page_timeout = msecs_to_jiffies(option);
-			break;
-		case pohmelfs_opt_mcache_timeout:
-			psb->mcache_timeout = msecs_to_jiffies(option);
-			break;
-		case pohmelfs_opt_trans_retries:
-			psb->trans_retries = option;
-			break;
-		case pohmelfs_opt_crypto_thread_num:
-			psb->crypto_thread_num = option;
-			break;
-		case pohmelfs_opt_trans_max_pages:
-			psb->trans_max_pages = option;
-			break;
-		case pohmelfs_opt_crypto_fail_unsupported:
-			psb->crypto_fail_unsupported = 1;
-			break;
-		default:
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
-{
-	int err;
-	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
-	unsigned long old_sb_flags = sb->s_flags;
-
-	err = pohmelfs_parse_options(data, psb, 1);
-	if (err)
-		goto err_out_restore;
-
-	if (!(*flags & MS_RDONLY))
-		sb->s_flags &= ~MS_RDONLY;
-	return 0;
-
-err_out_restore:
-	sb->s_flags = old_sb_flags;
-	return err;
-}
-
-static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count)
-{
-	struct inode *inode = &pi->vfs_inode;
-
-	dprintk("%s: %p: ino: %llu, owned: %d.\n",
-		__func__, inode, pi->ino, test_bit(NETFS_INODE_OWNED, &pi->state));
-
-	mutex_lock(&inode->i_mutex);
-	if (test_and_clear_bit(NETFS_INODE_OWNED, &pi->state)) {
-		filemap_fdatawrite(inode->i_mapping);
-		inode->i_sb->s_op->write_inode(inode, 0);
-	}
-
-#ifdef POHMELFS_TRUNCATE_ON_INODE_FLUSH
-	truncate_inode_pages(inode->i_mapping, 0);
-#endif
-
-	pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
-	mutex_unlock(&inode->i_mutex);
-}
-
-static void pohmelfs_put_inode_count(struct pohmelfs_inode *pi, unsigned int count)
-{
-	dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
-			__func__, pi->ino, pi, &pi->vfs_inode, count);
-
-	if (test_and_clear_bit(NETFS_INODE_NEED_FLUSH, &pi->state))
-		pohmelfs_flush_inode(pi, count);
-
-	while (count--)
-		iput(&pi->vfs_inode);
-}
-
-static void pohmelfs_drop_scan(struct work_struct *work)
-{
-	struct pohmelfs_sb *psb =
-		container_of(work, struct pohmelfs_sb, drop_dwork.work);
-	struct pohmelfs_inode *pi;
-	unsigned int count = 0;
-
-	while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count)))
-		pohmelfs_put_inode_count(pi, count);
-
-	pohmelfs_check_states(psb);
-
-	if (psb->drop_scan_timeout)
-		schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
-}
-
-/*
- * Run through all transactions starting from the oldest,
- * drop transaction from current state and try to send it
- * to all remote nodes, which are currently installed.
- */
-static void pohmelfs_trans_scan_state(struct netfs_state *st)
-{
-	struct rb_node *rb_node;
-	struct netfs_trans_dst *dst;
-	struct pohmelfs_sb *psb = st->psb;
-	unsigned int timeout = psb->trans_scan_timeout;
-	struct netfs_trans *t;
-	int err;
-
-	mutex_lock(&st->trans_lock);
-	for (rb_node = rb_first(&st->trans_root); rb_node; ) {
-		dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
-		t = dst->trans;
-
-		if (timeout && time_after(dst->send_time + timeout, jiffies)
-				&& dst->retries == 0)
-			break;
-
-		dprintk("%s: t: %p, gen: %u, st: %p, retries: %u, max: %u.\n",
-			__func__, t, t->gen, st, dst->retries, psb->trans_retries);
-		netfs_trans_get(t);
-
-		rb_node = rb_next(rb_node);
-
-		err = -ETIMEDOUT;
-		if (timeout && (++dst->retries < psb->trans_retries))
-			err = netfs_trans_resend(t, psb);
-
-		if (err || (t->flags & NETFS_TRANS_SINGLE_DST)) {
-			if (netfs_trans_remove_nolock(dst, st))
-				netfs_trans_drop_dst_nostate(dst);
-		}
-
-		t->result = err;
-		netfs_trans_put(t);
-	}
-	mutex_unlock(&st->trans_lock);
-}
-
-/*
- * Walk through all installed network states and resend all
- * transactions, which are old enough.
- */
-static void pohmelfs_trans_scan(struct work_struct *work)
-{
-	struct pohmelfs_sb *psb =
-		container_of(work, struct pohmelfs_sb, dwork.work);
-	struct netfs_state *st;
-	struct pohmelfs_config *c;
-
-	mutex_lock(&psb->state_lock);
-	list_for_each_entry(c, &psb->state_list, config_entry) {
-		st = &c->state;
-
-		pohmelfs_trans_scan_state(st);
-	}
-	mutex_unlock(&psb->state_lock);
-
-	/*
-	 * If no timeout specified then system is in the middle of umount process,
-	 * so no need to reschedule scanning process again.
-	 */
-	if (psb->trans_scan_timeout)
-		schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
-}
-
-int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
-		unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start)
-{
-	struct inode *inode = &pi->vfs_inode;
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	int err = 0, sz;
-	struct netfs_trans *t;
-	int path_len, addon_len = 0;
-	void *data;
-	struct netfs_inode_info *info;
-	struct netfs_cmd *cmd;
-
-	dprintk("%s: ino: %llu, cmd: %u, addon: %p.\n", __func__, pi->ino, cmd_op, addon);
-
-	path_len = pohmelfs_path_length(pi);
-	if (path_len < 0) {
-		err = path_len;
-		goto err_out_exit;
-	}
-
-	if (addon)
-		addon_len = strlen(addon) + 1; /* 0-byte */
-	sz = addon_len;
-
-	if (cmd_op == NETFS_INODE_INFO)
-		sz += sizeof(struct netfs_inode_info);
-
-	t = netfs_trans_alloc(psb, sz + path_len, flags, 0);
-	if (!t) {
-		err = -ENOMEM;
-		goto err_out_exit;
-	}
-	t->complete = complete;
-	t->private = priv;
-
-	cmd = netfs_trans_current(t);
-	data = (void *)(cmd + 1);
-
-	if (cmd_op == NETFS_INODE_INFO) {
-		info = (struct netfs_inode_info *)(cmd + 1);
-		data = (void *)(info + 1);
-
-		/*
-		 * We are under i_mutex, can read and change whatever we want...
-		 */
-		info->mode = inode->i_mode;
-		info->nlink = inode->i_nlink;
-		info->uid = inode->i_uid;
-		info->gid = inode->i_gid;
-		info->blocks = inode->i_blocks;
-		info->rdev = inode->i_rdev;
-		info->size = inode->i_size;
-		info->version = inode->i_version;
-
-		netfs_convert_inode_info(info);
-	}
-
-	path_len = pohmelfs_construct_path_string(pi, data, path_len);
-	if (path_len < 0)
-		goto err_out_free;
-
-	dprintk("%s: path_len: %d.\n", __func__, path_len);
-
-	if (addon) {
-		path_len--; /* Do not place null-byte before the addon */
-		path_len += sprintf(data + path_len, "/%s", addon) + 1; /* 0 - byte */
-	}
-
-	sz += path_len;
-
-	cmd->cmd = cmd_op;
-	cmd->ext = path_len;
-	cmd->size = sz;
-	cmd->id = id;
-	cmd->start = start;
-
-	netfs_convert_cmd(cmd);
-	netfs_trans_update(cmd, t, sz);
-
-	/*
-	 * Note, that it is possible to leak error here: transaction callback will not
-	 * be invoked for allocation path failure.
-	 */
-	return netfs_trans_finish(t, psb);
-
-err_out_free:
-	netfs_trans_free(t);
-err_out_exit:
-	if (complete)
-		complete(NULL, 0, priv, err);
-	return err;
-}
-
-int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
-		netfs_trans_complete_t complete, void *priv, u64 start)
-{
-	return pohmelfs_meta_command_data(pi, pi->ino, cmd_op, NULL, flags, complete, priv, start);
-}
-
-/*
- * Send request and wait for POHMELFS root capabilities response,
- * which will update server's informaion about size of the export,
- * permissions, number of objects, available size and so on.
- */
-static int pohmelfs_root_handshake(struct pohmelfs_sb *psb)
-{
-	struct netfs_trans *t;
-	struct netfs_cmd *cmd;
-	int err = -ENOMEM;
-
-	t = netfs_trans_alloc(psb, 0, 0, 0);
-	if (!t)
-		goto err_out_exit;
-
-	cmd = netfs_trans_current(t);
-
-	cmd->cmd = NETFS_CAPABILITIES;
-	cmd->id = POHMELFS_ROOT_CAPABILITIES;
-	cmd->size = 0;
-	cmd->start = 0;
-	cmd->ext = 0;
-	cmd->csize = 0;
-
-	netfs_convert_cmd(cmd);
-	netfs_trans_update(cmd, t, 0);
-
-	err = netfs_trans_finish(t, psb);
-	if (err)
-		goto err_out_exit;
-
-	psb->flags = ~0;
-	err = wait_event_interruptible_timeout(psb->wait,
-			(psb->flags != ~0),
-			psb->wait_on_page_timeout);
-	if (!err)
-		err = -ETIMEDOUT;
-	else if (err > 0)
-		err = -psb->flags;
-
-	if (err)
-		goto err_out_exit;
-
-	return 0;
-
-err_out_exit:
-	return err;
-}
-
-static int pohmelfs_show_stats(struct seq_file *m, struct dentry *root)
-{
-	struct netfs_state *st;
-	struct pohmelfs_ctl *ctl;
-	struct pohmelfs_sb *psb = POHMELFS_SB(root->d_sb);
-	struct pohmelfs_config *c;
-
-	mutex_lock(&psb->state_lock);
-
-	seq_printf(m, "\nidx addr(:port) socket_type protocol active priority permissions\n");
-
-	list_for_each_entry(c, &psb->state_list, config_entry) {
-		st = &c->state;
-		ctl = &st->ctl;
-
-		seq_printf(m, "%u ", ctl->idx);
-		if (ctl->addr.sa_family == AF_INET) {
-			struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
-			seq_printf(m, "%pI4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port));
-		} else if (ctl->addr.sa_family == AF_INET6) {
-			struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
-			seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port));
-		} else {
-			unsigned int i;
-			for (i = 0; i < ctl->addrlen; ++i)
-				seq_printf(m, "%02x.", ctl->addr.addr[i]);
-		}
-
-		seq_printf(m, " %u %u %d %u %x\n",
-				ctl->type, ctl->proto,
-				st->socket != NULL,
-				ctl->prio, ctl->perm);
-	}
-	mutex_unlock(&psb->state_lock);
-
-	return 0;
-}
-
-static const struct super_operations pohmelfs_sb_ops = {
-	.alloc_inode	= pohmelfs_alloc_inode,
-	.destroy_inode	= pohmelfs_destroy_inode,
-	.drop_inode	= pohmelfs_drop_inode,
-	.write_inode	= pohmelfs_write_inode,
-	.put_super	= pohmelfs_put_super,
-	.remount_fs	= pohmelfs_remount,
-	.statfs		= pohmelfs_statfs,
-	.show_options	= pohmelfs_show_options,
-	.show_stats	= pohmelfs_show_stats,
-};
-
-/*
- * Allocate private superblock and create root dir.
- */
-static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct pohmelfs_sb *psb;
-	int err = -ENOMEM;
-	struct inode *root;
-	struct pohmelfs_inode *npi;
-	struct qstr str;
-
-	psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL);
-	if (!psb)
-		goto err_out_exit;
-
-	err = bdi_init(&psb->bdi);
-	if (err)
-		goto err_out_free_sb;
-
-	err = bdi_register(&psb->bdi, NULL, "pfs-%d", atomic_inc_return(&psb_bdi_num));
-	if (err) {
-		bdi_destroy(&psb->bdi);
-		goto err_out_free_sb;
-	}
-
-	sb->s_fs_info = psb;
-	sb->s_op = &pohmelfs_sb_ops;
-	sb->s_magic = POHMELFS_MAGIC_NUM;
-	sb->s_maxbytes = MAX_LFS_FILESIZE;
-	sb->s_blocksize = PAGE_SIZE;
-	sb->s_bdi = &psb->bdi;
-
-	psb->sb = sb;
-
-	psb->ino = 2;
-	psb->idx = 0;
-	psb->active_state = NULL;
-	psb->trans_retries = 5;
-	psb->trans_data_size = PAGE_SIZE;
-	psb->drop_scan_timeout = msecs_to_jiffies(1000);
-	psb->trans_scan_timeout = msecs_to_jiffies(5000);
-	psb->wait_on_page_timeout = msecs_to_jiffies(5000);
-	init_waitqueue_head(&psb->wait);
-
-	spin_lock_init(&psb->ino_lock);
-
-	INIT_LIST_HEAD(&psb->drop_list);
-
-	mutex_init(&psb->mcache_lock);
-	psb->mcache_root = RB_ROOT;
-	psb->mcache_timeout = msecs_to_jiffies(5000);
-	atomic_long_set(&psb->mcache_gen, 0);
-
-	psb->trans_max_pages = 100;
-
-	psb->crypto_align_size = 16;
-	psb->crypto_attached_size = 0;
-	psb->hash_strlen = 0;
-	psb->cipher_strlen = 0;
-	psb->perform_crypto = 0;
-	psb->crypto_thread_num = 2;
-	psb->crypto_fail_unsupported = 0;
-	mutex_init(&psb->crypto_thread_lock);
-	INIT_LIST_HEAD(&psb->crypto_ready_list);
-	INIT_LIST_HEAD(&psb->crypto_active_list);
-
-	atomic_set(&psb->trans_gen, 1);
-	atomic_long_set(&psb->total_inodes, 0);
-
-	mutex_init(&psb->state_lock);
-	INIT_LIST_HEAD(&psb->state_list);
-
-	err = pohmelfs_parse_options((char *) data, psb, 0);
-	if (err)
-		goto err_out_free_bdi;
-
-	err = pohmelfs_copy_crypto(psb);
-	if (err)
-		goto err_out_free_bdi;
-
-	err = pohmelfs_state_init(psb);
-	if (err)
-		goto err_out_free_strings;
-
-	err = pohmelfs_crypto_init(psb);
-	if (err)
-		goto err_out_state_exit;
-
-	err = pohmelfs_root_handshake(psb);
-	if (err)
-		goto err_out_crypto_exit;
-
-	str.name = "/";
-	str.hash = jhash("/", 1, 0);
-	str.len = 1;
-
-	npi = pohmelfs_create_entry_local(psb, NULL, &str, 0, 0755|S_IFDIR);
-	if (IS_ERR(npi)) {
-		err = PTR_ERR(npi);
-		goto err_out_crypto_exit;
-	}
-	set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
-	clear_bit(NETFS_INODE_OWNED, &npi->state);
-
-	root = &npi->vfs_inode;
-
-	sb->s_root = d_alloc_root(root);
-	if (!sb->s_root)
-		goto err_out_put_root;
-
-	INIT_DELAYED_WORK(&psb->drop_dwork, pohmelfs_drop_scan);
-	schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
-
-	INIT_DELAYED_WORK(&psb->dwork, pohmelfs_trans_scan);
-	schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
-
-	return 0;
-
-err_out_put_root:
-	iput(root);
-err_out_crypto_exit:
-	pohmelfs_crypto_exit(psb);
-err_out_state_exit:
-	pohmelfs_state_exit(psb);
-err_out_free_strings:
-	kfree(psb->cipher_string);
-	kfree(psb->hash_string);
-err_out_free_bdi:
-	bdi_destroy(&psb->bdi);
-err_out_free_sb:
-	kfree(psb);
-err_out_exit:
-
-	dprintk("%s: err: %d.\n", __func__, err);
-	return err;
-}
-
-/*
- * Some VFS magic here...
- */
-static struct dentry *pohmelfs_mount(struct file_system_type *fs_type,
-	int flags, const char *dev_name, void *data)
-{
-	return mount_nodev(fs_type, flags, data, pohmelfs_fill_super);
-}
-
-/*
- * We need this to sync all inodes earlier, since when writeback
- * is invoked from the umount/mntput path dcache is already shrunk,
- * see generic_shutdown_super(), and no inodes can access the path.
- */
-static void pohmelfs_kill_super(struct super_block *sb)
-{
-	sync_inodes_sb(sb);
-	kill_anon_super(sb);
-}
-
-static struct file_system_type pohmel_fs_type = {
-	.owner		= THIS_MODULE,
-	.name		= "pohmel",
-	.mount		= pohmelfs_mount,
-	.kill_sb 	= pohmelfs_kill_super,
-};
-
-/*
- * Cache and module initializations and freeing routings.
- */
-static void pohmelfs_init_once(void *data)
-{
-	struct pohmelfs_inode *pi = data;
-
-	inode_init_once(&pi->vfs_inode);
-}
-
-static int __init pohmelfs_init_inodecache(void)
-{
-	pohmelfs_inode_cache = kmem_cache_create("pohmelfs_inode_cache",
-				sizeof(struct pohmelfs_inode),
-				0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
-				pohmelfs_init_once);
-	if (!pohmelfs_inode_cache)
-		return -ENOMEM;
-
-	return 0;
-}
-
-static void pohmelfs_destroy_inodecache(void)
-{
-	kmem_cache_destroy(pohmelfs_inode_cache);
-}
-
-static int __init init_pohmel_fs(void)
-{
-	int err;
-
-	err = pohmelfs_config_init();
-	if (err)
-		goto err_out_exit;
-
-	err = pohmelfs_init_inodecache();
-	if (err)
-		goto err_out_config_exit;
-
-	err = pohmelfs_mcache_init();
-	if (err)
-		goto err_out_destroy;
-
-	err = netfs_trans_init();
-	if (err)
-		goto err_out_mcache_exit;
-
-	err = register_filesystem(&pohmel_fs_type);
-	if (err)
-		goto err_out_trans;
-
-	return 0;
-
-err_out_trans:
-	netfs_trans_exit();
-err_out_mcache_exit:
-	pohmelfs_mcache_exit();
-err_out_destroy:
-	pohmelfs_destroy_inodecache();
-err_out_config_exit:
-	pohmelfs_config_exit();
-err_out_exit:
-	return err;
-}
-
-static void __exit exit_pohmel_fs(void)
-{
-	unregister_filesystem(&pohmel_fs_type);
-	pohmelfs_destroy_inodecache();
-	pohmelfs_mcache_exit();
-	pohmelfs_config_exit();
-	netfs_trans_exit();
-}
-
-module_init(init_pohmel_fs);
-module_exit(exit_pohmel_fs);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
-MODULE_DESCRIPTION("Pohmel filesystem");
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c
deleted file mode 100644
index 6710114cd..0000000
--- a/drivers/staging/pohmelfs/lock.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/backing-dev.h>
-#include <linux/fs.h>
-#include <linux/fsnotify.h>
-#include <linux/mempool.h>
-
-#include "netfs.h"
-
-static int pohmelfs_send_lock_trans(struct pohmelfs_inode *pi,
-		u64 id, u64 start, u32 size, int type)
-{
-	struct inode *inode = &pi->vfs_inode;
-	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
-	struct netfs_trans *t;
-	struct netfs_cmd *cmd;
-	int path_len, err;
-	void *data;
-	struct netfs_lock *l;
-	int isize = (type & POHMELFS_LOCK_GRAB) ? 0 : sizeof(struct netfs_inode_info);
-
-	err = pohmelfs_path_length(pi);
-	if (err < 0)
-		goto err_out_exit;
-
-	path_len = err;
-
-	err = -ENOMEM;
-	t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize,
-			NETFS_TRANS_SINGLE_DST, 0);
-	if (!t)
-		goto err_out_exit;
-
-	cmd = netfs_trans_current(t);
-	data = cmd + 1;
-
-	err = pohmelfs_construct_path_string(pi, data, path_len);
-	if (err < 0)
-		goto err_out_free;
-	path_len = err;
-
-	l = data + path_len;
-
-	l->start = start;
-	l->size = size;
-	l->type = type;
-	l->ino = pi->ino;
-
-	cmd->cmd = NETFS_LOCK;
-	cmd->start = 0;
-	cmd->id = id;
-	cmd->size = sizeof(struct netfs_lock) + path_len + isize;
-	cmd->ext = path_len;
-	cmd->csize = 0;
-
-	netfs_convert_cmd(cmd);
-	netfs_convert_lock(l);
-
-	if (isize) {
-		struct netfs_inode_info *info = (struct netfs_inode_info *)(l + 1);
-
-		info->mode = inode->i_mode;
-		info->nlink = inode->i_nlink;
-		info->uid = inode->i_uid;
-		info->gid = inode->i_gid;
-		info->blocks = inode->i_blocks;
-		info->rdev = inode->i_rdev;
-		info->size = inode->i_size;
-		info->version = inode->i_version;
-
-		netfs_convert_inode_info(info);
-	}
-
-	netfs_trans_update(cmd, t, path_len + sizeof(struct netfs_lock) + isize);
-
-	return netfs_trans_finish(t, psb);
-
-err_out_free:
-	netfs_trans_free(t);
-err_out_exit:
-	printk("%s: err: %d.\n", __func__, err);
-	return err;
-}
-
-int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-	struct pohmelfs_mcache *m;
-	int err = -ENOMEM;
-	struct iattr iattr;
-	struct inode *inode = &pi->vfs_inode;
-
-	dprintk("%s: %p: ino: %llu, start: %llu, size: %u, "
-			"type: %d, locked as: %d, owned: %d.\n",
-			__func__, &pi->vfs_inode, pi->ino,
-			start, size, type, pi->lock_type,
-			!!test_bit(NETFS_INODE_OWNED, &pi->state));
-
-	if (!pohmelfs_need_lock(pi, type))
-		return 0;
-
-	m = pohmelfs_mcache_alloc(psb, start, size, NULL);
-	if (IS_ERR(m))
-		return PTR_ERR(m);
-
-	err = pohmelfs_send_lock_trans(pi, m->gen, start, size,
-			type | POHMELFS_LOCK_GRAB);
-	if (err)
-		goto err_out_put;
-
-	err = wait_for_completion_timeout(&m->complete, psb->mcache_timeout);
-	if (err)
-		err = m->err;
-	else
-		err = -ETIMEDOUT;
-
-	if (err) {
-		printk("%s: %p: ino: %llu, mgen: %llu, start: %llu, size: %u, err: %d.\n",
-			__func__, &pi->vfs_inode, pi->ino, m->gen, start, size, err);
-	}
-
-	if (err && (err != -ENOENT))
-		goto err_out_put;
-
-	if (!err) {
-		netfs_convert_inode_info(&m->info);
-
-		iattr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_SIZE | ATTR_ATIME;
-		iattr.ia_mode = m->info.mode;
-		iattr.ia_uid = m->info.uid;
-		iattr.ia_gid = m->info.gid;
-		iattr.ia_size = m->info.size;
-		iattr.ia_atime = CURRENT_TIME;
-
-		dprintk("%s: %p: ino: %llu, mgen: %llu, start: %llu, isize: %llu -> %llu.\n",
-			__func__, &pi->vfs_inode, pi->ino, m->gen, start, inode->i_size, m->info.size);
-
-		err = pohmelfs_setattr_raw(inode, &iattr);
-		if (!err) {
-			struct dentry *dentry = d_find_alias(inode);
-			if (dentry) {
-				fsnotify_change(dentry, iattr.ia_valid);
-				dput(dentry);
-			}
-		}
-	}
-
-	pi->lock_type = type;
-	set_bit(NETFS_INODE_OWNED, &pi->state);
-
-	pohmelfs_mcache_put(psb, m);
-
-	return 0;
-
-err_out_put:
-	pohmelfs_mcache_put(psb, m);
-	return err;
-}
-
-int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
-{
-	dprintk("%s: %p: ino: %llu, start: %llu, size: %u, type: %d.\n",
-			__func__, &pi->vfs_inode, pi->ino, start, size, type);
-	pi->lock_type = 0;
-	clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state);
-	clear_bit(NETFS_INODE_OWNED, &pi->state);
-	return pohmelfs_send_lock_trans(pi, pi->ino, start, size, type);
-}
diff --git a/drivers/staging/pohmelfs/mcache.c b/drivers/staging/pohmelfs/mcache.c
deleted file mode 100644
index e22665c..0000000
--- a/drivers/staging/pohmelfs/mcache.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mempool.h>
-
-#include "netfs.h"
-
-static struct kmem_cache *pohmelfs_mcache_cache;
-static mempool_t *pohmelfs_mcache_pool;
-
-static inline int pohmelfs_mcache_cmp(u64 gen, u64 new)
-{
-	if (gen < new)
-		return 1;
-	if (gen > new)
-		return -1;
-	return 0;
-}
-
-struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen)
-{
-	struct rb_root *root = &psb->mcache_root;
-	struct rb_node *n = root->rb_node;
-	struct pohmelfs_mcache *tmp, *ret = NULL;
-	int cmp;
-
-	while (n) {
-		tmp = rb_entry(n, struct pohmelfs_mcache, mcache_entry);
-
-		cmp = pohmelfs_mcache_cmp(tmp->gen, gen);
-		if (cmp < 0)
-			n = n->rb_left;
-		else if (cmp > 0)
-			n = n->rb_right;
-		else {
-			ret = tmp;
-			pohmelfs_mcache_get(ret);
-			break;
-		}
-	}
-
-	return ret;
-}
-
-static int pohmelfs_mcache_insert(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
-{
-	struct rb_root *root = &psb->mcache_root;
-	struct rb_node **n = &root->rb_node, *parent = NULL;
-	struct pohmelfs_mcache *ret = NULL, *tmp;
-	int cmp;
-
-	while (*n) {
-		parent = *n;
-
-		tmp = rb_entry(parent, struct pohmelfs_mcache, mcache_entry);
-
-		cmp = pohmelfs_mcache_cmp(tmp->gen, m->gen);
-		if (cmp < 0)
-			n = &parent->rb_left;
-		else if (cmp > 0)
-			n = &parent->rb_right;
-		else {
-			ret = tmp;
-			break;
-		}
-	}
-
-	if (ret)
-		return -EEXIST;
-
-	rb_link_node(&m->mcache_entry, parent, n);
-	rb_insert_color(&m->mcache_entry, root);
-
-	return 0;
-}
-
-static int pohmelfs_mcache_remove(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
-{
-	if (m && m->mcache_entry.rb_parent_color) {
-		rb_erase(&m->mcache_entry, &psb->mcache_root);
-		m->mcache_entry.rb_parent_color = 0;
-		return 1;
-	}
-	return 0;
-}
-
-void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
-{
-	mutex_lock(&psb->mcache_lock);
-	pohmelfs_mcache_remove(psb, m);
-	mutex_unlock(&psb->mcache_lock);
-}
-
-struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
-		unsigned int size, void *data)
-{
-	struct pohmelfs_mcache *m;
-	int err = -ENOMEM;
-
-	m = mempool_alloc(pohmelfs_mcache_pool, GFP_KERNEL);
-	if (!m)
-		goto err_out_exit;
-
-	init_completion(&m->complete);
-	m->err = 0;
-	atomic_set(&m->refcnt, 1);
-	m->data = data;
-	m->start = start;
-	m->size = size;
-	m->gen = atomic_long_inc_return(&psb->mcache_gen);
-
-	mutex_lock(&psb->mcache_lock);
-	err = pohmelfs_mcache_insert(psb, m);
-	mutex_unlock(&psb->mcache_lock);
-	if (err)
-		goto err_out_free;
-
-	return m;
-
-err_out_free:
-	mempool_free(m, pohmelfs_mcache_pool);
-err_out_exit:
-	return ERR_PTR(err);
-}
-
-void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
-{
-	pohmelfs_mcache_remove_locked(psb, m);
-
-	mempool_free(m, pohmelfs_mcache_pool);
-}
-
-int __init pohmelfs_mcache_init(void)
-{
-	pohmelfs_mcache_cache = kmem_cache_create("pohmelfs_mcache_cache",
-				sizeof(struct pohmelfs_mcache),
-				0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), NULL);
-	if (!pohmelfs_mcache_cache)
-		goto err_out_exit;
-
-	pohmelfs_mcache_pool = mempool_create_slab_pool(256, pohmelfs_mcache_cache);
-	if (!pohmelfs_mcache_pool)
-		goto err_out_free;
-
-	return 0;
-
-err_out_free:
-	kmem_cache_destroy(pohmelfs_mcache_cache);
-err_out_exit:
-	return -ENOMEM;
-}
-
-void pohmelfs_mcache_exit(void)
-{
-	mempool_destroy(pohmelfs_mcache_pool);
-	kmem_cache_destroy(pohmelfs_mcache_cache);
-}
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
deleted file mode 100644
index b2e9186..0000000
--- a/drivers/staging/pohmelfs/net.c
+++ /dev/null
@@ -1,1209 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/fsnotify.h>
-#include <linux/jhash.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/kthread.h>
-#include <linux/pagemap.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/swap.h>
-#include <linux/syscalls.h>
-#include <linux/vmalloc.h>
-
-#include "netfs.h"
-
-/*
- * Async machinery lives here.
- * All commands being sent to server do _not_ require sync reply,
- * instead, if it is really needed, like readdir or readpage, caller
- * sleeps waiting for data, which will be placed into provided buffer
- * and caller will be awakened.
- *
- * Every command response can come without some listener. For example
- * readdir response will add new objects into cache without appropriate
- * request from userspace. This is used in cache coherency.
- *
- * If object is not found for given data, it is discarded.
- *
- * All requests are received by dedicated kernel thread.
- */
-
-/*
- * Basic network sending/receiving functions.
- * Blocked mode is used.
- */
-static int netfs_data_recv(struct netfs_state *st, void *buf, u64 size)
-{
-	struct msghdr msg;
-	struct kvec iov;
-	int err;
-
-	BUG_ON(!size);
-
-	iov.iov_base = buf;
-	iov.iov_len = size;
-
-	msg.msg_iov = (struct iovec *)&iov;
-	msg.msg_iovlen = 1;
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_flags = MSG_DONTWAIT;
-
-	err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
-			msg.msg_flags);
-	if (err <= 0) {
-		printk("%s: failed to recv data: size: %llu, err: %d.\n", __func__, size, err);
-		if (err == 0)
-			err = -ECONNRESET;
-	}
-
-	return err;
-}
-
-static int pohmelfs_data_recv(struct netfs_state *st, void *data, unsigned int size)
-{
-	unsigned int revents = 0;
-	unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
-	unsigned int mask = err_mask | POLLIN;
-	int err = 0;
-
-	while (size && !err) {
-		revents = netfs_state_poll(st);
-
-		if (!(revents & mask)) {
-			DEFINE_WAIT(wait);
-
-			for (;;) {
-				prepare_to_wait(&st->thread_wait, &wait, TASK_INTERRUPTIBLE);
-				if (kthread_should_stop())
-					break;
-
-				revents = netfs_state_poll(st);
-
-				if (revents & mask)
-					break;
-
-				if (signal_pending(current))
-					break;
-
-				schedule();
-				continue;
-			}
-			finish_wait(&st->thread_wait, &wait);
-		}
-
-		err = 0;
-		netfs_state_lock(st);
-		if (st->socket && (st->read_socket == st->socket) && (revents & POLLIN)) {
-			err = netfs_data_recv(st, data, size);
-			if (err > 0) {
-				data += err;
-				size -= err;
-				err = 0;
-			} else if (err == 0)
-				err = -ECONNRESET;
-		}
-
-		if (revents & err_mask) {
-			printk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
-					__func__, revents, st->socket, size, err);
-			err = -ECONNRESET;
-		}
-		netfs_state_unlock(st);
-
-		if (err < 0) {
-			if (netfs_state_trylock_send(st)) {
-				netfs_state_exit(st);
-				err = netfs_state_init(st);
-				if (!err)
-					err = -EAGAIN;
-				netfs_state_unlock_send(st);
-			} else {
-				st->need_reset = 1;
-			}
-		}
-
-		if (kthread_should_stop())
-			err = -ENODEV;
-
-		if (err)
-			printk("%s: socket: %p, read_socket: %p, revents: %x, rev_error: %d, "
-					"should_stop: %d, size: %u, err: %d.\n",
-				__func__, st->socket, st->read_socket,
-				revents, revents & err_mask, kthread_should_stop(), size, err);
-	}
-
-	return err;
-}
-
-int pohmelfs_data_recv_and_check(struct netfs_state *st, void *data, unsigned int size)
-{
-	struct netfs_cmd *cmd = &st->cmd;
-	int err;
-
-	err = pohmelfs_data_recv(st, data, size);
-	if (err)
-		return err;
-
-	return pohmelfs_crypto_process_input_data(&st->eng, cmd->iv, data, NULL, size);
-}
-
-/*
- * Polling machinery.
- */
-
-struct netfs_poll_helper {
-	poll_table 		pt;
-	struct netfs_state	*st;
-};
-
-static int netfs_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
-{
-	struct netfs_state *st = container_of(wait, struct netfs_state, wait);
-
-	wake_up(&st->thread_wait);
-	return 1;
-}
-
-static void netfs_queue_func(struct file *file, wait_queue_head_t *whead,
-				 poll_table *pt)
-{
-	struct netfs_state *st = container_of(pt, struct netfs_poll_helper, pt)->st;
-
-	st->whead = whead;
-	init_waitqueue_func_entry(&st->wait, netfs_queue_wake);
-	add_wait_queue(whead, &st->wait);
-}
-
-static void netfs_poll_exit(struct netfs_state *st)
-{
-	if (st->whead) {
-		remove_wait_queue(st->whead, &st->wait);
-		st->whead = NULL;
-	}
-}
-
-static int netfs_poll_init(struct netfs_state *st)
-{
-	struct netfs_poll_helper ph;
-
-	ph.st = st;
-	init_poll_funcptr(&ph.pt, &netfs_queue_func);
-
-	st->socket->ops->poll(NULL, st->socket, &ph.pt);
-	return 0;
-}
-
-/*
- * Get response for readpage command. We search inode and page in its mapping
- * and copy data into. If it was async request, then we queue page into shared
- * data and wakeup listener, who will copy it to userspace.
- *
- * There is a work in progress of allowing to call copy_to_user() directly from
- * async receiving kernel thread.
- */
-static int pohmelfs_read_page_response(struct netfs_state *st)
-{
-	struct pohmelfs_sb *psb = st->psb;
-	struct netfs_cmd *cmd = &st->cmd;
-	struct inode *inode;
-	struct page *page;
-	int err = 0;
-
-	if (cmd->size > PAGE_CACHE_SIZE) {
-		err = -EINVAL;
-		goto err_out_exit;
-	}
-
-	inode = ilookup(st->psb->sb, cmd->id);
-	if (!inode) {
-		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
-		err = -ENOENT;
-		goto err_out_exit;
-	}
-
-	page = find_get_page(inode->i_mapping, cmd->start >> PAGE_CACHE_SHIFT);
-	if (!page || !PageLocked(page)) {
-		printk("%s: failed to find/lock page: page: %p, id: %llu, start: %llu, index: %llu.\n",
-				__func__, page, cmd->id, cmd->start, cmd->start >> PAGE_CACHE_SHIFT);
-
-		while (cmd->size) {
-			unsigned int sz = min(cmd->size, st->size);
-
-			err = pohmelfs_data_recv(st, st->data, sz);
-			if (err)
-				break;
-
-			cmd->size -= sz;
-		}
-
-		err = -ENODEV;
-		if (page)
-			goto err_out_page_put;
-		goto err_out_put;
-	}
-
-	if (cmd->size) {
-		void *addr;
-
-		addr = kmap(page);
-		err = pohmelfs_data_recv(st, addr, cmd->size);
-		kunmap(page);
-
-		if (err)
-			goto err_out_page_unlock;
-	}
-
-	dprintk("%s: page: %p, start: %llu, size: %u, locked: %d.\n",
-		__func__, page, cmd->start, cmd->size, PageLocked(page));
-
-	SetPageChecked(page);
-	if ((psb->hash_string || psb->cipher_string) && psb->perform_crypto && cmd->size) {
-		err = pohmelfs_crypto_process_input_page(&st->eng, page, cmd->size, cmd->iv);
-		if (err < 0)
-			goto err_out_page_unlock;
-	} else {
-		SetPageUptodate(page);
-		unlock_page(page);
-		page_cache_release(page);
-	}
-
-	pohmelfs_put_inode(POHMELFS_I(inode));
-	wake_up(&st->psb->wait);
-
-	return 0;
-
-err_out_page_unlock:
-	SetPageError(page);
-	unlock_page(page);
-err_out_page_put:
-	page_cache_release(page);
-err_out_put:
-	pohmelfs_put_inode(POHMELFS_I(inode));
-err_out_exit:
-	wake_up(&st->psb->wait);
-	return err;
-}
-
-static int pohmelfs_check_name(struct pohmelfs_inode *parent, struct qstr *str,
-		struct netfs_inode_info *info)
-{
-	struct inode *inode;
-	struct pohmelfs_name *n;
-	int err = 0;
-	u64 ino = 0;
-
-	mutex_lock(&parent->offset_lock);
-	n = pohmelfs_search_hash(parent, str->hash);
-	if (n)
-		ino = n->ino;
-	mutex_unlock(&parent->offset_lock);
-
-	if (!ino)
-		goto out;
-
-	inode = ilookup(parent->vfs_inode.i_sb, ino);
-	if (!inode)
-		goto out;
-
-	dprintk("%s: parent: %llu, inode: %llu.\n", __func__, parent->ino, ino);
-
-	pohmelfs_fill_inode(inode, info);
-	pohmelfs_put_inode(POHMELFS_I(inode));
-	err = -EEXIST;
-out:
-	return err;
-}
-
-/*
- * Readdir response from server. If special field is set, we wakeup
- * listener (readdir() call), which will copy data to userspace.
- */
-static int pohmelfs_readdir_response(struct netfs_state *st)
-{
-	struct inode *inode;
-	struct netfs_cmd *cmd = &st->cmd;
-	struct netfs_inode_info *info;
-	struct pohmelfs_inode *parent = NULL, *npi;
-	int err = 0, last = cmd->ext;
-	struct qstr str;
-
-	if (cmd->size > st->size)
-		return -EINVAL;
-
-	inode = ilookup(st->psb->sb, cmd->id);
-	if (!inode) {
-		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
-		return -ENOENT;
-	}
-	parent = POHMELFS_I(inode);
-
-	if (!cmd->size && cmd->start) {
-		err = -cmd->start;
-		goto out;
-	}
-
-	if (cmd->size) {
-		char *name;
-
-		err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
-		if (err)
-			goto err_out_put;
-
-		info = (struct netfs_inode_info *)(st->data);
-
-		name = (char *)(info + 1);
-		str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
-		name[str.len] = 0;
-		str.name = name;
-		str.hash = jhash(str.name, str.len, 0);
-
-		netfs_convert_inode_info(info);
-
-		if (parent) {
-			err = pohmelfs_check_name(parent, &str, info);
-			if (err) {
-				if (err == -EEXIST)
-					err = 0;
-				goto out;
-			}
-		}
-
-		info->ino = cmd->start;
-		if (!info->ino)
-			info->ino = pohmelfs_new_ino(st->psb);
-
-		dprintk("%s: parent: %llu, ino: %llu, name: '%s', hash: %x, len: %u, mode: %o.\n",
-				__func__, parent->ino, info->ino, str.name, str.hash, str.len,
-				info->mode);
-
-		npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
-		if (IS_ERR(npi)) {
-			err = PTR_ERR(npi);
-
-			if (err != -EEXIST)
-				goto err_out_put;
-		} else {
-			struct dentry *dentry, *alias, *pd;
-
-			set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
-			clear_bit(NETFS_INODE_OWNED, &npi->state);
-
-			pd = d_find_alias(&parent->vfs_inode);
-			if (pd) {
-				str.hash = full_name_hash(str.name, str.len);
-				dentry = d_alloc(pd, &str);
-				if (dentry) {
-					alias = d_materialise_unique(dentry, &npi->vfs_inode);
-					if (alias)
-						dput(alias);
-				}
-
-				dput(dentry);
-				dput(pd);
-			}
-		}
-	}
-out:
-	if (last) {
-		set_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
-		set_bit(NETFS_INODE_REMOTE_SYNCED, &parent->state);
-		wake_up(&st->psb->wait);
-	}
-	pohmelfs_put_inode(parent);
-
-	return err;
-
-err_out_put:
-	clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
-	printk("%s: parent: %llu, ino: %llu, cmd_id: %llu.\n", __func__, parent->ino, cmd->start, cmd->id);
-	pohmelfs_put_inode(parent);
-	wake_up(&st->psb->wait);
-	return err;
-}
-
-/*
- * Lookup command response.
- * It searches for inode to be looked at (if it exists) and substitutes
- * its inode information (size, permission, mode and so on), if inode does
- * not exist, new one will be created and inserted into caches.
- */
-static int pohmelfs_lookup_response(struct netfs_state *st)
-{
-	struct inode *inode = NULL;
-	struct netfs_cmd *cmd = &st->cmd;
-	struct netfs_inode_info *info;
-	struct pohmelfs_inode *parent = NULL, *npi;
-	int err = -EINVAL;
-	char *name;
-
-	inode = ilookup(st->psb->sb, cmd->id);
-	if (!inode) {
-		printk("%s: lookup response: id: %llu, start: %llu, size: %u.\n",
-				__func__, cmd->id, cmd->start, cmd->size);
-		err = -ENOENT;
-		goto err_out_exit;
-	}
-	parent = POHMELFS_I(inode);
-
-	if (!cmd->size) {
-		err = -cmd->start;
-		goto err_out_put;
-	}
-
-	if (cmd->size < sizeof(struct netfs_inode_info)) {
-		printk("%s: broken lookup response: id: %llu, start: %llu, size: %u.\n",
-				__func__, cmd->id, cmd->start, cmd->size);
-		err = -EINVAL;
-		goto err_out_put;
-	}
-
-	err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
-	if (err)
-		goto err_out_put;
-
-	info = (struct netfs_inode_info *)(st->data);
-	name = (char *)(info + 1);
-
-	netfs_convert_inode_info(info);
-
-	info->ino = cmd->start;
-	if (!info->ino)
-		info->ino = pohmelfs_new_ino(st->psb);
-
-	dprintk("%s: parent: %llu, ino: %llu, name: '%s', start: %llu.\n",
-			__func__, parent->ino, info->ino, name, cmd->start);
-
-	if (cmd->start)
-		npi = pohmelfs_new_inode(st->psb, parent, NULL, info, 0);
-	else {
-		struct qstr str;
-
-		str.name = name;
-		str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
-		str.hash = jhash(name, str.len, 0);
-
-		npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
-	}
-	if (IS_ERR(npi)) {
-		err = PTR_ERR(npi);
-
-		if (err != -EEXIST)
-			goto err_out_put;
-	} else {
-		set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
-		clear_bit(NETFS_INODE_OWNED, &npi->state);
-	}
-
-	clear_bit(NETFS_COMMAND_PENDING, &parent->state);
-	pohmelfs_put_inode(parent);
-
-	wake_up(&st->psb->wait);
-
-	return 0;
-
-err_out_put:
-	pohmelfs_put_inode(parent);
-err_out_exit:
-	clear_bit(NETFS_COMMAND_PENDING, &parent->state);
-	wake_up(&st->psb->wait);
-	printk("%s: inode: %p, id: %llu, start: %llu, size: %u, err: %d.\n",
-			__func__, inode, cmd->id, cmd->start, cmd->size, err);
-	return err;
-}
-
-/*
- * Create response, just marks local inode as 'created', so that writeback
- * for any of its children (or own) would not try to sync it again.
- */
-static int pohmelfs_create_response(struct netfs_state *st)
-{
-	struct inode *inode;
-	struct netfs_cmd *cmd = &st->cmd;
-	struct pohmelfs_inode *pi;
-
-	inode = ilookup(st->psb->sb, cmd->id);
-	if (!inode) {
-		printk("%s: failed to find inode: id: %llu, start: %llu.\n",
-				__func__, cmd->id, cmd->start);
-		goto err_out_exit;
-	}
-
-	pi = POHMELFS_I(inode);
-
-	/*
-	 * To lock or not to lock?
-	 * We actually do not care if it races...
-	 */
-	if (cmd->start)
-		make_bad_inode(inode);
-	set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
-
-	pohmelfs_put_inode(pi);
-
-	wake_up(&st->psb->wait);
-	return 0;
-
-err_out_exit:
-	wake_up(&st->psb->wait);
-	return -ENOENT;
-}
-
-/*
- * Object remove response. Just says that remove request has been received.
- * Used in cache coherency protocol.
- */
-static int pohmelfs_remove_response(struct netfs_state *st)
-{
-	struct netfs_cmd *cmd = &st->cmd;
-	int err;
-
-	err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
-	if (err)
-		return err;
-
-	dprintk("%s: parent: %llu, path: '%s'.\n", __func__, cmd->id, (char *)st->data);
-
-	return 0;
-}
-
-/*
- * Transaction reply processing.
- *
- * Find transaction based on its generation number, bump its reference counter,
- * so that none could free it under us, drop from the trees and lists and
- * drop reference counter. When it hits zero (when all destinations replied
- * and all timeout handled by async scanning code), completion will be called
- * and transaction will be freed.
- */
-static int pohmelfs_transaction_response(struct netfs_state *st)
-{
-	struct netfs_trans_dst *dst;
-	struct netfs_trans *t = NULL;
-	struct netfs_cmd *cmd = &st->cmd;
-	short err = (signed)cmd->ext;
-
-	mutex_lock(&st->trans_lock);
-	dst = netfs_trans_search(st, cmd->start);
-	if (dst) {
-		netfs_trans_remove_nolock(dst, st);
-		t = dst->trans;
-	}
-	mutex_unlock(&st->trans_lock);
-
-	if (!t) {
-		printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u.\n",
-				__func__, cmd->start, cmd->id, cmd->size, cmd->ext);
-		err = -EINVAL;
-		goto out;
-	}
-
-	t->result = err;
-	netfs_trans_drop_dst_nostate(dst);
-
-out:
-	wake_up(&st->psb->wait);
-	return err;
-}
-
-/*
- * Inode metadata cache coherency message.
- */
-static int pohmelfs_page_cache_response(struct netfs_state *st)
-{
-	struct netfs_cmd *cmd = &st->cmd;
-	struct inode *inode;
-
-	dprintk("%s: st: %p, id: %llu, start: %llu, size: %u.\n", __func__, st, cmd->id, cmd->start, cmd->size);
-
-	inode = ilookup(st->psb->sb, cmd->id);
-	if (!inode) {
-		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
-		return -ENOENT;
-	}
-
-	set_bit(NETFS_INODE_NEED_FLUSH, &POHMELFS_I(inode)->state);
-	pohmelfs_put_inode(POHMELFS_I(inode));
-
-	return 0;
-}
-
-/*
- * Root capabilities response: export statistics
- * like used and available size, number of files and dirs,
- * permissions.
- */
-static int pohmelfs_root_cap_response(struct netfs_state *st)
-{
-	struct netfs_cmd *cmd = &st->cmd;
-	struct netfs_root_capabilities *cap;
-	struct pohmelfs_sb *psb = st->psb;
-
-	if (cmd->size != sizeof(struct netfs_root_capabilities)) {
-		psb->flags = EPROTO;
-		wake_up(&psb->wait);
-		return -EPROTO;
-	}
-
-	cap = st->data;
-
-	netfs_convert_root_capabilities(cap);
-
-	if (psb->total_size < cap->used + cap->avail)
-		psb->total_size = cap->used + cap->avail;
-	if (cap->avail)
-		psb->avail_size = cap->avail;
-	psb->state_flags = cap->flags;
-
-	if (psb->state_flags & POHMELFS_FLAGS_RO) {
-		psb->sb->s_flags |= MS_RDONLY;
-		printk(KERN_INFO "Mounting POHMELFS (%d) read-only.\n", psb->idx);
-	}
-
-	if (psb->state_flags & POHMELFS_FLAGS_XATTR)
-		printk(KERN_INFO "Mounting POHMELFS (%d) "
-			"with extended attributes support.\n", psb->idx);
-
-	if (atomic_long_read(&psb->total_inodes) <= 1)
-		atomic_long_set(&psb->total_inodes, cap->nr_files);
-
-	dprintk("%s: total: %llu, avail: %llu, flags: %llx, inodes: %llu.\n",
-		__func__, psb->total_size, psb->avail_size, psb->state_flags, cap->nr_files);
-
-	psb->flags = 0;
-	wake_up(&psb->wait);
-	return 0;
-}
-
-/*
- * Crypto capabilities of the server, where it says that
- * it supports or does not requested hash/cipher algorithms.
- */
-static int pohmelfs_crypto_cap_response(struct netfs_state *st)
-{
-	struct netfs_cmd *cmd = &st->cmd;
-	struct netfs_crypto_capabilities *cap;
-	struct pohmelfs_sb *psb = st->psb;
-	int err = 0;
-
-	if (cmd->size != sizeof(struct netfs_crypto_capabilities)) {
-		psb->flags = EPROTO;
-		wake_up(&psb->wait);
-		return -EPROTO;
-	}
-
-	cap = st->data;
-
-	dprintk("%s: cipher '%s': %s, hash: '%s': %s.\n",
-			__func__,
-			psb->cipher_string, (cap->cipher_strlen) ? "SUPPORTED" : "NOT SUPPORTED",
-			psb->hash_string, (cap->hash_strlen) ? "SUPPORTED" : "NOT SUPPORTED");
-
-	if (!cap->hash_strlen) {
-		if (psb->hash_strlen && psb->crypto_fail_unsupported)
-			err = -ENOTSUPP;
-		psb->hash_strlen = 0;
-		kfree(psb->hash_string);
-		psb->hash_string = NULL;
-	}
-
-	if (!cap->cipher_strlen) {
-		if (psb->cipher_strlen && psb->crypto_fail_unsupported)
-			err = -ENOTSUPP;
-		psb->cipher_strlen = 0;
-		kfree(psb->cipher_string);
-		psb->cipher_string = NULL;
-	}
-
-	return err;
-}
-
-/*
- * Capabilities handshake response.
- */
-static int pohmelfs_capabilities_response(struct netfs_state *st)
-{
-	struct netfs_cmd *cmd = &st->cmd;
-	int err = 0;
-
-	err = pohmelfs_data_recv(st, st->data, cmd->size);
-	if (err)
-		return err;
-
-	switch (cmd->id) {
-	case POHMELFS_CRYPTO_CAPABILITIES:
-			return pohmelfs_crypto_cap_response(st);
-	case POHMELFS_ROOT_CAPABILITIES:
-			return pohmelfs_root_cap_response(st);
-	default:
-			break;
-	}
-	return -EINVAL;
-}
-
-/*
- * Receiving extended attribute.
- * Does not work properly if received size is more than requested one,
- * it should not happen with current request/reply model though.
- */
-static int pohmelfs_getxattr_response(struct netfs_state *st)
-{
-	struct pohmelfs_sb *psb = st->psb;
-	struct netfs_cmd *cmd = &st->cmd;
-	struct pohmelfs_mcache *m;
-	short error = (signed short)cmd->ext, err;
-	unsigned int sz, total_size;
-
-	m = pohmelfs_mcache_search(psb, cmd->id);
-
-	dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
-		__func__, cmd->id, (m) ? m->gen : 0, error);
-
-	if (!m) {
-		printk("%s: failed to find getxattr cache entry: id: %llu.\n", __func__, cmd->id);
-		return -ENOENT;
-	}
-
-	if (cmd->size) {
-		sz = min_t(unsigned int, cmd->size, m->size);
-		err = pohmelfs_data_recv_and_check(st, m->data, sz);
-		if (err) {
-			error = err;
-			goto out;
-		}
-
-		m->size = sz;
-		total_size = cmd->size - sz;
-
-		while (total_size) {
-			sz = min(total_size, st->size);
-
-			err = pohmelfs_data_recv_and_check(st, st->data, sz);
-			if (err) {
-				error = err;
-				break;
-			}
-
-			total_size -= sz;
-		}
-	}
-
-out:
-	m->err = error;
-	complete(&m->complete);
-	pohmelfs_mcache_put(psb, m);
-
-	return error;
-}
-
-int pohmelfs_data_lock_response(struct netfs_state *st)
-{
-	struct pohmelfs_sb *psb = st->psb;
-	struct netfs_cmd *cmd = &st->cmd;
-	struct pohmelfs_mcache *m;
-	short err = (signed short)cmd->ext;
-	u64 id = cmd->id;
-
-	m = pohmelfs_mcache_search(psb, id);
-
-	dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
-		__func__, cmd->id, (m) ? m->gen : 0, err);
-
-	if (!m) {
-		pohmelfs_data_recv(st, st->data, cmd->size);
-		printk("%s: failed to find data lock response: id: %llu.\n", __func__, cmd->id);
-		return -ENOENT;
-	}
-
-	if (cmd->size)
-		err = pohmelfs_data_recv_and_check(st, &m->info, cmd->size);
-
-	m->err = err;
-	complete(&m->complete);
-	pohmelfs_mcache_put(psb, m);
-
-	return err;
-}
-
-static void __inline__ netfs_state_reset(struct netfs_state *st)
-{
-	netfs_state_lock_send(st);
-	netfs_state_exit(st);
-	netfs_state_init(st);
-	netfs_state_unlock_send(st);
-}
-
-/*
- * Main receiving function, called from dedicated kernel thread.
- */
-static int pohmelfs_recv(void *data)
-{
-	int err = -EINTR;
-	struct netfs_state *st = data;
-	struct netfs_cmd *cmd = &st->cmd;
-
-	while (!kthread_should_stop()) {
-		/*
-		 * If socket will be reset after this statement, then
-		 * pohmelfs_data_recv() will just fail and loop will
-		 * start again, so it can be done without any locks.
-		 *
-		 * st->read_socket is needed to prevents state machine
-		 * breaking between this data reading and subsequent one
-		 * in protocol specific functions during connection reset.
-		 * In case of reset we have to read next command and do
-		 * not expect data for old command to magically appear in
-		 * new connection.
-		 */
-		st->read_socket = st->socket;
-		err = pohmelfs_data_recv(st, cmd, sizeof(struct netfs_cmd));
-		if (err) {
-			msleep(1000);
-			continue;
-		}
-
-		netfs_convert_cmd(cmd);
-
-		dprintk("%s: cmd: %u, id: %llu, start: %llu, size: %u, "
-				"ext: %u, csize: %u, cpad: %u.\n",
-				__func__, cmd->cmd, cmd->id, cmd->start,
-				cmd->size, cmd->ext, cmd->csize, cmd->cpad);
-
-		if (cmd->csize) {
-			struct pohmelfs_crypto_engine *e = &st->eng;
-
-			if (unlikely(cmd->csize > e->size/2)) {
-				netfs_state_reset(st);
-				continue;
-			}
-
-			if (e->hash && unlikely(cmd->csize != st->psb->crypto_attached_size)) {
-				dprintk("%s: cmd: cmd: %u, id: %llu, start: %llu, size: %u, "
-						"csize: %u != digest size %u.\n",
-						__func__, cmd->cmd, cmd->id, cmd->start, cmd->size,
-						cmd->csize, st->psb->crypto_attached_size);
-				netfs_state_reset(st);
-				continue;
-			}
-
-			err = pohmelfs_data_recv(st, e->data, cmd->csize);
-			if (err) {
-				netfs_state_reset(st);
-				continue;
-			}
-
-#ifdef CONFIG_POHMELFS_DEBUG
-			{
-				unsigned int i;
-				unsigned char *hash = e->data;
-
-				dprintk("%s: received hash: ", __func__);
-				for (i = 0; i < cmd->csize; ++i)
-					printk("%02x ", hash[i]);
-
-				printk("\n");
-			}
-#endif
-			cmd->size -= cmd->csize;
-		}
-
-		/*
-		 * This should catch protocol breakage and random garbage instead of commands.
-		 */
-		if (unlikely((cmd->size > st->size) && (cmd->cmd != NETFS_XATTR_GET))) {
-			netfs_state_reset(st);
-			continue;
-		}
-
-		switch (cmd->cmd) {
-		case NETFS_READ_PAGE:
-				err = pohmelfs_read_page_response(st);
-				break;
-		case NETFS_READDIR:
-				err = pohmelfs_readdir_response(st);
-				break;
-		case NETFS_LOOKUP:
-				err = pohmelfs_lookup_response(st);
-				break;
-		case NETFS_CREATE:
-				err = pohmelfs_create_response(st);
-				break;
-		case NETFS_REMOVE:
-				err = pohmelfs_remove_response(st);
-				break;
-		case NETFS_TRANS:
-				err = pohmelfs_transaction_response(st);
-				break;
-		case NETFS_PAGE_CACHE:
-				err = pohmelfs_page_cache_response(st);
-				break;
-		case NETFS_CAPABILITIES:
-				err = pohmelfs_capabilities_response(st);
-				break;
-		case NETFS_LOCK:
-				err = pohmelfs_data_lock_response(st);
-				break;
-		case NETFS_XATTR_GET:
-				err = pohmelfs_getxattr_response(st);
-				break;
-		default:
-				printk("%s: wrong cmd: %u, id: %llu, start: %llu, size: %u, ext: %u.\n",
-					__func__, cmd->cmd, cmd->id, cmd->start, cmd->size, cmd->ext);
-				netfs_state_reset(st);
-				break;
-		}
-	}
-
-	while (!kthread_should_stop())
-		schedule_timeout_uninterruptible(msecs_to_jiffies(10));
-
-	return err;
-}
-
-int netfs_state_init(struct netfs_state *st)
-{
-	int err;
-	struct pohmelfs_ctl *ctl = &st->ctl;
-
-	err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &st->socket);
-	if (err) {
-		printk("%s: failed to create a socket: family: %d, type: %d, proto: %d, err: %d.\n",
-				__func__, ctl->addr.sa_family, ctl->type, ctl->proto, err);
-		goto err_out_exit;
-	}
-
-	st->socket->sk->sk_allocation = GFP_NOIO;
-	st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
-
-	err = kernel_connect(st->socket, (struct sockaddr *)&ctl->addr, ctl->addrlen, 0);
-	if (err) {
-		printk("%s: failed to connect to server: idx: %u, err: %d.\n",
-				__func__, st->psb->idx, err);
-		goto err_out_release;
-	}
-	st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
-
-	err = netfs_poll_init(st);
-	if (err)
-		goto err_out_release;
-
-	if (st->socket->ops->family == AF_INET) {
-		struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
-		printk(KERN_INFO "%s: (re)connected to peer %pi4:%d.\n", __func__,
-			&sin->sin_addr.s_addr, ntohs(sin->sin_port));
-	} else if (st->socket->ops->family == AF_INET6) {
-		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
-		printk(KERN_INFO "%s: (re)connected to peer %pi6:%d", __func__,
-				&sin->sin6_addr, ntohs(sin->sin6_port));
-	}
-
-	return 0;
-
-err_out_release:
-	sock_release(st->socket);
-err_out_exit:
-	st->socket = NULL;
-	return err;
-}
-
-void netfs_state_exit(struct netfs_state *st)
-{
-	if (st->socket) {
-		netfs_poll_exit(st);
-		st->socket->ops->shutdown(st->socket, 2);
-
-		if (st->socket->ops->family == AF_INET) {
-			struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
-			printk(KERN_INFO "%s: disconnected from peer %pi4:%d.\n", __func__,
-				&sin->sin_addr.s_addr, ntohs(sin->sin_port));
-		} else if (st->socket->ops->family == AF_INET6) {
-			struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
-			printk(KERN_INFO "%s: disconnected from peer %pi6:%d", __func__,
-				&sin->sin6_addr, ntohs(sin->sin6_port));
-		}
-
-		sock_release(st->socket);
-		st->socket = NULL;
-		st->read_socket = NULL;
-		st->need_reset = 0;
-	}
-}
-
-int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf)
-{
-	struct netfs_state *st = &conf->state;
-	int err = -ENOMEM;
-
-	mutex_init(&st->__state_lock);
-	mutex_init(&st->__state_send_lock);
-	init_waitqueue_head(&st->thread_wait);
-
-	st->psb = psb;
-	st->trans_root = RB_ROOT;
-	mutex_init(&st->trans_lock);
-
-	st->size = psb->trans_data_size;
-	st->data = kmalloc(st->size, GFP_KERNEL);
-	if (!st->data)
-		goto err_out_exit;
-
-	if (psb->perform_crypto) {
-		err = pohmelfs_crypto_engine_init(&st->eng, psb);
-		if (err)
-			goto err_out_free_data;
-	}
-
-	err = netfs_state_init(st);
-	if (err)
-		goto err_out_free_engine;
-
-	st->thread = kthread_run(pohmelfs_recv, st, "pohmelfs/%u", psb->idx);
-	if (IS_ERR(st->thread)) {
-		err = PTR_ERR(st->thread);
-		goto err_out_netfs_exit;
-	}
-
-	if (!psb->active_state)
-		psb->active_state = conf;
-
-	dprintk("%s: conf: %p, st: %p, socket: %p.\n",
-			__func__, conf, st, st->socket);
-	return 0;
-
-err_out_netfs_exit:
-	netfs_state_exit(st);
-err_out_free_engine:
-	pohmelfs_crypto_engine_exit(&st->eng);
-err_out_free_data:
-	kfree(st->data);
-err_out_exit:
-	return err;
-
-}
-
-void pohmelfs_state_flush_transactions(struct netfs_state *st)
-{
-	struct rb_node *rb_node;
-	struct netfs_trans_dst *dst;
-
-	mutex_lock(&st->trans_lock);
-	for (rb_node = rb_first(&st->trans_root); rb_node; ) {
-		dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
-		rb_node = rb_next(rb_node);
-
-		dst->trans->result = -EINVAL;
-		netfs_trans_remove_nolock(dst, st);
-		netfs_trans_drop_dst_nostate(dst);
-	}
-	mutex_unlock(&st->trans_lock);
-}
-
-static void pohmelfs_state_exit_one(struct pohmelfs_config *c)
-{
-	struct netfs_state *st = &c->state;
-
-	dprintk("%s: exiting, st: %p.\n", __func__, st);
-	if (st->thread) {
-		kthread_stop(st->thread);
-		st->thread = NULL;
-	}
-
-	netfs_state_lock_send(st);
-	netfs_state_exit(st);
-	netfs_state_unlock_send(st);
-
-	pohmelfs_state_flush_transactions(st);
-
-	pohmelfs_crypto_engine_exit(&st->eng);
-	kfree(st->data);
-
-	kfree(c);
-}
-
-/*
- * Initialize network stack. It searches for given ID in global
- * configuration table, this contains information of the remote server
- * (address (any supported by socket interface) and port, protocol and so on).
- */
-int pohmelfs_state_init(struct pohmelfs_sb *psb)
-{
-	int err = -ENOMEM;
-
-	err = pohmelfs_copy_config(psb);
-	if (err) {
-		pohmelfs_state_exit(psb);
-		return err;
-	}
-
-	return 0;
-}
-
-void pohmelfs_state_exit(struct pohmelfs_sb *psb)
-{
-	struct pohmelfs_config *c, *tmp;
-
-	list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
-		list_del(&c->config_entry);
-		pohmelfs_state_exit_one(c);
-	}
-}
-
-void pohmelfs_switch_active(struct pohmelfs_sb *psb)
-{
-	struct pohmelfs_config *c = psb->active_state;
-
-	if (!list_empty(&psb->state_list)) {
-		if (c->config_entry.next != &psb->state_list) {
-			psb->active_state = list_entry(c->config_entry.next,
-				struct pohmelfs_config, config_entry);
-		} else {
-			psb->active_state = list_entry(psb->state_list.next,
-				struct pohmelfs_config, config_entry);
-		}
-
-		dprintk("%s: empty: %d, active %p -> %p.\n",
-			__func__, list_empty(&psb->state_list), c,
-			psb->active_state);
-	} else
-		psb->active_state = NULL;
-}
-
-void pohmelfs_check_states(struct pohmelfs_sb *psb)
-{
-	struct pohmelfs_config *c, *tmp;
-	LIST_HEAD(delete_list);
-
-	mutex_lock(&psb->state_lock);
-	list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
-		if (pohmelfs_config_check(c, psb->idx)) {
-
-			if (psb->active_state == c)
-				pohmelfs_switch_active(psb);
-			list_move(&c->config_entry, &delete_list);
-		}
-	}
-	pohmelfs_copy_config(psb);
-	mutex_unlock(&psb->state_lock);
-
-	list_for_each_entry_safe(c, tmp, &delete_list, config_entry) {
-		list_del(&c->config_entry);
-		pohmelfs_state_exit_one(c);
-	}
-}
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
deleted file mode 100644
index f26894f..0000000
--- a/drivers/staging/pohmelfs/netfs.h
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#ifndef __NETFS_H
-#define __NETFS_H
-
-#include <linux/types.h>
-#include <linux/connector.h>
-#include <linux/backing-dev.h>
-
-#define POHMELFS_CN_IDX			5
-#define POHMELFS_CN_VAL			0
-
-#define POHMELFS_CTLINFO_ACK		1
-#define POHMELFS_NOINFO_ACK		2
-
-#define POHMELFS_NULL_IDX		65535
-
-/*
- * Network command structure.
- * Will be extended.
- */
-struct netfs_cmd {
-	__u16			cmd;	/* Command number */
-	__u16			csize;	/* Attached crypto information size */
-	__u16			cpad;	/* Attached padding size */
-	__u16			ext;	/* External flags */
-	__u32			size;	/* Size of the attached data */
-	__u32			trans;	/* Transaction id */
-	__u64			id;	/* Object ID to operate on. Used for feedback.*/
-	__u64			start;	/* Start of the object. */
-	__u64			iv;	/* IV sequence */
-	__u8			data[0];
-};
-
-static inline void netfs_convert_cmd(struct netfs_cmd *cmd)
-{
-	cmd->id = __be64_to_cpu(cmd->id);
-	cmd->start = __be64_to_cpu(cmd->start);
-	cmd->iv = __be64_to_cpu(cmd->iv);
-	cmd->cmd = __be16_to_cpu(cmd->cmd);
-	cmd->ext = __be16_to_cpu(cmd->ext);
-	cmd->csize = __be16_to_cpu(cmd->csize);
-	cmd->cpad = __be16_to_cpu(cmd->cpad);
-	cmd->size = __be32_to_cpu(cmd->size);
-}
-
-#define NETFS_TRANS_SINGLE_DST		(1<<0)
-
-enum {
-	NETFS_READDIR	= 1,	/* Read directory for given inode number */
-	NETFS_READ_PAGE,	/* Read data page from the server */
-	NETFS_WRITE_PAGE,	/* Write data page to the server */
-	NETFS_CREATE,		/* Create directory entry */
-	NETFS_REMOVE,		/* Remove directory entry */
-
-	NETFS_LOOKUP,		/* Lookup single object */
-	NETFS_LINK,		/* Create a link */
-	NETFS_TRANS,		/* Transaction */
-	NETFS_OPEN,		/* Open intent */
-	NETFS_INODE_INFO,	/* Metadata cache coherency synchronization message */
-
-	NETFS_PAGE_CACHE,	/* Page cache invalidation message */
-	NETFS_READ_PAGES,	/* Read multiple contiguous pages in one go */
-	NETFS_RENAME,		/* Rename object */
-	NETFS_CAPABILITIES,	/* Capabilities of the client, for example supported crypto */
-	NETFS_LOCK,		/* Distributed lock message */
-
-	NETFS_XATTR_SET,	/* Set extended attribute */
-	NETFS_XATTR_GET,	/* Get extended attribute */
-	NETFS_CMD_MAX
-};
-
-enum {
-	POHMELFS_FLAGS_ADD = 0, /* Network state control message for ADD */
-	POHMELFS_FLAGS_DEL,     /* Network state control message for DEL */
-	POHMELFS_FLAGS_SHOW,    /* Network state control message for SHOW */
-	POHMELFS_FLAGS_CRYPTO,	/* Crypto data control message */
-	POHMELFS_FLAGS_MODIFY,	/* Network state modification message */
-	POHMELFS_FLAGS_DUMP,	/* Network state control message for SHOW ALL */
-	POHMELFS_FLAGS_FLUSH,	/* Network state control message for FLUSH */
-};
-
-/*
- * Always wanted to copy it from socket headers into public one,
- * since they are __KERNEL__ protected there.
- */
-#define _K_SS_MAXSIZE	128
-
-struct saddr {
-	unsigned short		sa_family;
-	char			addr[_K_SS_MAXSIZE];
-};
-
-enum {
-	POHMELFS_CRYPTO_HASH = 0,
-	POHMELFS_CRYPTO_CIPHER,
-};
-
-struct pohmelfs_crypto {
-	unsigned int		idx;		/* Config index */
-	unsigned short		strlen;		/* Size of the attached crypto string including 0-byte
-						 * "cbc(aes)" for example */
-	unsigned short		type;		/* HMAC, cipher, both */
-	unsigned int		keysize;	/* Key size */
-	unsigned char		data[0];	/* Algorithm string, key and IV */
-};
-
-#define POHMELFS_IO_PERM_READ		(1<<0)
-#define POHMELFS_IO_PERM_WRITE		(1<<1)
-
-/*
- * Configuration command used to create table of different remote servers.
- */
-struct pohmelfs_ctl {
-	__u32			idx;		/* Config index */
-	__u32			type;		/* Socket type */
-	__u32			proto;		/* Socket protocol */
-	__u16			addrlen;	/* Size of the address */
-	__u16			perm;		/* IO permission */
-	__u16			prio;		/* IO priority */
-	struct saddr		addr;		/* Remote server address */
-};
-
-/*
- * Ack for userspace about requested command.
- */
-struct pohmelfs_cn_ack {
-	struct cn_msg		msg;
-	int			error;
-	int			msg_num;
-	int			unused[3];
-	struct pohmelfs_ctl	ctl;
-};
-
-/*
- * Inode info structure used to sync with server.
- * Check what stat() returns.
- */
-struct netfs_inode_info {
-	unsigned int		mode;
-	unsigned int		nlink;
-	unsigned int		uid;
-	unsigned int		gid;
-	unsigned int		blocksize;
-	unsigned int		padding;
-	__u64			ino;
-	__u64			blocks;
-	__u64			rdev;
-	__u64			size;
-	__u64			version;
-};
-
-static inline void netfs_convert_inode_info(struct netfs_inode_info *info)
-{
-	info->mode = __cpu_to_be32(info->mode);
-	info->nlink = __cpu_to_be32(info->nlink);
-	info->uid = __cpu_to_be32(info->uid);
-	info->gid = __cpu_to_be32(info->gid);
-	info->blocksize = __cpu_to_be32(info->blocksize);
-	info->blocks = __cpu_to_be64(info->blocks);
-	info->rdev = __cpu_to_be64(info->rdev);
-	info->size = __cpu_to_be64(info->size);
-	info->version = __cpu_to_be64(info->version);
-	info->ino = __cpu_to_be64(info->ino);
-}
-
-/*
- * Cache state machine.
- */
-enum {
-	NETFS_COMMAND_PENDING = 0,	/* Command is being executed */
-	NETFS_INODE_REMOTE_SYNCED,	/* Inode was synced to server */
-	NETFS_INODE_REMOTE_DIR_SYNCED,	/* Inode (directory) was synced from the server */
-	NETFS_INODE_OWNED,		/* Inode is owned by given host */
-	NETFS_INODE_NEED_FLUSH,		/* Inode has to be flushed to the server */
-};
-
-/*
- * POHMELFS capabilities: information about supported
- * crypto operations (hash/cipher, modes, key sizes and so on),
- * root information (used/available size, number of objects, permissions)
- */
-enum pohmelfs_capabilities {
-	POHMELFS_CRYPTO_CAPABILITIES = 0,
-	POHMELFS_ROOT_CAPABILITIES,
-};
-
-/* Read-only mount */
-#define POHMELFS_FLAGS_RO		(1<<0)
-/* Extended attributes support on/off */
-#define POHMELFS_FLAGS_XATTR		(1<<1)
-
-struct netfs_root_capabilities {
-	__u64			nr_files;
-	__u64			used, avail;
-	__u64			flags;
-};
-
-static inline void netfs_convert_root_capabilities(struct netfs_root_capabilities *cap)
-{
-	cap->nr_files = __cpu_to_be64(cap->nr_files);
-	cap->used = __cpu_to_be64(cap->used);
-	cap->avail = __cpu_to_be64(cap->avail);
-	cap->flags = __cpu_to_be64(cap->flags);
-}
-
-struct netfs_crypto_capabilities {
-	unsigned short		hash_strlen;	/* Hash string length, like "hmac(sha1) including 0 byte "*/
-	unsigned short		cipher_strlen;	/* Cipher string length with the same format */
-	unsigned int		cipher_keysize;	/* Cipher key size */
-};
-
-static inline void netfs_convert_crypto_capabilities(struct netfs_crypto_capabilities *cap)
-{
-	cap->hash_strlen = __cpu_to_be16(cap->hash_strlen);
-	cap->cipher_strlen = __cpu_to_be16(cap->cipher_strlen);
-	cap->cipher_keysize = __cpu_to_be32(cap->cipher_keysize);
-}
-
-enum pohmelfs_lock_type {
-	POHMELFS_LOCK_GRAB	= (1<<15),
-
-	POHMELFS_READ_LOCK	= 0,
-	POHMELFS_WRITE_LOCK,
-};
-
-struct netfs_lock {
-	__u64			start;
-	__u64			ino;
-	__u32			size;
-	__u32			type;
-};
-
-static inline void netfs_convert_lock(struct netfs_lock *lock)
-{
-	lock->start = __cpu_to_be64(lock->start);
-	lock->ino = __cpu_to_be64(lock->ino);
-	lock->size = __cpu_to_be32(lock->size);
-	lock->type = __cpu_to_be32(lock->type);
-}
-
-#ifdef __KERNEL__
-
-#include <linux/kernel.h>
-#include <linux/completion.h>
-#include <linux/rbtree.h>
-#include <linux/net.h>
-#include <linux/poll.h>
-
-/*
- * Private POHMELFS cache of objects in directory.
- */
-struct pohmelfs_name {
-	struct rb_node		hash_node;
-
-	struct list_head	sync_create_entry;
-
-	u64			ino;
-
-	u32			hash;
-	u32			mode;
-	u32			len;
-
-	char			*data;
-};
-
-/*
- * POHMELFS inode. Main object.
- */
-struct pohmelfs_inode {
-	struct list_head	inode_entry;		/* Entry in superblock list.
-							 * Objects which are not bound to dentry require to be dropped
-							 * in ->put_super()
-							 */
-	struct rb_root		hash_root;		/* The same, but indexed by name hash and len */
-	struct mutex		offset_lock;		/* Protect both above trees */
-
-	struct list_head	sync_create_list;	/* List of created but not yet synced to the server children */
-
-	unsigned int		drop_count;
-
-	int			lock_type;		/* How this inode is locked: read or write */
-
-	int			error;			/* Transaction error for given inode */
-
-	long			state;			/* State machine above */
-
-	u64			ino;			/* Inode number */
-	u64			total_len;		/* Total length of all children names, used to create offsets */
-
-	struct inode		vfs_inode;
-};
-
-struct netfs_trans;
-typedef int (*netfs_trans_complete_t)(struct page **pages, unsigned int page_num,
-		void *private, int err);
-
-struct netfs_state;
-struct pohmelfs_sb;
-
-struct netfs_trans {
-	/*
-	 * Transaction header and attached contiguous data live here.
-	 */
-	struct iovec			iovec;
-
-	/*
-	 * Pages attached to transaction.
-	 */
-	struct page			**pages;
-
-	/*
-	 * List and protecting lock for transaction destination
-	 * network states.
-	 */
-	spinlock_t			dst_lock;
-	struct list_head		dst_list;
-
-	/*
-	 * Number of users for given transaction.
-	 * For example each network state attached to transaction
-	 * via dst_list increases it.
-	 */
-	atomic_t			refcnt;
-
-	/*
-	 * Number of pages attached to given transaction.
-	 * Some slots in above page array can be NULL, since
-	 * for example page can be under writeback already,
-	 * so we skip it in this transaction.
-	 */
-	unsigned int			page_num;
-
-	/*
-	 * Transaction flags: single dst or broadcast and so on.
-	 */
-	unsigned int			flags;
-
-	/*
-	 * Size of the data, which can be placed into
-	 * iovec.iov_base area.
-	 */
-	unsigned int			total_size;
-
-	/*
-	 * Number of pages to be sent to remote server.
-	 * Usually equal to above page_num, but in case of partial
-	 * writeback it can accumulate only pages already completed
-	 * previous writeback.
-	 */
-	unsigned int			attached_pages;
-
-	/*
-	 * Attached number of bytes in all above pages.
-	 */
-	unsigned int			attached_size;
-
-	/*
-	 * Unique transacton generation number.
-	 * Used as identity in the network state tree of transactions.
-	 */
-	unsigned int			gen;
-
-	/*
-	 * Transaction completion status.
-	 */
-	int				result;
-
-	/*
-	 * Superblock this transaction belongs to
-	 */
-	struct pohmelfs_sb		*psb;
-
-	/*
-	 * Crypto engine, which processed this transaction.
-	 * Can be not NULL only if crypto engine holds encrypted pages.
-	 */
-	struct pohmelfs_crypto_engine	*eng;
-
-	/* Private data */
-	void				*private;
-
-	/* Completion callback, invoked just before transaction is destroyed */
-	netfs_trans_complete_t		complete;
-};
-
-static inline int netfs_trans_cur_len(struct netfs_trans *t)
-{
-	return (signed)(t->total_size - t->iovec.iov_len);
-}
-
-static inline void *netfs_trans_current(struct netfs_trans *t)
-{
-	return t->iovec.iov_base + t->iovec.iov_len;
-}
-
-struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
-		unsigned int flags, unsigned int nr);
-void netfs_trans_free(struct netfs_trans *t);
-int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb);
-int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb);
-
-static inline void netfs_trans_reset(struct netfs_trans *t)
-{
-	t->complete = NULL;
-}
-
-struct netfs_trans_dst {
-	struct list_head		trans_entry;
-	struct rb_node			state_entry;
-
-	unsigned long			send_time;
-
-	/*
-	 * Times this transaction was resent to its old or new,
-	 * depending on flags, destinations. When it reaches maximum
-	 * allowed number, specified in superblock->trans_retries,
-	 * transaction will be freed with ETIMEDOUT error.
-	 */
-	unsigned int			retries;
-
-	struct netfs_trans		*trans;
-	struct netfs_state		*state;
-};
-
-struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen);
-void netfs_trans_drop_dst(struct netfs_trans_dst *dst);
-void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst);
-void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st);
-void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st);
-int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb);
-int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st);
-
-int netfs_trans_init(void);
-void netfs_trans_exit(void);
-
-struct pohmelfs_crypto_engine {
-	u64				iv;		/* Crypto IV for current operation */
-	unsigned long			timeout;	/* Crypto waiting timeout */
-	unsigned int			size;		/* Size of crypto scratchpad */
-	void				*data;		/* Temporal crypto scratchpad */
-	/*
-	 * Crypto operations performed on objects.
-	 */
-	struct crypto_hash		*hash;
-	struct crypto_ablkcipher	*cipher;
-
-	struct pohmelfs_crypto_thread	*thread;	/* Crypto thread which hosts this engine */
-
-	struct page			**pages;
-	unsigned int			page_num;
-};
-
-struct pohmelfs_crypto_thread {
-	struct list_head		thread_entry;
-
-	struct task_struct		*thread;
-	struct pohmelfs_sb		*psb;
-
-	struct pohmelfs_crypto_engine	eng;
-
-	struct netfs_trans		*trans;
-
-	wait_queue_head_t		wait;
-	int				error;
-
-	unsigned int			size;
-	struct page			*page;
-};
-
-void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th);
-
-/*
- * Network state, attached to one server.
- */
-struct netfs_state {
-	struct mutex		__state_lock;		/* Can not allow to use the same socket simultaneously */
-	struct mutex		__state_send_lock;
-	struct netfs_cmd	cmd;			/* Cached command */
-	struct netfs_inode_info	info;			/* Cached inode info */
-
-	void			*data;			/* Cached some data */
-	unsigned int		size;			/* Size of that data */
-
-	struct pohmelfs_sb	*psb;			/* Superblock */
-
-	struct task_struct	*thread;		/* Async receiving thread */
-
-	/* Waiting/polling machinery */
-	wait_queue_t		wait;
-	wait_queue_head_t	*whead;
-	wait_queue_head_t	thread_wait;
-
-	struct mutex		trans_lock;
-	struct rb_root		trans_root;
-
-	struct pohmelfs_ctl	ctl;			/* Remote peer */
-
-	struct socket		*socket;		/* Socket object */
-	struct socket		*read_socket;		/* Cached pointer to socket object.
-							 * Used to determine if between lock drops socket was changed.
-							 * Never used to read data or any kind of access.
-							 */
-	/*
-	 * Crypto engines to process incoming data.
-	 */
-	struct pohmelfs_crypto_engine	eng;
-
-	int			need_reset;
-};
-
-int netfs_state_init(struct netfs_state *st);
-void netfs_state_exit(struct netfs_state *st);
-
-static inline void netfs_state_lock_send(struct netfs_state *st)
-{
-	mutex_lock(&st->__state_send_lock);
-}
-
-static inline int netfs_state_trylock_send(struct netfs_state *st)
-{
-	return mutex_trylock(&st->__state_send_lock);
-}
-
-static inline void netfs_state_unlock_send(struct netfs_state *st)
-{
-	BUG_ON(!mutex_is_locked(&st->__state_send_lock));
-
-	mutex_unlock(&st->__state_send_lock);
-}
-
-static inline void netfs_state_lock(struct netfs_state *st)
-{
-	mutex_lock(&st->__state_lock);
-}
-
-static inline void netfs_state_unlock(struct netfs_state *st)
-{
-	BUG_ON(!mutex_is_locked(&st->__state_lock));
-
-	mutex_unlock(&st->__state_lock);
-}
-
-static inline unsigned int netfs_state_poll(struct netfs_state *st)
-{
-	unsigned int revents = POLLHUP | POLLERR;
-
-	netfs_state_lock(st);
-	if (st->socket)
-		revents = st->socket->ops->poll(NULL, st->socket, NULL);
-	netfs_state_unlock(st);
-
-	return revents;
-}
-
-struct pohmelfs_config;
-
-struct pohmelfs_sb {
-	struct rb_root		mcache_root;
-	struct mutex		mcache_lock;
-	atomic_long_t		mcache_gen;
-	unsigned long		mcache_timeout;
-
-	unsigned int		idx;
-
-	unsigned int		trans_retries;
-
-	atomic_t		trans_gen;
-
-	unsigned int		crypto_attached_size;
-	unsigned int		crypto_align_size;
-
-	unsigned int		crypto_fail_unsupported;
-
-	unsigned int		crypto_thread_num;
-	struct list_head	crypto_active_list, crypto_ready_list;
-	struct mutex		crypto_thread_lock;
-
-	unsigned int		trans_max_pages;
-	unsigned long		trans_data_size;
-	unsigned long		trans_timeout;
-
-	unsigned long		drop_scan_timeout;
-	unsigned long		trans_scan_timeout;
-
-	unsigned long		wait_on_page_timeout;
-
-	struct list_head	flush_list;
-	struct list_head	drop_list;
-	spinlock_t		ino_lock;
-	u64			ino;
-
-	/*
-	 * Remote nodes POHMELFS connected to.
-	 */
-	struct list_head	state_list;
-	struct mutex		state_lock;
-
-	/*
-	 * Currently active state to request data from.
-	 */
-	struct pohmelfs_config	*active_state;
-
-
-	wait_queue_head_t	wait;
-
-	/*
-	 * Timed checks: stale transactions, inodes to be freed and so on.
-	 */
-	struct delayed_work	dwork;
-	struct delayed_work	drop_dwork;
-
-	struct super_block	*sb;
-
-	struct backing_dev_info	bdi;
-
-	/*
-	 * Algorithm strings.
-	 */
-	char			*hash_string;
-	char			*cipher_string;
-
-	u8			*hash_key;
-	u8			*cipher_key;
-
-	/*
-	 * Algorithm string lengths.
-	 */
-	unsigned int		hash_strlen;
-	unsigned int		cipher_strlen;
-	unsigned int		hash_keysize;
-	unsigned int		cipher_keysize;
-
-	/*
-	 * Controls whether to perfrom crypto processing or not.
-	 */
-	int			perform_crypto;
-
-	/*
-	 * POHMELFS statistics.
-	 */
-	u64			total_size;
-	u64			avail_size;
-	atomic_long_t		total_inodes;
-
-	/*
-	 * Xattr support, read-only and so on.
-	 */
-	u64			state_flags;
-
-	/*
-	 * Temporary storage to detect changes in the wait queue.
-	 */
-	long			flags;
-};
-
-static inline void netfs_trans_update(struct netfs_cmd *cmd,
-		struct netfs_trans *t, unsigned int size)
-{
-	unsigned int sz = ALIGN(size, t->psb->crypto_align_size);
-
-	t->iovec.iov_len += sizeof(struct netfs_cmd) + sz;
-	cmd->cpad = __cpu_to_be16(sz - size);
-}
-
-static inline struct pohmelfs_sb *POHMELFS_SB(struct super_block *sb)
-{
-	return sb->s_fs_info;
-}
-
-static inline struct pohmelfs_inode *POHMELFS_I(struct inode *inode)
-{
-	return container_of(inode, struct pohmelfs_inode, vfs_inode);
-}
-
-static inline u64 pohmelfs_new_ino(struct pohmelfs_sb *psb)
-{
-	u64 ino;
-
-	spin_lock(&psb->ino_lock);
-	ino = psb->ino++;
-	spin_unlock(&psb->ino_lock);
-
-	return ino;
-}
-
-static inline void pohmelfs_put_inode(struct pohmelfs_inode *pi)
-{
-	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
-
-	spin_lock(&psb->ino_lock);
-	list_move_tail(&pi->inode_entry, &psb->drop_list);
-	pi->drop_count++;
-	spin_unlock(&psb->ino_lock);
-}
-
-struct pohmelfs_config {
-	struct list_head	config_entry;
-
-	struct netfs_state	state;
-};
-
-struct pohmelfs_config_group {
-	/*
-	 * Entry in the global config group list.
-	 */
-	struct list_head	group_entry;
-
-	/*
-	 * Index of the current group.
-	 */
-	unsigned int		idx;
-	/*
-	 * Number of config_list entries in this group entry.
-	 */
-	unsigned int		num_entry;
-	/*
-	 * Algorithm strings.
-	 */
-	char			*hash_string;
-	char			*cipher_string;
-
-	/*
-	 * Algorithm string lengths.
-	 */
-	unsigned int		hash_strlen;
-	unsigned int		cipher_strlen;
-
-	/*
-	 * Key and its size.
-	 */
-	unsigned int		hash_keysize;
-	unsigned int		cipher_keysize;
-	u8			*hash_key;
-	u8			*cipher_key;
-
-	/*
-	 * List of config entries (network state info) for given idx.
-	 */
-	struct list_head	config_list;
-};
-
-int __init pohmelfs_config_init(void);
-void pohmelfs_config_exit(void);
-int pohmelfs_copy_config(struct pohmelfs_sb *psb);
-int pohmelfs_copy_crypto(struct pohmelfs_sb *psb);
-int pohmelfs_config_check(struct pohmelfs_config *config, int idx);
-int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf);
-
-extern const struct file_operations pohmelfs_dir_fops;
-extern const struct inode_operations pohmelfs_dir_inode_ops;
-
-int pohmelfs_state_init(struct pohmelfs_sb *psb);
-void pohmelfs_state_exit(struct pohmelfs_sb *psb);
-void pohmelfs_state_flush_transactions(struct netfs_state *st);
-
-void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info);
-
-void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
-void pohmelfs_free_names(struct pohmelfs_inode *parent);
-struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash);
-
-void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi);
-
-struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
-	struct pohmelfs_inode *parent, struct qstr *str, u64 start, umode_t mode);
-
-int pohmelfs_write_create_inode(struct pohmelfs_inode *pi);
-
-int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans);
-int pohmelfs_remove_child(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
-
-struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
-		struct pohmelfs_inode *parent, struct qstr *str,
-		struct netfs_inode_info *info, int link);
-
-int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr);
-int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr);
-
-int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
-		netfs_trans_complete_t complete, void *priv, u64 start);
-int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
-		unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start);
-
-void pohmelfs_check_states(struct pohmelfs_sb *psb);
-void pohmelfs_switch_active(struct pohmelfs_sb *psb);
-
-int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len);
-int pohmelfs_path_length(struct pohmelfs_inode *pi);
-
-struct pohmelfs_crypto_completion {
-	struct completion	complete;
-	int			error;
-};
-
-int pohmelfs_trans_crypt(struct netfs_trans *t, struct pohmelfs_sb *psb);
-void pohmelfs_crypto_exit(struct pohmelfs_sb *psb);
-int pohmelfs_crypto_init(struct pohmelfs_sb *psb);
-
-int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb);
-void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e);
-
-int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 iv,
-		void *data, struct page *page, unsigned int size);
-int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
-		struct page *page, unsigned int size, u64 iv);
-
-static inline u64 pohmelfs_gen_iv(struct netfs_trans *t)
-{
-	u64 iv = t->gen;
-
-	iv <<= 32;
-	iv |= ((unsigned long)t) & 0xffffffff;
-
-	return iv;
-}
-
-int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
-int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
-int pohmelfs_data_lock_response(struct netfs_state *st);
-
-static inline int pohmelfs_need_lock(struct pohmelfs_inode *pi, int type)
-{
-	if (test_bit(NETFS_INODE_OWNED, &pi->state)) {
-		if (type == pi->lock_type)
-			return 0;
-		if ((type == POHMELFS_READ_LOCK) && (pi->lock_type == POHMELFS_WRITE_LOCK))
-			return 0;
-	}
-
-	if (!test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
-		return 0;
-
-	return 1;
-}
-
-int __init pohmelfs_mcache_init(void);
-void pohmelfs_mcache_exit(void);
-
-/* #define CONFIG_POHMELFS_DEBUG */
-
-#ifdef CONFIG_POHMELFS_DEBUG
-#define dprintka(f, a...) printk(f, ##a)
-#define dprintk(f, a...) printk("%d: " f, task_pid_vnr(current), ##a)
-#else
-#define dprintka(f, a...) do {} while (0)
-#define dprintk(f, a...) do {} while (0)
-#endif
-
-static inline void netfs_trans_get(struct netfs_trans *t)
-{
-	atomic_inc(&t->refcnt);
-}
-
-static inline void netfs_trans_put(struct netfs_trans *t)
-{
-	if (atomic_dec_and_test(&t->refcnt)) {
-		dprintk("%s: t: %p, gen: %u, err: %d.\n",
-			__func__, t, t->gen, t->result);
-		if (t->complete)
-			t->complete(t->pages, t->page_num,
-				t->private, t->result);
-		netfs_trans_free(t);
-	}
-}
-
-struct pohmelfs_mcache {
-	struct rb_node			mcache_entry;
-	struct completion		complete;
-
-	atomic_t			refcnt;
-
-	u64				gen;
-
-	void				*data;
-	u64				start;
-	u32				size;
-	int				err;
-
-	struct netfs_inode_info		info;
-};
-
-struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
-		unsigned int size, void *data);
-void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
-struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen);
-void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
-
-static inline void pohmelfs_mcache_get(struct pohmelfs_mcache *m)
-{
-	atomic_inc(&m->refcnt);
-}
-
-static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
-		struct pohmelfs_mcache *m)
-{
-	if (atomic_dec_and_test(&m->refcnt))
-		pohmelfs_mcache_free(psb, m);
-}
-
-/*#define POHMELFS_TRUNCATE_ON_INODE_FLUSH
- */
-
-#endif /* __KERNEL__*/
-
-#endif /* __NETFS_H */
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c
deleted file mode 100644
index 400a9fc..0000000
--- a/drivers/staging/pohmelfs/path_entry.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/ktime.h>
-#include <linux/fs_struct.h>
-#include <linux/pagemap.h>
-#include <linux/writeback.h>
-#include <linux/mount.h>
-#include <linux/mm.h>
-
-#include "netfs.h"
-
-#define UNHASHED_OBSCURE_STRING_SIZE		sizeof(" (deleted)")
-
-/*
- * Create path from root for given inode.
- * Path is formed as set of stuctures, containing name of the object
- * and its inode data (mode, permissions and so on).
- */
-int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len)
-{
-	struct path path;
-	struct dentry *d;
-	char *ptr;
-	int err = 0, strlen, reduce = 0;
-
-	d = d_find_alias(&pi->vfs_inode);
-	if (!d) {
-		printk("%s: no alias, list_empty: %d.\n", __func__, list_empty(&pi->vfs_inode.i_dentry));
-		return -ENOENT;
-	}
-
-	spin_lock(&current->fs->lock);
-	path.mnt = mntget(current->fs->root.mnt);
-	spin_unlock(&current->fs->lock);
-
-	path.dentry = d;
-
-	if (!IS_ROOT(d) && d_unhashed(d))
-		reduce = 1;
-
-	ptr = d_path(&path, data, len);
-	if (IS_ERR(ptr)) {
-		err = PTR_ERR(ptr);
-		goto out;
-	}
-
-	if (reduce && len >= UNHASHED_OBSCURE_STRING_SIZE) {
-		char *end = data + len - UNHASHED_OBSCURE_STRING_SIZE;
-		*end = '\0';
-	}
-
-	strlen = len - (ptr - (char *)data);
-	memmove(data, ptr, strlen);
-	ptr = data;
-
-	err = strlen;
-
-	dprintk("%s: dname: '%s', len: %u, maxlen: %u, name: '%s', strlen: %d.\n",
-			__func__, d->d_name.name, d->d_name.len, len, ptr, strlen);
-
-out:
-	dput(d);
-	mntput(path.mnt);
-
-	return err;
-}
-
-int pohmelfs_path_length(struct pohmelfs_inode *pi)
-{
-	struct dentry *d, *root, *first;
-	int len;
-	unsigned seq;
-
-	first = d_find_alias(&pi->vfs_inode);
-	if (!first) {
-		dprintk("%s: ino: %llu, mode: %o.\n", __func__, pi->ino, pi->vfs_inode.i_mode);
-		return -ENOENT;
-	}
-
-	spin_lock(&current->fs->lock);
-	root = dget(current->fs->root.dentry);
-	spin_unlock(&current->fs->lock);
-
-rename_retry:
-	len = 1; /* Root slash */
-	d = first;
-	seq = read_seqbegin(&rename_lock);
-	rcu_read_lock();
-
-	if (!IS_ROOT(d) && d_unhashed(d))
-		len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */
-
-	while (d && d != root && !IS_ROOT(d)) {
-		len += d->d_name.len + 1; /* Plus slash */
-		d = d->d_parent;
-	}
-	rcu_read_unlock();
-	if (read_seqretry(&rename_lock, seq))
-		goto rename_retry;
-
-	dput(root);
-	dput(first);
-
-	return len + 1; /* Including zero-byte */
-}
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c
deleted file mode 100644
index 06c1a74..0000000
--- a/drivers/staging/pohmelfs/trans.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/crypto.h>
-#include <linux/fs.h>
-#include <linux/jhash.h>
-#include <linux/hash.h>
-#include <linux/ktime.h>
-#include <linux/mempool.h>
-#include <linux/mm.h>
-#include <linux/mount.h>
-#include <linux/pagemap.h>
-#include <linux/parser.h>
-#include <linux/poll.h>
-#include <linux/swap.h>
-#include <linux/slab.h>
-#include <linux/statfs.h>
-#include <linux/writeback.h>
-
-#include "netfs.h"
-
-static struct kmem_cache *netfs_trans_dst;
-static mempool_t *netfs_trans_dst_pool;
-
-static void netfs_trans_init_static(struct netfs_trans *t, int num, int size)
-{
-	t->page_num = num;
-	t->total_size = size;
-	atomic_set(&t->refcnt, 1);
-
-	spin_lock_init(&t->dst_lock);
-	INIT_LIST_HEAD(&t->dst_list);
-}
-
-static int netfs_trans_send_pages(struct netfs_trans *t, struct netfs_state *st)
-{
-	int err = 0;
-	unsigned int i, attached_pages = t->attached_pages, ci;
-	struct msghdr msg;
-	struct page **pages = (t->eng) ? t->eng->pages : t->pages;
-	struct page *p;
-	unsigned int size;
-
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_flags = MSG_WAITALL | MSG_MORE;
-
-	ci = 0;
-	for (i = 0; i < t->page_num; ++i) {
-		struct page *page = pages[ci];
-		struct netfs_cmd cmd;
-		struct iovec io;
-
-		p = t->pages[i];
-
-		if (!p)
-			continue;
-
-		size = page_private(p);
-
-		io.iov_base = &cmd;
-		io.iov_len = sizeof(struct netfs_cmd);
-
-		cmd.cmd = NETFS_WRITE_PAGE;
-		cmd.ext = 0;
-		cmd.id = 0;
-		cmd.size = size;
-		cmd.start = p->index;
-		cmd.start <<= PAGE_CACHE_SHIFT;
-		cmd.csize = 0;
-		cmd.cpad = 0;
-		cmd.iv = pohmelfs_gen_iv(t);
-
-		netfs_convert_cmd(&cmd);
-
-		msg.msg_iov = &io;
-		msg.msg_iovlen = 1;
-		msg.msg_flags = MSG_WAITALL | MSG_MORE;
-
-		err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, sizeof(struct netfs_cmd));
-		if (err <= 0) {
-			printk("%s: %d/%d failed to send transaction header: t: %p, gen: %u, err: %d.\n",
-					__func__, i, t->page_num, t, t->gen, err);
-			if (err == 0)
-				err = -ECONNRESET;
-			goto err_out;
-		}
-
-		msg.msg_flags = MSG_WAITALL | (attached_pages == 1 ? 0 :
-				MSG_MORE);
-
-		err = kernel_sendpage(st->socket, page, 0, size, msg.msg_flags);
-		if (err <= 0) {
-			printk("%s: %d/%d failed to send transaction page: t: %p, gen: %u, size: %u, err: %d.\n",
-					__func__, i, t->page_num, t, t->gen, size, err);
-			if (err == 0)
-				err = -ECONNRESET;
-			goto err_out;
-		}
-
-		dprintk("%s: %d/%d sent t: %p, gen: %u, page: %p/%p, size: %u.\n",
-			__func__, i, t->page_num, t, t->gen, page, p, size);
-
-		err = 0;
-		attached_pages--;
-		if (!attached_pages)
-			break;
-		ci++;
-
-		continue;
-
-err_out:
-		printk("%s: t: %p, gen: %u, err: %d.\n", __func__, t, t->gen, err);
-		netfs_state_exit(st);
-		break;
-	}
-
-	return err;
-}
-
-int netfs_trans_send(struct netfs_trans *t, struct netfs_state *st)
-{
-	int err;
-	struct msghdr msg;
-
-	BUG_ON(!t->iovec.iov_len);
-	BUG_ON(t->iovec.iov_len > 1024*1024*1024);
-
-	netfs_state_lock_send(st);
-	if (!st->socket) {
-		err = netfs_state_init(st);
-		if (err)
-			goto err_out_unlock_return;
-	}
-
-	msg.msg_iov = &t->iovec;
-	msg.msg_iovlen = 1;
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_flags = MSG_WAITALL;
-
-	if (t->attached_pages)
-		msg.msg_flags |= MSG_MORE;
-
-	err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, t->iovec.iov_len);
-	if (err <= 0) {
-		printk("%s: failed to send contig transaction: t: %p, gen: %u, size: %zu, err: %d.\n",
-				__func__, t, t->gen, t->iovec.iov_len, err);
-		if (err == 0)
-			err = -ECONNRESET;
-		goto err_out_unlock_return;
-	}
-
-	dprintk("%s: sent %s transaction: t: %p, gen: %u, size: %zu, page_num: %u.\n",
-			__func__, (t->page_num) ? "partial" : "full",
-			t, t->gen, t->iovec.iov_len, t->page_num);
-
-	err = 0;
-	if (t->attached_pages)
-		err = netfs_trans_send_pages(t, st);
-
-err_out_unlock_return:
-
-	if (st->need_reset)
-		netfs_state_exit(st);
-
-	netfs_state_unlock_send(st);
-
-	dprintk("%s: t: %p, gen: %u, err: %d.\n",
-		__func__, t, t->gen, err);
-
-	t->result = err;
-	return err;
-}
-
-static inline int netfs_trans_cmp(unsigned int gen, unsigned int new)
-{
-	if (gen < new)
-		return 1;
-	if (gen > new)
-		return -1;
-	return 0;
-}
-
-struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen)
-{
-	struct rb_root *root = &st->trans_root;
-	struct rb_node *n = root->rb_node;
-	struct netfs_trans_dst *tmp, *ret = NULL;
-	struct netfs_trans *t;
-	int cmp;
-
-	while (n) {
-		tmp = rb_entry(n, struct netfs_trans_dst, state_entry);
-		t = tmp->trans;
-
-		cmp = netfs_trans_cmp(t->gen, gen);
-		if (cmp < 0)
-			n = n->rb_left;
-		else if (cmp > 0)
-			n = n->rb_right;
-		else {
-			ret = tmp;
-			break;
-		}
-	}
-
-	return ret;
-}
-
-static int netfs_trans_insert(struct netfs_trans_dst *ndst, struct netfs_state *st)
-{
-	struct rb_root *root = &st->trans_root;
-	struct rb_node **n = &root->rb_node, *parent = NULL;
-	struct netfs_trans_dst *ret = NULL, *tmp;
-	struct netfs_trans *t = NULL, *new = ndst->trans;
-	int cmp;
-
-	while (*n) {
-		parent = *n;
-
-		tmp = rb_entry(parent, struct netfs_trans_dst, state_entry);
-		t = tmp->trans;
-
-		cmp = netfs_trans_cmp(t->gen, new->gen);
-		if (cmp < 0)
-			n = &parent->rb_left;
-		else if (cmp > 0)
-			n = &parent->rb_right;
-		else {
-			ret = tmp;
-			break;
-		}
-	}
-
-	if (ret) {
-		printk("%s: exist: old: gen: %u, flags: %x, send_time: %lu, "
-				"new: gen: %u, flags: %x, send_time: %lu.\n",
-			__func__, t->gen, t->flags, ret->send_time,
-			new->gen, new->flags, ndst->send_time);
-		return -EEXIST;
-	}
-
-	rb_link_node(&ndst->state_entry, parent, n);
-	rb_insert_color(&ndst->state_entry, root);
-	ndst->send_time = jiffies;
-
-	return 0;
-}
-
-int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st)
-{
-	if (dst && dst->state_entry.rb_parent_color) {
-		rb_erase(&dst->state_entry, &st->trans_root);
-		dst->state_entry.rb_parent_color = 0;
-		return 1;
-	}
-	return 0;
-}
-
-static int netfs_trans_remove_state(struct netfs_trans_dst *dst)
-{
-	int ret;
-	struct netfs_state *st = dst->state;
-
-	mutex_lock(&st->trans_lock);
-	ret = netfs_trans_remove_nolock(dst, st);
-	mutex_unlock(&st->trans_lock);
-
-	return ret;
-}
-
-/*
- * Create new destination for given transaction associated with given network state.
- * Transaction's reference counter is bumped and will be dropped when either
- * reply is received or when async timeout detection task will fail resending
- * and drop transaction.
- */
-static int netfs_trans_push_dst(struct netfs_trans *t, struct netfs_state *st)
-{
-	struct netfs_trans_dst *dst;
-	int err;
-
-	dst = mempool_alloc(netfs_trans_dst_pool, GFP_KERNEL);
-	if (!dst)
-		return -ENOMEM;
-
-	dst->retries = 0;
-	dst->send_time = 0;
-	dst->state = st;
-	dst->trans = t;
-	netfs_trans_get(t);
-
-	mutex_lock(&st->trans_lock);
-	err = netfs_trans_insert(dst, st);
-	mutex_unlock(&st->trans_lock);
-
-	if (err)
-		goto err_out_free;
-
-	spin_lock(&t->dst_lock);
-	list_add_tail(&dst->trans_entry, &t->dst_list);
-	spin_unlock(&t->dst_lock);
-
-	return 0;
-
-err_out_free:
-	t->result = err;
-	netfs_trans_put(t);
-	mempool_free(dst, netfs_trans_dst_pool);
-	return err;
-}
-
-static void netfs_trans_free_dst(struct netfs_trans_dst *dst)
-{
-	netfs_trans_put(dst->trans);
-	mempool_free(dst, netfs_trans_dst_pool);
-}
-
-static void netfs_trans_remove_dst(struct netfs_trans_dst *dst)
-{
-	if (netfs_trans_remove_state(dst))
-		netfs_trans_free_dst(dst);
-}
-
-/*
- * Drop destination transaction entry when we know it.
- */
-void netfs_trans_drop_dst(struct netfs_trans_dst *dst)
-{
-	struct netfs_trans *t = dst->trans;
-
-	spin_lock(&t->dst_lock);
-	list_del_init(&dst->trans_entry);
-	spin_unlock(&t->dst_lock);
-
-	netfs_trans_remove_dst(dst);
-}
-
-/*
- * Drop destination transaction entry when we know it and when we
- * already removed dst from state tree.
- */
-void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst)
-{
-	struct netfs_trans *t = dst->trans;
-
-	spin_lock(&t->dst_lock);
-	list_del_init(&dst->trans_entry);
-	spin_unlock(&t->dst_lock);
-
-	netfs_trans_free_dst(dst);
-}
-
-/*
- * This drops destination transaction entry from appropriate network state
- * tree and drops related reference counter. It is possible that transaction
- * will be freed here if its reference counter hits zero.
- * Destination transaction entry will be freed.
- */
-void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st)
-{
-	struct netfs_trans_dst *dst, *tmp, *ret = NULL;
-
-	spin_lock(&t->dst_lock);
-	list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
-		if (dst->state == st) {
-			ret = dst;
-			list_del(&dst->trans_entry);
-			break;
-		}
-	}
-	spin_unlock(&t->dst_lock);
-
-	if (ret)
-		netfs_trans_remove_dst(ret);
-}
-
-/*
- * This drops destination transaction entry from appropriate network state
- * tree and drops related reference counter. It is possible that transaction
- * will be freed here if its reference counter hits zero.
- * Destination transaction entry will be freed.
- */
-void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st)
-{
-	struct netfs_trans_dst *dst, *tmp, *ret;
-
-	spin_lock(&t->dst_lock);
-	ret = list_entry(t->dst_list.prev, struct netfs_trans_dst, trans_entry);
-	if (ret->state != st) {
-		ret = NULL;
-		list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
-			if (dst->state == st) {
-				ret = dst;
-				list_del_init(&dst->trans_entry);
-				break;
-			}
-		}
-	} else {
-		list_del(&ret->trans_entry);
-	}
-	spin_unlock(&t->dst_lock);
-
-	if (ret)
-		netfs_trans_remove_dst(ret);
-}
-
-static int netfs_trans_push(struct netfs_trans *t, struct netfs_state *st)
-{
-	int err;
-
-	err = netfs_trans_push_dst(t, st);
-	if (err)
-		return err;
-
-	err = netfs_trans_send(t, st);
-	if (err)
-		goto err_out_free;
-
-	if (t->flags & NETFS_TRANS_SINGLE_DST)
-		pohmelfs_switch_active(st->psb);
-
-	return 0;
-
-err_out_free:
-	t->result = err;
-	netfs_trans_drop_last(t, st);
-
-	return err;
-}
-
-int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
-{
-	struct pohmelfs_config *c;
-	int err = -ENODEV;
-	struct netfs_state *st;
-#if 0
-	dprintk("%s: t: %p, gen: %u, size: %u, page_num: %u, active: %p.\n",
-		__func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state);
-#endif
-	mutex_lock(&psb->state_lock);
-	list_for_each_entry(c, &psb->state_list, config_entry) {
-		st = &c->state;
-
-		if (t->flags & NETFS_TRANS_SINGLE_DST) {
-			if (!(st->ctl.perm & POHMELFS_IO_PERM_READ))
-				continue;
-		} else {
-			if (!(st->ctl.perm & POHMELFS_IO_PERM_WRITE))
-				continue;
-		}
-
-		if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio) &&
-				(t->flags & NETFS_TRANS_SINGLE_DST))
-			st = &psb->active_state->state;
-
-		err = netfs_trans_push(t, st);
-		if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
-			break;
-	}
-
-	mutex_unlock(&psb->state_lock);
-#if 0
-	dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
-		__func__, t, t->gen, t->iovec.iov_len, t->page_num, err);
-#endif
-	if (err)
-		t->result = err;
-	return err;
-}
-
-int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb)
-{
-	int err;
-	struct netfs_cmd *cmd = t->iovec.iov_base;
-
-	t->gen = atomic_inc_return(&psb->trans_gen);
-
-	cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) +
-		t->attached_size + t->attached_pages * sizeof(struct netfs_cmd);
-	cmd->cmd = NETFS_TRANS;
-	cmd->start = t->gen;
-	cmd->id = 0;
-
-	if (psb->perform_crypto) {
-		cmd->ext = psb->crypto_attached_size;
-		cmd->csize = psb->crypto_attached_size;
-	}
-
-	dprintk("%s: t: %u, size: %u, iov_len: %zu, attached_size: %u, attached_pages: %u.\n",
-			__func__, t->gen, cmd->size, t->iovec.iov_len, t->attached_size, t->attached_pages);
-	err = pohmelfs_trans_crypt(t, psb);
-	if (err) {
-		t->result = err;
-		netfs_convert_cmd(cmd);
-		dprintk("%s: trans: %llu, crypto_attached_size: %u, attached_size: %u, attached_pages: %d, trans_size: %u, err: %d.\n",
-			__func__, cmd->start, psb->crypto_attached_size, t->attached_size, t->attached_pages, cmd->size, err);
-	}
-	netfs_trans_put(t);
-	return err;
-}
-
-/*
- * Resend transaction to remote server(s).
- * If new servers were added into superblock, we can try to send data
- * to them too.
- *
- * It is called under superblock's state_lock, so we can safely
- * dereference psb->state_list. Also, transaction's reference counter is
- * bumped, so it can not go away under us, thus we can safely access all
- * its members. State is locked.
- *
- * This function returns 0 if transaction was successfully sent to at
- * least one destination target.
- */
-int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb)
-{
-	struct netfs_trans_dst *dst;
-	struct netfs_state *st;
-	struct pohmelfs_config *c;
-	int err, exist, error = -ENODEV;
-
-	list_for_each_entry(c, &psb->state_list, config_entry) {
-		st = &c->state;
-
-		exist = 0;
-		spin_lock(&t->dst_lock);
-		list_for_each_entry(dst, &t->dst_list, trans_entry) {
-			if (st == dst->state) {
-				exist = 1;
-				break;
-			}
-		}
-		spin_unlock(&t->dst_lock);
-
-		if (exist) {
-			if (!(t->flags & NETFS_TRANS_SINGLE_DST) ||
-					(c->config_entry.next == &psb->state_list)) {
-				dprintk("%s: resending st: %p, t: %p, gen: %u.\n",
-						__func__, st, t, t->gen);
-				err = netfs_trans_send(t, st);
-				if (!err)
-					error = 0;
-			}
-			continue;
-		}
-
-		dprintk("%s: pushing/resending st: %p, t: %p, gen: %u.\n",
-				__func__, st, t, t->gen);
-		err = netfs_trans_push(t, st);
-		if (err)
-			continue;
-		error = 0;
-		if (t->flags & NETFS_TRANS_SINGLE_DST)
-			break;
-	}
-
-	t->result = error;
-	return error;
-}
-
-void *netfs_trans_add(struct netfs_trans *t, unsigned int size)
-{
-	struct iovec *io = &t->iovec;
-	void *ptr;
-
-	if (size > t->total_size) {
-		ptr = ERR_PTR(-EINVAL);
-		goto out;
-	}
-
-	if (io->iov_len + size > t->total_size) {
-		dprintk("%s: too big size t: %p, gen: %u, iov_len: %zu, size: %u, total: %u.\n",
-				__func__, t, t->gen, io->iov_len, size, t->total_size);
-		ptr = ERR_PTR(-E2BIG);
-		goto out;
-	}
-
-	ptr = io->iov_base + io->iov_len;
-	io->iov_len += size;
-
-out:
-	dprintk("%s: t: %p, gen: %u, size: %u, total: %zu.\n",
-		__func__, t, t->gen, size, io->iov_len);
-	return ptr;
-}
-
-void netfs_trans_free(struct netfs_trans *t)
-{
-	if (t->eng)
-		pohmelfs_crypto_thread_make_ready(t->eng->thread);
-	kfree(t);
-}
-
-struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
-		unsigned int flags, unsigned int nr)
-{
-	struct netfs_trans *t;
-	unsigned int num, cont, pad, size_no_trans;
-	unsigned int crypto_added = 0;
-	struct netfs_cmd *cmd;
-
-	if (psb->perform_crypto)
-		crypto_added = psb->crypto_attached_size;
-
-	/*
-	 * |sizeof(struct netfs_trans)|
-	 * |sizeof(struct netfs_cmd)| - transaction header
-	 * |size| - buffer with requested size
-	 * |padding| - crypto padding, zero bytes
-	 * |nr * sizeof(struct page *)| - array of page pointers
-	 *
-	 * Overall size should be less than PAGE_SIZE for guaranteed allocation.
-	 */
-
-	cont = size;
-	size = ALIGN(size, psb->crypto_align_size);
-	pad = size - cont;
-
-	size_no_trans = size + sizeof(struct netfs_cmd) * 2 + crypto_added;
-
-	cont = sizeof(struct netfs_trans) + size_no_trans;
-
-	num = (PAGE_SIZE - cont)/sizeof(struct page *);
-
-	if (nr > num)
-		nr = num;
-
-	t = kzalloc(cont + nr*sizeof(struct page *), GFP_NOIO);
-	if (!t)
-		goto err_out_exit;
-
-	t->iovec.iov_base = (void *)(t + 1);
-	t->pages = (struct page **)(t->iovec.iov_base + size_no_trans);
-
-	/*
-	 * Reserving space for transaction header.
-	 */
-	t->iovec.iov_len = sizeof(struct netfs_cmd) + crypto_added;
-
-	netfs_trans_init_static(t, nr, size_no_trans);
-
-	t->flags = flags;
-	t->psb = psb;
-
-	cmd = (struct netfs_cmd *)t->iovec.iov_base;
-
-	cmd->size = size;
-	cmd->cpad = pad;
-	cmd->csize = crypto_added;
-
-	dprintk("%s: t: %p, gen: %u, size: %u, padding: %u, align_size: %u, flags: %x, "
-			"page_num: %u, base: %p, pages: %p.\n",
-			__func__, t, t->gen, size, pad, psb->crypto_align_size, flags, nr,
-			t->iovec.iov_base, t->pages);
-
-	return t;
-
-err_out_exit:
-	return NULL;
-}
-
-int netfs_trans_init(void)
-{
-	int err = -ENOMEM;
-
-	netfs_trans_dst = kmem_cache_create("netfs_trans_dst", sizeof(struct netfs_trans_dst),
-			0, 0, NULL);
-	if (!netfs_trans_dst)
-		goto err_out_exit;
-
-	netfs_trans_dst_pool = mempool_create_slab_pool(256, netfs_trans_dst);
-	if (!netfs_trans_dst_pool)
-		goto err_out_free;
-
-	return 0;
-
-err_out_free:
-	kmem_cache_destroy(netfs_trans_dst);
-err_out_exit:
-	return err;
-}
-
-void netfs_trans_exit(void)
-{
-	mempool_destroy(netfs_trans_dst_pool);
-	kmem_cache_destroy(netfs_trans_dst);
-}
diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h
index 9b5d771..ed85b44 100644
--- a/drivers/staging/rtl8712/drv_types.h
+++ b/drivers/staging/rtl8712/drv_types.h
@@ -37,6 +37,8 @@
 #include "wlan_bssdef.h"
 #include "rtl8712_spec.h"
 #include "rtl8712_hal.h"
+#include <linux/mutex.h>
+#include <linux/completion.h>
 
 enum _NIC_VERSION {
 	RTL8711_NIC,
@@ -168,6 +170,7 @@
 	s32	bSurpriseRemoved;
 	u32	IsrContent;
 	u32	ImrContent;
+	bool	fw_found;
 	u8	EepromAddressSize;
 	u8	hw_init_completed;
 	struct task_struct *cmdThread;
@@ -184,6 +187,10 @@
 	_workitem wkFilterRxFF0;
 	u8 blnEnableRxFF0Filter;
 	spinlock_t lockRxFF0Filter;
+	const struct firmware *fw;
+	struct usb_interface *pusb_intf;
+	struct mutex mutex_start;
+	struct completion rtl8712_fw_ready;
 };
 
 static inline u8 *myid(struct eeprom_priv *peepriv)
diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c
index d0029aa..cc893c0 100644
--- a/drivers/staging/rtl8712/hal_init.c
+++ b/drivers/staging/rtl8712/hal_init.c
@@ -42,29 +42,56 @@
 #define FWBUFF_ALIGN_SZ 512
 #define MAX_DUMP_FWSZ	49152 /*default = 49152 (48k)*/
 
-static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl,
-		    const u8 **ppmappedfw)
+static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
 {
-	int rc;
-	const char firmware_file[] = "rtlwifi/rtl8712u.bin";
-	const struct firmware **praw = (const struct firmware **)
-				       (pphfwfile_hdl);
-	struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)
-					(&padapter->dvobjpriv);
-	struct usb_device *pusbdev = pdvobjpriv->pusbdev;
+	struct _adapter *padapter = context;
 
+	complete(&padapter->rtl8712_fw_ready);
+	if (!firmware) {
+		struct usb_device *udev = padapter->dvobjpriv.pusbdev;
+		struct usb_interface *pusb_intf = padapter->pusb_intf;
+		printk(KERN_ERR "r8712u: Firmware request failed\n");
+		padapter->fw_found = false;
+		usb_put_dev(udev);
+		usb_set_intfdata(pusb_intf, NULL);
+		return;
+	}
+	padapter->fw = firmware;
+	padapter->fw_found = true;
+	/* firmware available - start netdev */
+	register_netdev(padapter->pnetdev);
+}
+
+static const char firmware_file[] = "rtlwifi/rtl8712u.bin";
+
+int rtl871x_load_fw(struct _adapter *padapter)
+{
+	struct device *dev = &padapter->dvobjpriv.pusbdev->dev;
+	int rc;
+
+	init_completion(&padapter->rtl8712_fw_ready);
 	printk(KERN_INFO "r8712u: Loading firmware from \"%s\"\n",
 	       firmware_file);
-	rc = request_firmware(praw, firmware_file, &pusbdev->dev);
-	if (rc < 0) {
-		printk(KERN_ERR "r8712u: Unable to load firmware\n");
-		printk(KERN_ERR "r8712u: Install latest linux-firmware\n");
+	rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev,
+				     GFP_KERNEL, padapter, rtl871x_load_fw_cb);
+	if (rc)
+		printk(KERN_ERR "r8712u: Firmware request error %d\n", rc);
+	return rc;
+}
+MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
+
+static u32 rtl871x_open_fw(struct _adapter *padapter, const u8 **ppmappedfw)
+{
+	const struct firmware **praw = &padapter->fw;
+
+	if (padapter->fw->size > 200000) {
+		printk(KERN_ERR "r8172u: Badfw->size of %d\n",
+		       (int)padapter->fw->size);
 		return 0;
 	}
 	*ppmappedfw = (u8 *)((*praw)->data);
 	return (*praw)->size;
 }
-MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
 
 static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv)
 {
@@ -142,18 +169,17 @@
 	uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */
 	struct fw_hdr fwhdr;
 	u32 ulfilelength;	/* FW file size */
-	void *phfwfile_hdl = NULL;
 	const u8 *pmappedfw = NULL;
 	u8 *ptmpchar = NULL, *ppayload, *ptr;
 	struct tx_desc *ptx_desc;
 	u32 txdscp_sz = sizeof(struct tx_desc);
 	u8 ret = _FAIL;
 
-	ulfilelength = rtl871x_open_fw(padapter, &phfwfile_hdl, &pmappedfw);
+	ulfilelength = rtl871x_open_fw(padapter, &pmappedfw);
 	if (pmappedfw && (ulfilelength > 0)) {
 		update_fwhdr(&fwhdr, pmappedfw);
 		if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL)
-			goto firmware_rel;
+			return ret;
 		fill_fwpriv(padapter, &fwhdr.fwpriv);
 		/* firmware check ok */
 		maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ?
@@ -161,7 +187,7 @@
 		maxlen += txdscp_sz;
 		ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ);
 		if (ptmpchar == NULL)
-			goto firmware_rel;
+			return ret;
 
 		ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ -
 			    ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1)));
@@ -297,8 +323,6 @@
 
 exit_fail:
 	kfree(ptmpchar);
-firmware_rel:
-	release_firmware((struct firmware *)phfwfile_hdl);
 	return ret;
 }
 
diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c
index 9a75c6d..98a3d68 100644
--- a/drivers/staging/rtl8712/os_intfs.c
+++ b/drivers/staging/rtl8712/os_intfs.c
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
+#include <linux/firmware.h>
 #include "osdep_service.h"
 #include "drv_types.h"
 #include "xmit_osdep.h"
@@ -264,12 +265,12 @@
 void r8712_stop_drv_timers(struct _adapter *padapter)
 {
 	_cancel_timer_ex(&padapter->mlmepriv.assoc_timer);
-	_cancel_timer_ex(&padapter->mlmepriv.sitesurveyctrl.
-			 sitesurvey_ctrl_timer);
 	_cancel_timer_ex(&padapter->securitypriv.tkip_timer);
 	_cancel_timer_ex(&padapter->mlmepriv.scan_to_timer);
 	_cancel_timer_ex(&padapter->mlmepriv.dhcp_timer);
 	_cancel_timer_ex(&padapter->mlmepriv.wdg_timer);
+	_cancel_timer_ex(&padapter->mlmepriv.sitesurveyctrl.
+			 sitesurvey_ctrl_timer);
 }
 
 static u8 init_default_value(struct _adapter *padapter)
@@ -347,7 +348,8 @@
 	r8712_free_mlme_priv(&padapter->mlmepriv);
 	r8712_free_io_queue(padapter);
 	_free_xmit_priv(&padapter->xmitpriv);
-	_r8712_free_sta_priv(&padapter->stapriv);
+	if (padapter->fw_found)
+		_r8712_free_sta_priv(&padapter->stapriv);
 	_r8712_free_recv_priv(&padapter->recvpriv);
 	mp871xdeinit(padapter);
 	if (pnetdev)
@@ -388,6 +390,7 @@
 {
 	struct _adapter *padapter = (struct _adapter *)netdev_priv(pnetdev);
 
+	mutex_lock(&padapter->mutex_start);
 	if (padapter->bup == false) {
 		padapter->bDriverStopped = false;
 		padapter->bSurpriseRemoved = false;
@@ -435,11 +438,13 @@
 	/* start driver mlme relation timer */
 	start_drv_timers(padapter);
 	padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
+	mutex_unlock(&padapter->mutex_start);
 	return 0;
 netdev_open_error:
 	padapter->bup = false;
 	netif_carrier_off(pnetdev);
 	netif_stop_queue(pnetdev);
+	mutex_unlock(&padapter->mutex_start);
 	return -1;
 }
 
@@ -473,6 +478,9 @@
 	r8712_free_network_queue(padapter);
 	/* The interface is no longer Up: */
 	padapter->bup = false;
+	release_firmware(padapter->fw);
+	/* never exit with a firmware callback pending */
+	wait_for_completion(&padapter->rtl8712_fw_ready);
 	return 0;
 }
 
diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h
index 665e718..d19865a 100644
--- a/drivers/staging/rtl8712/rtl8712_hal.h
+++ b/drivers/staging/rtl8712/rtl8712_hal.h
@@ -145,5 +145,6 @@
 };
 
 uint	 rtl8712_hal_init(struct _adapter *padapter);
+int rtl871x_load_fw(struct _adapter *padapter);
 
 #endif
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
index 64f5696..81bde80 100644
--- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
@@ -43,6 +43,7 @@
 	_r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
 	_r8712_init_sta_recv_priv(&psta->sta_recvpriv);
 #ifdef CONFIG_R8712_AP
+	_init_listhead(&psta->asoc_list);
 	_init_listhead(&psta->auth_list);
 #endif
 }
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index 5385da2..9bade18 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -89,6 +89,7 @@
 	{USB_DEVICE(0x0DF6, 0x0045)},
 	{USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */
 	{USB_DEVICE(0x0DF6, 0x004B)},
+	{USB_DEVICE(0x0DF6, 0x005B)},
 	{USB_DEVICE(0x0DF6, 0x005D)},
 	{USB_DEVICE(0x0DF6, 0x0063)},
 	/* Sweex */
@@ -389,6 +390,7 @@
 	pdvobjpriv = &padapter->dvobjpriv;
 	pdvobjpriv->padapter = padapter;
 	padapter->dvobjpriv.pusbdev = udev;
+	padapter->pusb_intf = pusb_intf;
 	usb_set_intfdata(pusb_intf, pnetdev);
 	SET_NETDEV_DEV(pnetdev, &pusb_intf->dev);
 	/* step 2. */
@@ -595,10 +597,11 @@
 			       "%pM\n", mac);
 		memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
 	}
-	/* step 6. Tell the network stack we exist */
-	if (register_netdev(pnetdev) != 0)
+	/* step 6. Load the firmware asynchronously */
+	if (rtl871x_load_fw(padapter))
 		goto error;
 	spin_lock_init(&padapter->lockRxFF0Filter);
+	mutex_init(&padapter->mutex_start);
 	return 0;
 error:
 	usb_put_dev(udev);
@@ -629,7 +632,8 @@
 		flush_scheduled_work();
 		udelay(1);
 		/*Stop driver mlme relation timer */
-		r8712_stop_drv_timers(padapter);
+		if (padapter->fw_found)
+			r8712_stop_drv_timers(padapter);
 		r871x_dev_unload(padapter);
 		r8712_free_drv_sw(padapter);
 	}
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index e1c4492..dde559d 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -1046,8 +1046,6 @@
 
 	/* Free the driver's device context: */
 	kfree(drv_datap->base_img);
-	kfree(drv_datap);
-	dev_set_drvdata(bridge, NULL);
 	kfree((void *)dev_ctxt);
 	return status;
 }
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
index 76cfc6e..385740b 100644
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c
@@ -410,6 +410,9 @@
 		DBC_ASSERT(ret == true);
 	}
 
+	kfree(drv_datap);
+	dev_set_drvdata(bridge, NULL);
+
 func_cont:
 	mem_ext_phys_pool_release();
 
@@ -500,35 +503,42 @@
 	}
 #endif
 	pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL);
-	if (pr_ctxt) {
-		pr_ctxt->res_state = PROC_RES_ALLOCATED;
-		spin_lock_init(&pr_ctxt->dmm_map_lock);
-		INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
-		spin_lock_init(&pr_ctxt->dmm_rsv_lock);
-		INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
+	if (!pr_ctxt)
+		return -ENOMEM;
 
-		pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
-		if (pr_ctxt->node_id) {
-			idr_init(pr_ctxt->node_id);
-		} else {
-			status = -ENOMEM;
-			goto err;
-		}
+	pr_ctxt->res_state = PROC_RES_ALLOCATED;
+	spin_lock_init(&pr_ctxt->dmm_map_lock);
+	INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
+	spin_lock_init(&pr_ctxt->dmm_rsv_lock);
+	INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
 
-		pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
-		if (pr_ctxt->stream_id)
-			idr_init(pr_ctxt->stream_id);
-		else
-			status = -ENOMEM;
-	} else {
+	pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+	if (!pr_ctxt->node_id) {
 		status = -ENOMEM;
+		goto err1;
 	}
-err:
+
+	idr_init(pr_ctxt->node_id);
+
+	pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+	if (!pr_ctxt->stream_id) {
+		status = -ENOMEM;
+		goto err2;
+	}
+
+	idr_init(pr_ctxt->stream_id);
+
 	filp->private_data = pr_ctxt;
+
 #ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-	if (!status)
-		atomic_inc(&bridge_cref);
+	atomic_inc(&bridge_cref);
 #endif
+	return 0;
+
+err2:
+	kfree(pr_ctxt->node_id);
+err1:
+	kfree(pr_ctxt);
 	return status;
 }
 
@@ -550,6 +560,8 @@
 	flush_signals(current);
 	drv_remove_all_resources(pr_ctxt);
 	proc_detach(pr_ctxt);
+	kfree(pr_ctxt->node_id);
+	kfree(pr_ctxt->stream_id);
 	kfree(pr_ctxt);
 
 	filp->private_data = NULL;
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c
index 2d63178..705a9e5 100644
--- a/drivers/staging/usbip/stub_main.c
+++ b/drivers/staging/usbip/stub_main.c
@@ -246,8 +246,9 @@
 {
 	int ret;
 
-	stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN);
+	init_busid_table();
 
+	stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN);
 	if (!stub_priv_cache) {
 		pr_err("kmem_cache_create failed\n");
 		return -ENOMEM;
@@ -266,7 +267,6 @@
 		goto err_create_file;
 	}
 
-	init_busid_table();
 	pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
 	return ret;
 
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c
index 642840c..ef7c52b 100644
--- a/drivers/staging/zcache/zcache-main.c
+++ b/drivers/staging/zcache/zcache-main.c
@@ -358,8 +358,8 @@
 	if (unlikely(zbpg == NULL))
 		goto out;
 	/* ok, have a page, now compress the data before taking locks */
-	spin_lock(&zbpg->lock);
 	spin_lock(&zbud_budlists_spinlock);
+	spin_lock(&zbpg->lock);
 	list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list);
 	zbud_unbuddied[nchunks].count++;
 	zh = &zbpg->buddy[0];
@@ -389,12 +389,11 @@
 	zh->oid = *oid;
 	zh->pool_id = pool_id;
 	zh->client_id = client_id;
-	/* can wait to copy the data until the list locks are dropped */
-	spin_unlock(&zbud_budlists_spinlock);
-
 	to = zbud_data(zh, size);
 	memcpy(to, cdata, size);
 	spin_unlock(&zbpg->lock);
+	spin_unlock(&zbud_budlists_spinlock);
+
 	zbud_cumul_chunk_counts[nchunks]++;
 	atomic_inc(&zcache_zbud_curr_zpages);
 	zcache_zbud_cumul_zpages++;
@@ -655,8 +654,8 @@
  */
 static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5;
 
-static unsigned long zv_curr_dist_counts[NCHUNKS];
-static unsigned long zv_cumul_dist_counts[NCHUNKS];
+static atomic_t zv_curr_dist_counts[NCHUNKS];
+static atomic_t zv_cumul_dist_counts[NCHUNKS];
 
 static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id,
 				struct tmem_oid *oid, uint32_t index,
@@ -675,8 +674,8 @@
 			&page, &offset, ZCACHE_GFP_MASK);
 	if (unlikely(ret))
 		goto out;
-	zv_curr_dist_counts[chunks]++;
-	zv_cumul_dist_counts[chunks]++;
+	atomic_inc(&zv_curr_dist_counts[chunks]);
+	atomic_inc(&zv_cumul_dist_counts[chunks]);
 	zv = kmap_atomic(page, KM_USER0) + offset;
 	zv->index = index;
 	zv->oid = *oid;
@@ -698,7 +697,7 @@
 
 	ASSERT_SENTINEL(zv, ZVH);
 	BUG_ON(chunks >= NCHUNKS);
-	zv_curr_dist_counts[chunks]--;
+	atomic_dec(&zv_curr_dist_counts[chunks]);
 	size -= sizeof(*zv);
 	BUG_ON(size == 0);
 	INVERT_SENTINEL(zv, ZVH);
@@ -738,7 +737,7 @@
 	char *p = buf;
 
 	for (i = 0; i < NCHUNKS; i++) {
-		n = zv_curr_dist_counts[i];
+		n = atomic_read(&zv_curr_dist_counts[i]);
 		p += sprintf(p, "%lu ", n);
 		chunks += n;
 		sum_total_chunks += i * n;
@@ -754,7 +753,7 @@
 	char *p = buf;
 
 	for (i = 0; i < NCHUNKS; i++) {
-		n = zv_cumul_dist_counts[i];
+		n = atomic_read(&zv_cumul_dist_counts[i]);
 		p += sprintf(p, "%lu ", n);
 		chunks += n;
 		sum_total_chunks += i * n;
@@ -1782,9 +1781,9 @@
  * Swizzling increases objects per swaptype, increasing tmem concurrency
  * for heavy swaploads.  Later, larger nr_cpus -> larger SWIZ_BITS
  * Setting SWIZ_BITS to 27 basically reconstructs the swap entry from
- * frontswap_get_page()
+ * frontswap_get_page(), but has side-effects. Hence using 8.
  */
-#define SWIZ_BITS		27
+#define SWIZ_BITS		8
 #define SWIZ_MASK		((1 << SWIZ_BITS) - 1)
 #define _oswiz(_type, _ind)	((_type << SWIZ_BITS) | (_ind & SWIZ_MASK))
 #define iswiz(_ind)		(_ind >> SWIZ_BITS)
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 9f50c4e..9b7336f 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -45,7 +45,7 @@
 #include "8250.h"
 
 #ifdef CONFIG_SPARC
-#include "suncore.h"
+#include "../suncore.h"
 #endif
 
 /*
diff --git a/drivers/tty/serial/8250/m32r_sio.c b/drivers/tty/serial/m32r_sio.c
similarity index 100%
rename from drivers/tty/serial/8250/m32r_sio.c
rename to drivers/tty/serial/m32r_sio.c
diff --git a/drivers/tty/serial/8250/m32r_sio.h b/drivers/tty/serial/m32r_sio.h
similarity index 100%
rename from drivers/tty/serial/8250/m32r_sio.h
rename to drivers/tty/serial/m32r_sio.h
diff --git a/drivers/tty/serial/8250/m32r_sio_reg.h b/drivers/tty/serial/m32r_sio_reg.h
similarity index 100%
rename from drivers/tty/serial/8250/m32r_sio_reg.h
rename to drivers/tty/serial/m32r_sio_reg.h
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 1c24269..f809041 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -46,6 +46,13 @@
 
 #define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/
 
+/* SCR register bitmasks */
+#define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK		(1 << 7)
+
+/* FCR register bitmasks */
+#define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT		6
+#define OMAP_UART_FCR_RX_FIFO_TRIG_MASK			(0x3 << 6)
+
 static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
 /* Forward declaration of functions */
@@ -129,6 +136,7 @@
 static void serial_omap_stop_tx(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
+	struct omap_uart_port_info *pdata = up->pdev->dev.platform_data;
 
 	if (up->use_dma &&
 		up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) {
@@ -151,6 +159,9 @@
 		serial_out(up, UART_IER, up->ier);
 	}
 
+	if (!up->use_dma && pdata->set_forceidle)
+		pdata->set_forceidle(up->pdev);
+
 	pm_runtime_mark_last_busy(&up->pdev->dev);
 	pm_runtime_put_autosuspend(&up->pdev->dev);
 }
@@ -279,6 +290,7 @@
 static void serial_omap_start_tx(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
+	struct omap_uart_port_info *pdata = up->pdev->dev.platform_data;
 	struct circ_buf *xmit;
 	unsigned int start;
 	int ret = 0;
@@ -286,6 +298,8 @@
 	if (!up->use_dma) {
 		pm_runtime_get_sync(&up->pdev->dev);
 		serial_omap_enable_ier_thri(up);
+		if (pdata->set_noidle)
+			pdata->set_noidle(up->pdev);
 		pm_runtime_mark_last_busy(&up->pdev->dev);
 		pm_runtime_put_autosuspend(&up->pdev->dev);
 		return;
@@ -726,8 +740,7 @@
 	quot = serial_omap_get_divisor(port, baud);
 
 	/* calculate wakeup latency constraint */
-	up->calc_latency = (1000000 * up->port.fifosize) /
-				(1000 * baud / 8);
+	up->calc_latency = (USEC_PER_SEC * up->port.fifosize) / (baud / 8);
 	up->latency = up->calc_latency;
 	schedule_work(&up->qos_work);
 
@@ -811,14 +824,21 @@
 	up->mcr = serial_in(up, UART_MCR);
 	serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
 	/* FIFO ENABLE, DMA MODE */
-	serial_out(up, UART_FCR, up->fcr);
-	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+	up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK;
 
 	if (up->use_dma) {
 		serial_out(up, UART_TI752_TLR, 0);
-		up->scr |= (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8);
+		up->scr |= UART_FCR_TRIGGER_4;
+	} else {
+		/* Set receive FIFO threshold to 1 byte */
+		up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK;
+		up->fcr |= (0x1 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT);
 	}
 
+	serial_out(up, UART_FCR, up->fcr);
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
 	serial_out(up, UART_OMAP_SCR, up->scr);
 
 	serial_out(up, UART_EFR, up->efr);
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index f96f37b..c55e5fb 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -1593,7 +1593,8 @@
 #define S5PV210_SERIAL_DRV_DATA	(kernel_ulong_t)NULL
 #endif
 
-#ifdef CONFIG_CPU_EXYNOS4210
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) || \
+	defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250)
 static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
 	.info = &(struct s3c24xx_uart_info) {
 		.name		= "Samsung Exynos4 UART",
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index d136b8f..81e2c0d 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -187,7 +187,10 @@
 		return -ENODEV;
 	dev->current_state = PCI_D0;
 
-	if (!dev->irq) {
+	/* The xHCI driver supports MSI and MSI-X,
+	 * so don't fail if the BIOS doesn't provide a legacy IRQ.
+	 */
+	if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
 		dev_err(&dev->dev,
 			"Found HC with no IRQ.  Check BIOS/PCI %s setup!\n",
 			pci_name(dev));
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index eb19cba..e128232 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2447,8 +2447,10 @@
 			&& device_can_wakeup(&hcd->self.root_hub->dev))
 		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
 
-	/* enable irqs just before we start the controller */
-	if (usb_hcd_is_primary_hcd(hcd)) {
+	/* enable irqs just before we start the controller,
+	 * if the BIOS provides legacy PCI irqs.
+	 */
+	if (usb_hcd_is_primary_hcd(hcd) && irqnum) {
 		retval = usb_hcd_request_irqs(hcd, irqnum, irqflags);
 		if (retval)
 			goto err_request_irq;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a0613d8..265c2f6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -705,10 +705,26 @@
 	if (type == HUB_INIT3)
 		goto init3;
 
-	/* After a resume, port power should still be on.
+	/* The superspeed hub except for root hub has to use Hub Depth
+	 * value as an offset into the route string to locate the bits
+	 * it uses to determine the downstream port number. So hub driver
+	 * should send a set hub depth request to superspeed hub after
+	 * the superspeed hub is set configuration in initialization or
+	 * reset procedure.
+	 *
+	 * After a resume, port power should still be on.
 	 * For any other type of activation, turn it on.
 	 */
 	if (type != HUB_RESUME) {
+		if (hdev->parent && hub_is_superspeed(hdev)) {
+			ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+					HUB_SET_DEPTH, USB_RT_HUB,
+					hdev->level - 1, 0, NULL, 0,
+					USB_CTRL_SET_TIMEOUT);
+			if (ret < 0)
+				dev_err(hub->intfdev,
+						"set hub depth failed\n");
+		}
 
 		/* Speed up system boot by using a delayed_work for the
 		 * hub's initial power-up delays.  This is pretty awkward
@@ -987,18 +1003,6 @@
 		goto fail;
 	}
 
-	if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) {
-		ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-				HUB_SET_DEPTH, USB_RT_HUB,
-				hdev->level - 1, 0, NULL, 0,
-				USB_CTRL_SET_TIMEOUT);
-
-		if (ret < 0) {
-			message = "can't set hub depth";
-			goto fail;
-		}
-	}
-
 	/* Request the entire hub descriptor.
 	 * hub->descriptor can handle USB_MAXCHILDREN ports,
 	 * but the hub can/will return fewer bytes here.
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 6d87f28..2c0cd82 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -418,7 +418,7 @@
 
 	/* support autoresume for remote wakeup testing */
 	if (autoresume)
-		sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+		loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 
 	/* support OTG systems */
 	if (gadget_is_otg(cdev->gadget)) {
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 91413ca..353cdd4 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -130,7 +130,7 @@
 	tristate
 
 config USB_EHCI_FSL
-	bool "Support for Freescale on-chip EHCI USB controller"
+	bool "Support for Freescale PPC on-chip EHCI USB controller"
 	depends on USB_EHCI_HCD && FSL_SOC
 	select USB_EHCI_ROOT_HUB_TT
 	select USB_FSL_MPH_DR_OF if OF
@@ -138,7 +138,7 @@
 	  Variation of ARC USB block used in some Freescale chips.
 
 config USB_EHCI_MXC
-	bool "Support for Freescale on-chip EHCI USB controller"
+	bool "Support for Freescale i.MX on-chip EHCI USB controller"
 	depends on USB_EHCI_HCD && ARCH_MXC
 	select USB_EHCI_ROOT_HUB_TT
 	---help---
@@ -546,7 +546,7 @@
 config USB_WHCI_HCD
 	tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
-	depends on PCI && USB
+	depends on PCI && USB && UWB
 	select USB_WUSB
 	select UWB_WHCI
 	help
@@ -559,7 +559,7 @@
 config USB_HWA_HCD
 	tristate "Host Wire Adapter (HWA) driver (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
-	depends on USB
+	depends on USB && UWB
 	select USB_WUSB
 	select UWB_HWA
 	help
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index b556a72..c26a82e 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -239,7 +239,7 @@
 	ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
 }
 
-static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
+static int ehci_fsl_usb_setup(struct ehci_hcd *ehci)
 {
 	struct usb_hcd *hcd = ehci_to_hcd(ehci);
 	struct fsl_usb2_platform_data *pdata;
@@ -299,12 +299,19 @@
 #endif
 		out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
 	}
+
+	if (!(in_be32(non_ehci + FSL_SOC_USB_CTRL) & CTRL_PHY_CLK_VALID)) {
+		printk(KERN_WARNING "fsl-ehci: USB PHY clock invalid\n");
+		return -ENODEV;
+	}
+	return 0;
 }
 
 /* called after powerup, by probe or system-pm "wakeup" */
 static int ehci_fsl_reinit(struct ehci_hcd *ehci)
 {
-	ehci_fsl_usb_setup(ehci);
+	if (ehci_fsl_usb_setup(ehci))
+		return -ENODEV;
 	ehci_port_power(ehci, 0);
 
 	return 0;
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index 4918062..bdf43e2 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -45,5 +45,6 @@
 #define FSL_SOC_USB_PRICTRL	0x40c	/* NOTE: big-endian */
 #define FSL_SOC_USB_SICTRL	0x410	/* NOTE: big-endian */
 #define FSL_SOC_USB_CTRL	0x500	/* NOTE: big-endian */
+#define CTRL_PHY_CLK_VALID	(1 << 17)
 #define SNOOP_SIZE_2GB		0x1e
 #endif				/* _EHCI_FSL_H */
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index caf8742..7732d69 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -867,6 +867,22 @@
 
 static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
 {
+	/* Skip Netlogic mips SoC's internal PCI USB controller.
+	 * This device does not need/support EHCI/OHCI handoff
+	 */
+	if (pdev->vendor == 0x184e)	/* vendor Netlogic */
+		return;
+	if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI &&
+			pdev->class != PCI_CLASS_SERIAL_USB_OHCI &&
+			pdev->class != PCI_CLASS_SERIAL_USB_EHCI &&
+			pdev->class != PCI_CLASS_SERIAL_USB_XHCI)
+		return;
+
+	if (pci_enable_device(pdev) < 0) {
+		dev_warn(&pdev->dev, "Can't enable PCI device, "
+				"BIOS handoff failed.\n");
+		return;
+	}
 	if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
 		quirk_usb_handoff_uhci(pdev);
 	else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
@@ -875,5 +891,6 @@
 		quirk_usb_disable_ehci(pdev);
 	else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
 		quirk_usb_handoff_xhci(pdev);
+	pci_disable_device(pdev);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 35e257f..557b6f3 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -93,7 +93,7 @@
 	 */
 	memset(port_removable, 0, sizeof(port_removable));
 	for (i = 0; i < ports; i++) {
-		portsc = xhci_readl(xhci, xhci->usb3_ports[i]);
+		portsc = xhci_readl(xhci, xhci->usb2_ports[i]);
 		/* If a device is removable, PORTSC reports a 0, same as in the
 		 * hub descriptor DeviceRemovable bits.
 		 */
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 36cbe22..383fc85 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1126,26 +1126,42 @@
 }
 
 /*
- * Convert bInterval expressed in frames (in 1-255 range) to exponent of
+ * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
  * microframes, rounded down to nearest power of 2.
  */
-static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
-		struct usb_host_endpoint *ep)
+static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
+		struct usb_host_endpoint *ep, unsigned int desc_interval,
+		unsigned int min_exponent, unsigned int max_exponent)
 {
 	unsigned int interval;
 
-	interval = fls(8 * ep->desc.bInterval) - 1;
-	interval = clamp_val(interval, 3, 10);
-	if ((1 << interval) != 8 * ep->desc.bInterval)
+	interval = fls(desc_interval) - 1;
+	interval = clamp_val(interval, min_exponent, max_exponent);
+	if ((1 << interval) != desc_interval)
 		dev_warn(&udev->dev,
 			 "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
 			 ep->desc.bEndpointAddress,
 			 1 << interval,
-			 8 * ep->desc.bInterval);
+			 desc_interval);
 
 	return interval;
 }
 
+static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	return xhci_microframes_to_exponent(udev, ep,
+			ep->desc.bInterval, 0, 15);
+}
+
+
+static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	return xhci_microframes_to_exponent(udev, ep,
+			ep->desc.bInterval * 8, 3, 10);
+}
+
 /* Return the polling or NAK interval.
  *
  * The polling interval is expressed in "microframes".  If xHCI's Interval field
@@ -1164,7 +1180,7 @@
 		/* Max NAK rate */
 		if (usb_endpoint_xfer_control(&ep->desc) ||
 		    usb_endpoint_xfer_bulk(&ep->desc)) {
-			interval = ep->desc.bInterval;
+			interval = xhci_parse_microframe_interval(udev, ep);
 			break;
 		}
 		/* Fall through - SS and HS isoc/int have same decoding */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 6bbe3c3..c939f5f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -352,6 +352,11 @@
 		/* hcd->irq is -1, we have MSI */
 		return 0;
 
+	if (!pdev->irq) {
+		xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n");
+		return -EINVAL;
+	}
+
 	/* fall back to legacy interrupt*/
 	ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
 			hcd->irq_descr, hcd);
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index e61aa95..1d5eda2 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -39,7 +39,8 @@
 
 #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
 	&& !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
-	&& !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN)
+	&& !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) \
+	&& !defined(CONFIG_MIPS)
 static inline void readsl(const void __iomem *addr, void *buf, int len)
 	{ insl((unsigned long)addr, buf, len); }
 static inline void readsw(const void __iomem *addr, void *buf, int len)
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 76d6293..735ef4c 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -118,7 +118,7 @@
 
 config USB_MV_OTG
 	tristate "Marvell USB OTG support"
-	depends on USB_MV_UDC && USB_SUSPEND
+	depends on USB_EHCI_MV && USB_MV_UDC && USB_SUSPEND
 	select USB_OTG
 	select USB_OTG_UTILS
 	help
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 8dbf51a..08a5575 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -136,6 +136,8 @@
 	{ USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
 	{ USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */
 	{ USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
+	{ USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
+	{ USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
 	{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
 	{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
 	{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index ad654f8..f770415 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -839,6 +839,7 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
 	{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index f994503..6f6058f 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -1187,3 +1187,10 @@
  */
 /* ZigBee controller */
 #define FTDI_RF_R106		0x8A28
+
+/*
+ * Product: HCP HIT GPRS modem
+ * Manufacturer: HCP d.o.o.
+ * ATI command output: Cinterion MC55i
+ */
+#define FTDI_CINTERION_MC55I_PID	0xA951
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index ea126a4..b54afce 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -788,7 +788,6 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff),
@@ -803,7 +802,6 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
-	/* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) },
@@ -828,7 +826,6 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
-	/* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
@@ -836,7 +833,6 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff),
@@ -846,7 +842,6 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0067, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0077, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) },
@@ -855,6 +850,16 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0088, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0089, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0090, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0091, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0092, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0093, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0095, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) },
@@ -875,23 +880,18 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
@@ -1066,17 +1066,27 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
+	  0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
-	  0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) },
+
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 1d5deee..f98800f 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -36,6 +36,11 @@
 	{USB_DEVICE(0x413c, 0x8171)},	/* Dell Gobi QDL device */
 	{USB_DEVICE(0x1410, 0xa001)},	/* Novatel Gobi Modem device */
 	{USB_DEVICE(0x1410, 0xa008)},	/* Novatel Gobi QDL device */
+	{USB_DEVICE(0x1410, 0xa010)},	/* Novatel Gobi QDL device */
+	{USB_DEVICE(0x1410, 0xa011)},	/* Novatel Gobi QDL device */
+	{USB_DEVICE(0x1410, 0xa012)},	/* Novatel Gobi QDL device */
+	{USB_DEVICE(0x1410, 0xa013)},	/* Novatel Gobi QDL device */
+	{USB_DEVICE(0x1410, 0xa014)},	/* Novatel Gobi QDL device */
 	{USB_DEVICE(0x0b05, 0x1776)},	/* Asus Gobi Modem device */
 	{USB_DEVICE(0x0b05, 0x1774)},	/* Asus Gobi QDL device */
 	{USB_DEVICE(0x19d2, 0xfff3)},	/* ONDA Gobi Modem device */
@@ -86,7 +91,16 @@
 	{USB_DEVICE(0x16d8, 0x8002)},	/* CMDTech Gobi 2000 Modem device (VU922) */
 	{USB_DEVICE(0x05c6, 0x9204)},	/* Gobi 2000 QDL device */
 	{USB_DEVICE(0x05c6, 0x9205)},	/* Gobi 2000 Modem device */
+
+	{USB_DEVICE(0x05c6, 0x920c)},	/* Gobi 3000 QDL */
+	{USB_DEVICE(0x05c6, 0x920d)},	/* Gobi 3000 Composite */
+	{USB_DEVICE(0x1410, 0xa020)},   /* Novatel Gobi 3000 QDL */
+	{USB_DEVICE(0x1410, 0xa021)},	/* Novatel Gobi 3000 Composite */
+	{USB_DEVICE(0x413c, 0x8193)},	/* Dell Gobi 3000 QDL */
+	{USB_DEVICE(0x413c, 0x8194)},	/* Dell Gobi 3000 Composite */
 	{USB_DEVICE(0x1199, 0x9013)},	/* Sierra Wireless Gobi 3000 Modem device (MC8355) */
+	{USB_DEVICE(0x12D1, 0x14F0)},	/* Sony Gobi 3000 QDL */
+	{USB_DEVICE(0x12D1, 0x14F1)},	/* Sony Gobi 3000 Composite */
 	{ }				/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
@@ -123,8 +137,6 @@
 
 	spin_lock_init(&data->susp_lock);
 
-	usb_enable_autosuspend(serial->dev);
-
 	switch (nintf) {
 	case 1:
 		/* QDL mode */
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 8468eb7..75b838e 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -165,7 +165,7 @@
 /* the array dimension is the number of default entries plus */
 /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
 /* null entry */
-static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[14+TI_EXTRA_VID_PID_COUNT+1] = {
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -179,6 +179,7 @@
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
+	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
 };
 
 static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
@@ -188,7 +189,7 @@
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[18+2*TI_EXTRA_VID_PID_COUNT+1] = {
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -206,6 +207,7 @@
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
+	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
 	{ }
 };
 
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index 2aac195..f140f1b 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -49,6 +49,10 @@
 #define MTS_MT9234ZBA_PRODUCT_ID	0xF115
 #define MTS_MT9234ZBAOLD_PRODUCT_ID	0x0319
 
+/* Abbott Diabetics vendor and product ids */
+#define ABBOTT_VENDOR_ID		0x1a61
+#define ABBOTT_PRODUCT_ID		0x3410
+
 /* Commands */
 #define TI_GET_VERSION			0x01
 #define TI_GET_PORT_STATUS		0x02
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 3dd7da9..db51ba1 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -788,15 +788,19 @@
 	struct Scsi_Host *host = us_to_host(us);
 
 	/* If the device is really gone, cut short reset delays */
-	if (us->pusb_dev->state == USB_STATE_NOTATTACHED)
+	if (us->pusb_dev->state == USB_STATE_NOTATTACHED) {
 		set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
+		wake_up(&us->delay_wait);
+	}
 
-	/* Prevent SCSI-scanning (if it hasn't started yet)
-	 * and wait for the SCSI-scanning thread to stop.
+	/* Prevent SCSI scanning (if it hasn't started yet)
+	 * or wait for the SCSI-scanning routine to stop.
 	 */
-	set_bit(US_FLIDX_DONT_SCAN, &us->dflags);
-	wake_up(&us->delay_wait);
-	wait_for_completion(&us->scanning_done);
+	cancel_delayed_work_sync(&us->scan_dwork);
+
+	/* Balance autopm calls if scanning was cancelled */
+	if (test_bit(US_FLIDX_SCAN_PENDING, &us->dflags))
+		usb_autopm_put_interface_no_suspend(us->pusb_intf);
 
 	/* Removing the host will perform an orderly shutdown: caches
 	 * synchronized, disks spun down, etc.
@@ -823,53 +827,28 @@
 	scsi_host_put(us_to_host(us));
 }
 
-/* Thread to carry out delayed SCSI-device scanning */
-static int usb_stor_scan_thread(void * __us)
+/* Delayed-work routine to carry out SCSI-device scanning */
+static void usb_stor_scan_dwork(struct work_struct *work)
 {
-	struct us_data *us = (struct us_data *)__us;
+	struct us_data *us = container_of(work, struct us_data,
+			scan_dwork.work);
 	struct device *dev = &us->pusb_intf->dev;
 
-	dev_dbg(dev, "device found\n");
+	dev_dbg(dev, "starting scan\n");
 
-	set_freezable();
-
-	/*
-	 * Wait for the timeout to expire or for a disconnect
-	 *
-	 * We can't freeze in this thread or we risk causing khubd to
-	 * fail to freeze, but we can't be non-freezable either. Nor can
-	 * khubd freeze while waiting for scanning to complete as it may
-	 * hold the device lock, causing a hang when suspending devices.
-	 * So instead of using wait_event_freezable(), explicitly test
-	 * for (DONT_SCAN || freezing) in interruptible wait and proceed
-	 * if any of DONT_SCAN, freezing or timeout has happened.
-	 */
-	if (delay_use > 0) {
-		dev_dbg(dev, "waiting for device to settle "
-				"before scanning\n");
-		wait_event_interruptible_timeout(us->delay_wait,
-				test_bit(US_FLIDX_DONT_SCAN, &us->dflags) ||
-				freezing(current), delay_use * HZ);
+	/* For bulk-only devices, determine the max LUN value */
+	if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) {
+		mutex_lock(&us->dev_mutex);
+		us->max_lun = usb_stor_Bulk_max_lun(us);
+		mutex_unlock(&us->dev_mutex);
 	}
+	scsi_scan_host(us_to_host(us));
+	dev_dbg(dev, "scan complete\n");
 
-	/* If the device is still connected, perform the scanning */
-	if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) {
-
-		/* For bulk-only devices, determine the max LUN value */
-		if (us->protocol == USB_PR_BULK &&
-				!(us->fflags & US_FL_SINGLE_LUN)) {
-			mutex_lock(&us->dev_mutex);
-			us->max_lun = usb_stor_Bulk_max_lun(us);
-			mutex_unlock(&us->dev_mutex);
-		}
-		scsi_scan_host(us_to_host(us));
-		dev_dbg(dev, "scan complete\n");
-
-		/* Should we unbind if no devices were detected? */
-	}
+	/* Should we unbind if no devices were detected? */
 
 	usb_autopm_put_interface(us->pusb_intf);
-	complete_and_exit(&us->scanning_done, 0);
+	clear_bit(US_FLIDX_SCAN_PENDING, &us->dflags);
 }
 
 static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf)
@@ -916,7 +895,7 @@
 	init_completion(&us->cmnd_ready);
 	init_completion(&(us->notify));
 	init_waitqueue_head(&us->delay_wait);
-	init_completion(&us->scanning_done);
+	INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork);
 
 	/* Associate the us_data structure with the USB device */
 	result = associate_dev(us, intf);
@@ -947,7 +926,6 @@
 /* Second part of general USB mass-storage probing */
 int usb_stor_probe2(struct us_data *us)
 {
-	struct task_struct *th;
 	int result;
 	struct device *dev = &us->pusb_intf->dev;
 
@@ -988,20 +966,14 @@
 		goto BadDevice;
 	}
 
-	/* Start up the thread for delayed SCSI-device scanning */
-	th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan");
-	if (IS_ERR(th)) {
-		dev_warn(dev,
-				"Unable to start the device-scanning thread\n");
-		complete(&us->scanning_done);
-		quiesce_and_remove_host(us);
-		result = PTR_ERR(th);
-		goto BadDevice;
-	}
-
+	/* Submit the delayed_work for SCSI-device scanning */
 	usb_autopm_get_interface_no_resume(us->pusb_intf);
-	wake_up_process(th);
+	set_bit(US_FLIDX_SCAN_PENDING, &us->dflags);
 
+	if (delay_use > 0)
+		dev_dbg(dev, "waiting for device to settle before scanning\n");
+	queue_delayed_work(system_freezable_wq, &us->scan_dwork,
+			delay_use * HZ);
 	return 0;
 
 	/* We come here if there are any problems */
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 7b0f211..75f70f0 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -47,6 +47,7 @@
 #include <linux/blkdev.h>
 #include <linux/completion.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
 #include <scsi/scsi_host.h>
 
 struct us_data;
@@ -72,7 +73,7 @@
 #define US_FLIDX_DISCONNECTING	3	/* disconnect in progress   */
 #define US_FLIDX_RESETTING	4	/* device reset in progress */
 #define US_FLIDX_TIMED_OUT	5	/* SCSI midlayer timed out  */
-#define US_FLIDX_DONT_SCAN	6	/* don't scan (disconnect)  */
+#define US_FLIDX_SCAN_PENDING	6	/* scanning not yet done    */
 #define US_FLIDX_REDO_READ10	7	/* redo READ(10) command    */
 #define US_FLIDX_READ10_WORKED	8	/* previous READ(10) succeeded */
 
@@ -147,8 +148,8 @@
 	/* mutual exclusion and synchronization structures */
 	struct completion	cmnd_ready;	 /* to sleep thread on	    */
 	struct completion	notify;		 /* thread begin/end	    */
-	wait_queue_head_t	delay_wait;	 /* wait during scan, reset */
-	struct completion	scanning_done;	 /* wait for scan thread    */
+	wait_queue_head_t	delay_wait;	 /* wait during reset	    */
+	struct delayed_work	scan_dwork;	 /* for async scanning      */
 
 	/* subdriver information */
 	void			*extra;		 /* Any extra data          */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6ca0c40..a435942 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1123,6 +1123,18 @@
 	help
 	  Say Y here if you want to control the backlight of your display.
 
+config FB_I740
+	tristate "Intel740 support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && FB && PCI
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	select FB_DDC
+	help
+	  This driver supports graphics cards based on Intel740 chip.
+
 config FB_I810
 	tristate "Intel 810/815 support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL
@@ -2004,6 +2016,7 @@
 config FB_SH_MOBILE_MERAM
 	tristate "SuperH Mobile MERAM read ahead support for LCDC"
 	depends on FB_SH_MOBILE_LCDC
+	select GENERIC_ALLOCATOR
 	default y
 	---help---
 	  Enable MERAM support for the SH-Mobile LCD controller.
@@ -2411,7 +2424,7 @@
 
 source "drivers/video/omap/Kconfig"
 source "drivers/video/omap2/Kconfig"
-
+source "drivers/video/exynos/Kconfig"
 source "drivers/video/backlight/Kconfig"
 
 if VT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 1426068..9356add 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -15,6 +15,8 @@
 obj-$(CONFIG_LOGO)		  += logo/
 obj-y				  += backlight/
 
+obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/
+
 obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
 obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
 obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
@@ -37,6 +39,7 @@
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
 obj-$(CONFIG_FB_PM3)		  += pm3fb.o
 
+obj-$(CONFIG_FB_I740)		  += i740fb.o
 obj-$(CONFIG_FB_MATROX)		  += matrox/
 obj-$(CONFIG_FB_RIVA)		  += riva/
 obj-$(CONFIG_FB_NVIDIA)		  += nvidia/
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index e40c00f..d99505b 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -421,24 +421,18 @@
 		var->red.length = var->green.length = var->blue.length
 			= var->bits_per_pixel;
 		break;
-	case 15:
 	case 16:
 		if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
 			/* RGB:565 mode */
 			var->red.offset = 11;
 			var->blue.offset = 0;
-			var->green.length = 6;
-		} else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) {
-			var->red.offset = 10;
-			var->blue.offset = 0;
-			var->green.length = 5;
 		} else {
-			/* BGR:555 mode */
+			/* BGR:565 mode */
 			var->red.offset = 0;
-			var->blue.offset = 10;
-			var->green.length = 5;
+			var->blue.offset = 11;
 		}
 		var->green.offset = 5;
+		var->green.length = 6;
 		var->red.length = var->blue.length = 5;
 		break;
 	case 32:
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index de9da67..befcbd8 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -477,7 +477,8 @@
 	u32 sys_clksrc;
 
 	/* Allocate new device private */
-	fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL);
+	fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device),
+			     GFP_KERNEL);
 	if (!fbdev) {
 		print_err("fail to allocate device private record");
 		return -ENOMEM;
@@ -498,8 +499,9 @@
 	au1100fb_fix.mmio_start = regs_res->start;
 	au1100fb_fix.mmio_len = resource_size(regs_res);
 
-	if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
-				DRIVER_NAME)) {
+	if (!devm_request_mem_region(au1100fb_fix.mmio_start,
+				     au1100fb_fix.mmio_len,
+				     DRIVER_NAME)) {
 		print_err("fail to lock memory region at 0x%08lx",
 				au1100fb_fix.mmio_start);
 		return -EBUSY;
@@ -514,8 +516,9 @@
 	fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
 		  	(fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
 
-	fbdev->fb_mem = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
-					&fbdev->fb_phys, GFP_KERNEL);
+	fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev,
+					    PAGE_ALIGN(fbdev->fb_len),
+					    &fbdev->fb_phys, GFP_KERNEL);
 	if (!fbdev->fb_mem) {
 		print_err("fail to allocate frambuffer (size: %dK))",
 			  fbdev->fb_len / 1024);
@@ -557,14 +560,14 @@
 	fbdev->info.fbops = &au1100fb_ops;
 	fbdev->info.fix = au1100fb_fix;
 
-	if (!(fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL))) {
+	fbdev->info.pseudo_palette =
+		devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL);
+	if (!fbdev->info.pseudo_palette)
 		return -ENOMEM;
-	}
 
 	if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
 		print_err("Fail to allocate colormap (%d entries)",
 			   AU1100_LCD_NBR_PALETTE_ENTRIES);
-		kfree(fbdev->info.pseudo_palette);
 		return -EFAULT;
 	}
 
@@ -582,9 +585,6 @@
 	return 0;
 
 failed:
-	if (fbdev->regs) {
-		release_mem_region(fbdev->regs_phys, fbdev->regs_len);
-	}
 	if (fbdev->fb_mem) {
 		dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem,
 				     fbdev->fb_phys);
@@ -592,10 +592,9 @@
 	if (fbdev->info.cmap.len != 0) {
 		fb_dealloc_cmap(&fbdev->info.cmap);
 	}
-	kfree(fbdev);
 	platform_set_drvdata(dev, NULL);
 
-	return 0;
+	return -ENODEV;
 }
 
 int au1100fb_drv_remove(struct platform_device *dev)
@@ -615,14 +614,7 @@
 	/* Clean up all probe data */
 	unregister_framebuffer(&fbdev->info);
 
-	release_mem_region(fbdev->regs_phys, fbdev->regs_len);
-
-	dma_free_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem,
-			  fbdev->fb_phys);
-
 	fb_dealloc_cmap(&fbdev->info.cmap);
-	kfree(fbdev->info.pseudo_palette);
-	kfree((void*)fbdev);
 
 	return 0;
 }
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 04e4479..3e9a773 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1724,7 +1724,7 @@
 		/* Allocate the framebuffer to the maximum screen size */
 		fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
 
-		fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev,
+		fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev,
 				PAGE_ALIGN(fbdev->fb_len),
 				&fbdev->fb_phys, GFP_KERNEL);
 		if (!fbdev->fb_mem) {
@@ -1788,9 +1788,6 @@
 
 failed:
 	/* NOTE: This only does the current plane/window that failed; others are still active */
-	if (fbdev->fb_mem)
-		dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
-				fbdev->fb_mem, fbdev->fb_phys);
 	if (fbi) {
 		if (fbi->cmap.len != 0)
 			fb_dealloc_cmap(&fbi->cmap);
@@ -1817,10 +1814,6 @@
 
 		/* Clean up all probe data */
 		unregister_framebuffer(fbi);
-		if (fbdev->fb_mem)
-			dma_free_noncoherent(&dev->dev,
-					PAGE_ALIGN(fbdev->fb_len),
-					fbdev->fb_mem, fbdev->fb_phys);
 		if (fbi->cmap.len != 0)
 			fb_dealloc_cmap(&fbi->cmap);
 		kfree(fbi->pseudo_palette);
diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c
index bea53c1..befbc80 100644
--- a/drivers/video/bf537-lq035.c
+++ b/drivers/video/bf537-lq035.c
@@ -383,23 +383,19 @@
 	}
 
 #if (defined(UD) && defined(LBR))
-	if (gpio_request(UD, KBUILD_MODNAME)) {
+	if (gpio_request_one(UD, GPIOF_OUT_INIT_LOW, KBUILD_MODNAME)) {
 		pr_err("requesting GPIO %d failed\n", UD);
 		return -EBUSY;
 	}
 
-	if (gpio_request(LBR, KBUILD_MODNAME)) {
+	if (gpio_request_one(LBR, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) {
 		pr_err("requesting GPIO %d failed\n", LBR);
 		gpio_free(UD);
 		return -EBUSY;
 	}
-
-	gpio_direction_output(UD, 0);
-	gpio_direction_output(LBR, 1);
-
 #endif
 
-	if (gpio_request(MOD, KBUILD_MODNAME)) {
+	if (gpio_request_one(MOD, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) {
 		pr_err("requesting GPIO %d failed\n", MOD);
 #if (defined(UD) && defined(LBR))
 		gpio_free(LBR);
@@ -408,8 +404,6 @@
 		return -EBUSY;
 	}
 
-	gpio_direction_output(MOD, 1);
-
 	SSYNC();
 	return 0;
 }
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index 46b03f5..dc2f004 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -240,7 +240,7 @@
 	u16 eppi_req_18[] = EPPI0_18;
 	u16 disp = fbi->mach_info->disp;
 
-	if (gpio_request(disp, DRIVER_NAME)) {
+	if (gpio_request_one(disp, GPIOF_OUT_INIT_HIGH, DRIVER_NAME)) {
 		printk(KERN_ERR "Requesting GPIO %d failed\n", disp);
 		return -EFAULT;
 	}
@@ -263,8 +263,6 @@
 		}
 	}
 
-	gpio_direction_output(disp, 1);
-
 	return 0;
 }
 
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index c633068..86922ac 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -365,10 +365,10 @@
 	 * Drive PPI_FS3 Low
 	 */
 	if (ANOMALY_05000400) {
-		int ret = gpio_request(P_IDENT(P_PPI0_FS3), "PPI_FS3");
+		int ret = gpio_request_one(P_IDENT(P_PPI0_FS3),
+					GPIOF_OUT_INIT_LOW, "PPI_FS3");
 		if (ret)
 			return ret;
-		gpio_direction_output(P_IDENT(P_PPI0_FS3), 0);
 	}
 
 	if (ppi16)
@@ -716,14 +716,14 @@
 	}
 
 	if (info->disp_info->use_bl) {
-		ret = gpio_request(info->disp_info->gpio_bl, "LQ035 Backlight");
+		ret = gpio_request_one(info->disp_info->gpio_bl,
+					GPIOF_OUT_INIT_LOW, "LQ035 Backlight");
 
 		if (ret) {
 			dev_err(&pdev->dev, "failed to request GPIO %d\n",
 				info->disp_info->gpio_bl);
 			goto out9;
 		}
-		gpio_direction_output(info->disp_info->gpio_bl, 0);
 	}
 
 	ret = register_framebuffer(fbinfo);
diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c
index 811dd7f..c992814 100644
--- a/drivers/video/bfin_adv7393fb.c
+++ b/drivers/video/bfin_adv7393fb.c
@@ -411,12 +411,13 @@
 
 	/* Workaround "PPI Does Not Start Properly In Specific Mode" */
 	if (ANOMALY_05000400) {
-		if (gpio_request(P_IDENT(P_PPI0_FS3), "PPI0_FS3")) {
+		ret = gpio_request_one(P_IDENT(P_PPI0_FS3), GPIOF_OUT_INIT_LOW,
+					"PPI0_FS3")
+		if (ret) {
 			dev_err(&client->dev, "PPI0_FS3 GPIO request failed\n");
 			ret = -EBUSY;
 			goto out_8;
 		}
-		gpio_direction_output(P_IDENT(P_PPI0_FS3), 0);
 	}
 
 	if (peripheral_request_list(ppi_pins, DRIVER_NAME)) {
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 29577bf..dd80386 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -32,6 +32,7 @@
 #include <linux/console.h>
 #include <linux/slab.h>
 #include <video/da8xx-fb.h>
+#include <asm/div64.h>
 
 #define DRIVER_NAME "da8xx_lcdc"
 
@@ -161,6 +162,7 @@
 	int			vsync_timeout;
 #ifdef CONFIG_CPU_FREQ
 	struct notifier_block	freq_transition;
+	unsigned int		lcd_fck_rate;
 #endif
 	void (*panel_power_ctrl)(int);
 };
@@ -174,7 +176,6 @@
 	.activate = 0,
 	.height = -1,
 	.width = -1,
-	.pixclock = 46666,	/* 46us - AUO display */
 	.accel_flags = 0,
 	.left_margin = LEFT_MARGIN,
 	.right_margin = RIGHT_MARGIN,
@@ -840,11 +841,13 @@
 	struct da8xx_fb_par *par;
 
 	par = container_of(nb, struct da8xx_fb_par, freq_transition);
-	if (val == CPUFREQ_PRECHANGE) {
-		lcd_disable_raster();
-	} else if (val == CPUFREQ_POSTCHANGE) {
-		lcd_calc_clk_divider(par);
-		lcd_enable_raster();
+	if (val == CPUFREQ_POSTCHANGE) {
+		if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
+			par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
+			lcd_disable_raster();
+			lcd_calc_clk_divider(par);
+			lcd_enable_raster();
+		}
 	}
 
 	return 0;
@@ -1048,6 +1051,22 @@
 	.fb_blank = cfb_blank,
 };
 
+/* Calculate and return pixel clock period in pico seconds */
+static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
+{
+	unsigned int lcd_clk, div;
+	unsigned int configured_pix_clk;
+	unsigned long long pix_clk_period_picosec = 1000000000000ULL;
+
+	lcd_clk = clk_get_rate(par->lcdc_clk);
+	div = lcd_clk / par->pxl_clk;
+	configured_pix_clk = (lcd_clk / div);
+
+	do_div(pix_clk_period_picosec, configured_pix_clk);
+
+	return pix_clk_period_picosec;
+}
+
 static int __devinit fb_probe(struct platform_device *device)
 {
 	struct da8xx_lcdc_platform_data *fb_pdata =
@@ -1137,6 +1156,9 @@
 
 	par = da8xx_fb_info->par;
 	par->lcdc_clk = fb_clk;
+#ifdef CONFIG_CPU_FREQ
+	par->lcd_fck_rate = clk_get_rate(fb_clk);
+#endif
 	par->pxl_clk = lcdc_info->pxl_clk;
 	if (fb_pdata->panel_power_ctrl) {
 		par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
@@ -1209,6 +1231,7 @@
 
 	da8xx_fb_var.hsync_len = lcdc_info->hsw;
 	da8xx_fb_var.vsync_len = lcdc_info->vsw;
+	da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
 
 	/* Initialize fbinfo */
 	da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
@@ -1264,8 +1287,8 @@
 irq_freq:
 #ifdef CONFIG_CPU_FREQ
 	lcd_da8xx_cpufreq_deregister(par);
-#endif
 err_cpu_freq:
+#endif
 	unregister_framebuffer(da8xx_fb_info);
 
 err_dealloc_cmap:
diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig
new file mode 100644
index 0000000..1b035b2
--- /dev/null
+++ b/drivers/video/exynos/Kconfig
@@ -0,0 +1,37 @@
+#
+# Exynos Video configuration
+#
+
+menuconfig EXYNOS_VIDEO
+	bool "Exynos Video driver support"
+	help
+	  This enables support for EXYNOS Video device.
+
+if EXYNOS_VIDEO
+
+#
+# MIPI DSI driver
+#
+
+config EXYNOS_MIPI_DSI
+	bool "EXYNOS MIPI DSI driver support."
+	depends on ARCH_S5PV210 || ARCH_EXYNOS
+	help
+	  This enables support for MIPI-DSI device.
+
+config EXYNOS_LCD_S6E8AX0
+	bool "S6E8AX0 MIPI AMOLED LCD Driver"
+	depends on (EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE)
+	default n
+	help
+	  If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its
+	  LCD control driver.
+
+config EXYNOS_DP
+	bool "EXYNOS DP driver support"
+	depends on ARCH_EXYNOS
+	default n
+	help
+	  This enables support for DP device.
+
+endif # EXYNOS_VIDEO
diff --git a/drivers/video/exynos/Makefile b/drivers/video/exynos/Makefile
new file mode 100644
index 0000000..ec7772e
--- /dev/null
+++ b/drivers/video/exynos/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the exynos video drivers.
+#
+
+obj-$(CONFIG_EXYNOS_MIPI_DSI)		+= exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
+				     	exynos_mipi_dsi_lowlevel.o
+obj-$(CONFIG_EXYNOS_LCD_S6E8AX0)	+= s6e8ax0.o
+obj-$(CONFIG_EXYNOS_DP)			+= exynos_dp_core.o exynos_dp_reg.o
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
new file mode 100644
index 0000000..2a4481c
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -0,0 +1,1058 @@
+/*
+ * Samsung SoC DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <video/exynos_dp.h>
+
+#include <plat/cpu.h>
+
+#include "exynos_dp_core.h"
+
+static int exynos_dp_init_dp(struct exynos_dp_device *dp)
+{
+	exynos_dp_reset(dp);
+
+	/* SW defined function Normal operation */
+	exynos_dp_enable_sw_function(dp);
+
+	exynos_dp_config_interrupt(dp);
+	exynos_dp_init_analog_func(dp);
+
+	exynos_dp_init_hpd(dp);
+	exynos_dp_init_aux(dp);
+
+	return 0;
+}
+
+static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
+{
+	int timeout_loop = 0;
+
+	exynos_dp_init_hpd(dp);
+
+	udelay(200);
+
+	while (exynos_dp_get_plug_in_status(dp) != 0) {
+		timeout_loop++;
+		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+			dev_err(dp->dev, "failed to get hpd plug status\n");
+			return -ETIMEDOUT;
+		}
+		udelay(10);
+	}
+
+	return 0;
+}
+
+static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
+{
+	int i;
+	unsigned char sum = 0;
+
+	for (i = 0; i < EDID_BLOCK_LENGTH; i++)
+		sum = sum + edid_data[i];
+
+	return sum;
+}
+
+static int exynos_dp_read_edid(struct exynos_dp_device *dp)
+{
+	unsigned char edid[EDID_BLOCK_LENGTH * 2];
+	unsigned int extend_block = 0;
+	unsigned char sum;
+	unsigned char test_vector;
+	int retval;
+
+	/*
+	 * EDID device address is 0x50.
+	 * However, if necessary, you must have set upper address
+	 * into E-EDID in I2C device, 0x30.
+	 */
+
+	/* Read Extension Flag, Number of 128-byte EDID extension blocks */
+	exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+				EDID_EXTENSION_FLAG,
+				&extend_block);
+
+	if (extend_block > 0) {
+		dev_dbg(dp->dev, "EDID data includes a single extension!\n");
+
+		/* Read EDID data */
+		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+						EDID_HEADER_PATTERN,
+						EDID_BLOCK_LENGTH,
+						&edid[EDID_HEADER_PATTERN]);
+		if (retval != 0) {
+			dev_err(dp->dev, "EDID Read failed!\n");
+			return -EIO;
+		}
+		sum = exynos_dp_calc_edid_check_sum(edid);
+		if (sum != 0) {
+			dev_err(dp->dev, "EDID bad checksum!\n");
+			return -EIO;
+		}
+
+		/* Read additional EDID data */
+		retval = exynos_dp_read_bytes_from_i2c(dp,
+				I2C_EDID_DEVICE_ADDR,
+				EDID_BLOCK_LENGTH,
+				EDID_BLOCK_LENGTH,
+				&edid[EDID_BLOCK_LENGTH]);
+		if (retval != 0) {
+			dev_err(dp->dev, "EDID Read failed!\n");
+			return -EIO;
+		}
+		sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
+		if (sum != 0) {
+			dev_err(dp->dev, "EDID bad checksum!\n");
+			return -EIO;
+		}
+
+		exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_TEST_REQUEST,
+					&test_vector);
+		if (test_vector & DPCD_TEST_EDID_READ) {
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TEST_EDID_CHECKSUM,
+				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TEST_RESPONSE,
+				DPCD_TEST_EDID_CHECKSUM_WRITE);
+		}
+	} else {
+		dev_info(dp->dev, "EDID data does not include any extensions.\n");
+
+		/* Read EDID data */
+		retval = exynos_dp_read_bytes_from_i2c(dp,
+				I2C_EDID_DEVICE_ADDR,
+				EDID_HEADER_PATTERN,
+				EDID_BLOCK_LENGTH,
+				&edid[EDID_HEADER_PATTERN]);
+		if (retval != 0) {
+			dev_err(dp->dev, "EDID Read failed!\n");
+			return -EIO;
+		}
+		sum = exynos_dp_calc_edid_check_sum(edid);
+		if (sum != 0) {
+			dev_err(dp->dev, "EDID bad checksum!\n");
+			return -EIO;
+		}
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_TEST_REQUEST,
+			&test_vector);
+		if (test_vector & DPCD_TEST_EDID_READ) {
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TEST_EDID_CHECKSUM,
+				edid[EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TEST_RESPONSE,
+				DPCD_TEST_EDID_CHECKSUM_WRITE);
+		}
+	}
+
+	dev_err(dp->dev, "EDID Read success!\n");
+	return 0;
+}
+
+static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
+{
+	u8 buf[12];
+	int i;
+	int retval;
+
+	/* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
+	exynos_dp_read_bytes_from_dpcd(dp,
+		DPCD_ADDR_DPCD_REV,
+		12, buf);
+
+	/* Read EDID */
+	for (i = 0; i < 3; i++) {
+		retval = exynos_dp_read_edid(dp);
+		if (retval == 0)
+			break;
+	}
+
+	return retval;
+}
+
+static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
+						bool enable)
+{
+	u8 data;
+
+	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, &data);
+
+	if (enable)
+		exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
+			DPCD_ENHANCED_FRAME_EN |
+			DPCD_LANE_COUNT_SET(data));
+	else
+		exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
+			DPCD_LANE_COUNT_SET(data));
+}
+
+static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
+{
+	u8 data;
+	int retval;
+
+	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
+	retval = DPCD_ENHANCED_FRAME_CAP(data);
+
+	return retval;
+}
+
+static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp)
+{
+	u8 data;
+
+	data = exynos_dp_is_enhanced_mode_available(dp);
+	exynos_dp_enable_rx_to_enhanced_mode(dp, data);
+	exynos_dp_enable_enhanced_mode(dp, data);
+}
+
+static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
+{
+	exynos_dp_set_training_pattern(dp, DP_NONE);
+
+	exynos_dp_write_byte_to_dpcd(dp,
+		DPCD_ADDR_TRAINING_PATTERN_SET,
+		DPCD_TRAINING_PATTERN_DISABLED);
+}
+
+static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
+					int pre_emphasis, int lane)
+{
+	switch (lane) {
+	case 0:
+		exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
+		break;
+	case 1:
+		exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
+		break;
+
+	case 2:
+		exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
+		break;
+
+	case 3:
+		exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
+		break;
+	}
+}
+
+static void exynos_dp_link_start(struct exynos_dp_device *dp)
+{
+	u8 buf[5];
+	int lane;
+	int lane_count;
+
+	lane_count = dp->link_train.lane_count;
+
+	dp->link_train.lt_state = CLOCK_RECOVERY;
+	dp->link_train.eq_loop = 0;
+
+	for (lane = 0; lane < lane_count; lane++)
+		dp->link_train.cr_loop[lane] = 0;
+
+	/* Set sink to D0 (Sink Not Ready) mode. */
+	exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
+				DPCD_SET_POWER_STATE_D0);
+
+	/* Set link rate and count as you want to establish*/
+	exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
+	exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
+
+	/* Setup RX configuration */
+	buf[0] = dp->link_train.link_rate;
+	buf[1] = dp->link_train.lane_count;
+	exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
+				2, buf);
+
+	/* Set TX pre-emphasis to minimum */
+	for (lane = 0; lane < lane_count; lane++)
+		exynos_dp_set_lane_lane_pre_emphasis(dp,
+			PRE_EMPHASIS_LEVEL_0, lane);
+
+	/* Set training pattern 1 */
+	exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
+
+	/* Set RX training pattern */
+	buf[0] = DPCD_SCRAMBLING_DISABLED |
+		 DPCD_TRAINING_PATTERN_1;
+	exynos_dp_write_byte_to_dpcd(dp,
+		DPCD_ADDR_TRAINING_PATTERN_SET, buf[0]);
+
+	for (lane = 0; lane < lane_count; lane++)
+		buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
+			    DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
+	exynos_dp_write_bytes_to_dpcd(dp,
+		DPCD_ADDR_TRAINING_PATTERN_SET,
+		lane_count, buf);
+}
+
+static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
+{
+	int shift = (lane & 1) * 4;
+	u8 link_value = link_status[lane>>1];
+
+	return (link_value >> shift) & 0xf;
+}
+
+static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
+{
+	int lane;
+	u8 lane_status;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = exynos_dp_get_lane_status(link_status, lane);
+		if ((lane_status & DPCD_LANE_CR_DONE) == 0)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
+{
+	int lane;
+	u8 lane_align;
+	u8 lane_status;
+
+	lane_align = link_status[2];
+	if ((lane_align == DPCD_INTERLANE_ALIGN_DONE) == 0)
+		return -EINVAL;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = exynos_dp_get_lane_status(link_status, lane);
+		lane_status &= DPCD_CHANNEL_EQ_BITS;
+		if (lane_status != DPCD_CHANNEL_EQ_BITS)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
+							int lane)
+{
+	int shift = (lane & 1) * 4;
+	u8 link_value = adjust_request[lane>>1];
+
+	return (link_value >> shift) & 0x3;
+}
+
+static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
+					u8 adjust_request[2],
+					int lane)
+{
+	int shift = (lane & 1) * 4;
+	u8 link_value = adjust_request[lane>>1];
+
+	return ((link_value >> shift) & 0xc) >> 2;
+}
+
+static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
+					u8 training_lane_set, int lane)
+{
+	switch (lane) {
+	case 0:
+		exynos_dp_set_lane0_link_training(dp, training_lane_set);
+		break;
+	case 1:
+		exynos_dp_set_lane1_link_training(dp, training_lane_set);
+		break;
+
+	case 2:
+		exynos_dp_set_lane2_link_training(dp, training_lane_set);
+		break;
+
+	case 3:
+		exynos_dp_set_lane3_link_training(dp, training_lane_set);
+		break;
+	}
+}
+
+static unsigned int exynos_dp_get_lane_link_training(
+				struct exynos_dp_device *dp,
+				int lane)
+{
+	u32 reg;
+
+	switch (lane) {
+	case 0:
+		reg = exynos_dp_get_lane0_link_training(dp);
+		break;
+	case 1:
+		reg = exynos_dp_get_lane1_link_training(dp);
+		break;
+	case 2:
+		reg = exynos_dp_get_lane2_link_training(dp);
+		break;
+	case 3:
+		reg = exynos_dp_get_lane3_link_training(dp);
+		break;
+	}
+
+	return reg;
+}
+
+static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
+{
+	if (dp->link_train.link_rate == LINK_RATE_2_70GBPS) {
+		/* set to reduced bit rate */
+		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
+		dev_err(dp->dev, "set to bandwidth %.2x\n",
+			dp->link_train.link_rate);
+		dp->link_train.lt_state = START;
+	} else {
+		exynos_dp_training_pattern_dis(dp);
+		/* set enhanced mode if available */
+		exynos_dp_set_enhanced_mode(dp);
+		dp->link_train.lt_state = FAILED;
+	}
+}
+
+static void exynos_dp_get_adjust_train(struct exynos_dp_device *dp,
+				u8 adjust_request[2])
+{
+	int lane;
+	int lane_count;
+	u8 voltage_swing;
+	u8 pre_emphasis;
+	u8 training_lane;
+
+	lane_count = dp->link_train.lane_count;
+	for (lane = 0; lane < lane_count; lane++) {
+		voltage_swing = exynos_dp_get_adjust_request_voltage(
+						adjust_request, lane);
+		pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+						adjust_request, lane);
+		training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+				DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+		if (voltage_swing == VOLTAGE_LEVEL_3 ||
+		   pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
+			training_lane |= DPCD_MAX_SWING_REACHED;
+			training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+		}
+		dp->link_train.training_lane[lane] = training_lane;
+	}
+}
+
+static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp,
+					u8 voltage_swing)
+{
+	int lane;
+	int lane_count;
+
+	lane_count = dp->link_train.lane_count;
+	for (lane = 0; lane < lane_count; lane++) {
+		if (voltage_swing == VOLTAGE_LEVEL_3 ||
+			dp->link_train.cr_loop[lane] == MAX_CR_LOOP)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
+{
+	u8 data;
+	u8 link_status[6];
+	int lane;
+	int lane_count;
+	u8 buf[5];
+
+	u8 *adjust_request;
+	u8 voltage_swing;
+	u8 pre_emphasis;
+	u8 training_lane;
+
+	udelay(100);
+
+	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+				6, link_status);
+	lane_count = dp->link_train.lane_count;
+
+	if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
+		/* set training pattern 2 for EQ */
+		exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
+
+		adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
+						- DPCD_ADDR_LANE0_1_STATUS);
+
+		exynos_dp_get_adjust_train(dp, adjust_request);
+
+		buf[0] = DPCD_SCRAMBLING_DISABLED |
+			 DPCD_TRAINING_PATTERN_2;
+		exynos_dp_write_byte_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_LANE0_SET,
+			buf[0]);
+
+		for (lane = 0; lane < lane_count; lane++) {
+			exynos_dp_set_lane_link_training(dp,
+				dp->link_train.training_lane[lane],
+				lane);
+			buf[lane] = dp->link_train.training_lane[lane];
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TRAINING_LANE0_SET + lane,
+				buf[lane]);
+		}
+		dp->link_train.lt_state = EQUALIZER_TRAINING;
+	} else {
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+			&data);
+		adjust_request[0] = data;
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_ADJUST_REQUEST_LANE2_3,
+			&data);
+		adjust_request[1] = data;
+
+		for (lane = 0; lane < lane_count; lane++) {
+			training_lane = exynos_dp_get_lane_link_training(
+							dp, lane);
+			voltage_swing = exynos_dp_get_adjust_request_voltage(
+							adjust_request, lane);
+			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+							adjust_request, lane);
+			if ((DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing) &&
+			    (DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis))
+				dp->link_train.cr_loop[lane]++;
+			dp->link_train.training_lane[lane] = training_lane;
+		}
+
+		if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) {
+			exynos_dp_reduce_link_rate(dp);
+		} else {
+			exynos_dp_get_adjust_train(dp, adjust_request);
+
+			for (lane = 0; lane < lane_count; lane++) {
+				exynos_dp_set_lane_link_training(dp,
+					dp->link_train.training_lane[lane],
+					lane);
+				buf[lane] = dp->link_train.training_lane[lane];
+				exynos_dp_write_byte_to_dpcd(dp,
+					DPCD_ADDR_TRAINING_LANE0_SET + lane,
+					buf[lane]);
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
+{
+	u8 link_status[6];
+	int lane;
+	int lane_count;
+	u8 buf[5];
+	u32 reg;
+
+	u8 *adjust_request;
+
+	udelay(400);
+
+	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+				6, link_status);
+	lane_count = dp->link_train.lane_count;
+
+	if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
+		adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
+						- DPCD_ADDR_LANE0_1_STATUS);
+
+		if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
+			/* traing pattern Set to Normal */
+			exynos_dp_training_pattern_dis(dp);
+
+			dev_info(dp->dev, "Link Training success!\n");
+
+			exynos_dp_get_link_bandwidth(dp, &reg);
+			dp->link_train.link_rate = reg;
+			dev_dbg(dp->dev, "final bandwidth = %.2x\n",
+				dp->link_train.link_rate);
+
+			exynos_dp_get_lane_count(dp, &reg);
+			dp->link_train.lane_count = reg;
+			dev_dbg(dp->dev, "final lane count = %.2x\n",
+				dp->link_train.lane_count);
+			/* set enhanced mode if available */
+			exynos_dp_set_enhanced_mode(dp);
+
+			dp->link_train.lt_state = FINISHED;
+		} else {
+			/* not all locked */
+			dp->link_train.eq_loop++;
+
+			if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
+				exynos_dp_reduce_link_rate(dp);
+			} else {
+				exynos_dp_get_adjust_train(dp, adjust_request);
+
+				for (lane = 0; lane < lane_count; lane++) {
+					exynos_dp_set_lane_link_training(dp,
+						dp->link_train.training_lane[lane],
+						lane);
+					buf[lane] = dp->link_train.training_lane[lane];
+					exynos_dp_write_byte_to_dpcd(dp,
+						DPCD_ADDR_TRAINING_LANE0_SET + lane,
+						buf[lane]);
+				}
+			}
+		}
+	} else {
+		exynos_dp_reduce_link_rate(dp);
+	}
+
+	return 0;
+}
+
+static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
+			u8 *bandwidth)
+{
+	u8 data;
+
+	/*
+	 * For DP rev.1.1, Maximum link rate of Main Link lanes
+	 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
+	 */
+	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LINK_RATE, &data);
+	*bandwidth = data;
+}
+
+static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
+			u8 *lane_count)
+{
+	u8 data;
+
+	/*
+	 * For DP rev.1.1, Maximum number of Main Link lanes
+	 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
+	 */
+	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
+	*lane_count = DPCD_MAX_LANE_COUNT(data);
+}
+
+static void exynos_dp_init_training(struct exynos_dp_device *dp,
+			enum link_lane_count_type max_lane,
+			enum link_rate_type max_rate)
+{
+	/*
+	 * MACRO_RST must be applied after the PLL_LOCK to avoid
+	 * the DP inter pair skew issue for at least 10 us
+	 */
+	exynos_dp_reset_macro(dp);
+
+	/* Initialize by reading RX's DPCD */
+	exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
+	exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
+
+	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
+	   (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
+			dp->link_train.link_rate);
+		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
+	}
+
+	if (dp->link_train.lane_count == 0) {
+		dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n",
+			dp->link_train.lane_count);
+		dp->link_train.lane_count = (u8)LANE_COUNT1;
+	}
+
+	/* Setup TX lane count & rate */
+	if (dp->link_train.lane_count > max_lane)
+		dp->link_train.lane_count = max_lane;
+	if (dp->link_train.link_rate > max_rate)
+		dp->link_train.link_rate = max_rate;
+
+	/* All DP analog module power up */
+	exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
+}
+
+static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
+{
+	int retval = 0;
+	int training_finished;
+
+	/* Turn off unnecessary lane */
+	if (dp->link_train.lane_count == 1)
+		exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1);
+
+	training_finished = 0;
+
+	dp->link_train.lt_state = START;
+
+	/* Process here */
+	while (!training_finished) {
+		switch (dp->link_train.lt_state) {
+		case START:
+			exynos_dp_link_start(dp);
+			break;
+		case CLOCK_RECOVERY:
+			exynos_dp_process_clock_recovery(dp);
+			break;
+		case EQUALIZER_TRAINING:
+			exynos_dp_process_equalizer_training(dp);
+			break;
+		case FINISHED:
+			training_finished = 1;
+			break;
+		case FAILED:
+			return -EREMOTEIO;
+		}
+	}
+
+	return retval;
+}
+
+static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
+				u32 count,
+				u32 bwtype)
+{
+	int i;
+	int retval;
+
+	for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
+		exynos_dp_init_training(dp, count, bwtype);
+		retval = exynos_dp_sw_link_training(dp);
+		if (retval == 0)
+			break;
+
+		udelay(100);
+	}
+
+	return retval;
+}
+
+static int exynos_dp_config_video(struct exynos_dp_device *dp,
+			struct video_info *video_info)
+{
+	int retval = 0;
+	int timeout_loop = 0;
+	int done_count = 0;
+
+	exynos_dp_config_video_slave_mode(dp, video_info);
+
+	exynos_dp_set_video_color_format(dp, video_info->color_depth,
+			video_info->color_space,
+			video_info->dynamic_range,
+			video_info->ycbcr_coeff);
+
+	if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+		dev_err(dp->dev, "PLL is not locked yet.\n");
+		return -EINVAL;
+	}
+
+	for (;;) {
+		timeout_loop++;
+		if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0)
+			break;
+		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+			dev_err(dp->dev, "Timeout of video streamclk ok\n");
+			return -ETIMEDOUT;
+		}
+
+		mdelay(100);
+	}
+
+	/* Set to use the register calculated M/N video */
+	exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
+
+	/* For video bist, Video timing must be generated by register */
+	exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);
+
+	/* Disable video mute */
+	exynos_dp_enable_video_mute(dp, 0);
+
+	/* Configure video slave mode */
+	exynos_dp_enable_video_master(dp, 0);
+
+	/* Enable video */
+	exynos_dp_start_video(dp);
+
+	timeout_loop = 0;
+
+	for (;;) {
+		timeout_loop++;
+		if (exynos_dp_is_video_stream_on(dp) == 0) {
+			done_count++;
+			if (done_count > 10)
+				break;
+		} else if (done_count) {
+			done_count = 0;
+		}
+		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+			dev_err(dp->dev, "Timeout of video streamclk ok\n");
+			return -ETIMEDOUT;
+		}
+
+		mdelay(100);
+	}
+
+	if (retval != 0)
+		dev_err(dp->dev, "Video stream is not detected!\n");
+
+	return retval;
+}
+
+static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
+{
+	u8 data;
+
+	if (enable) {
+		exynos_dp_enable_scrambling(dp);
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			&data);
+		exynos_dp_write_byte_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			(u8)(data & ~DPCD_SCRAMBLING_DISABLED));
+	} else {
+		exynos_dp_disable_scrambling(dp);
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			&data);
+		exynos_dp_write_byte_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			(u8)(data | DPCD_SCRAMBLING_DISABLED));
+	}
+}
+
+static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
+{
+	struct exynos_dp_device *dp = arg;
+
+	dev_err(dp->dev, "exynos_dp_irq_handler\n");
+	return IRQ_HANDLED;
+}
+
+static int __devinit exynos_dp_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct exynos_dp_device *dp;
+	struct exynos_dp_platdata *pdata;
+
+	int ret = 0;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "no platform data\n");
+		return -EINVAL;
+	}
+
+	dp = kzalloc(sizeof(struct exynos_dp_device), GFP_KERNEL);
+	if (!dp) {
+		dev_err(&pdev->dev, "no memory for device data\n");
+		return -ENOMEM;
+	}
+
+	dp->dev = &pdev->dev;
+
+	dp->clock = clk_get(&pdev->dev, "dp");
+	if (IS_ERR(dp->clock)) {
+		dev_err(&pdev->dev, "failed to get clock\n");
+		ret = PTR_ERR(dp->clock);
+		goto err_dp;
+	}
+
+	clk_enable(dp->clock);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get registers\n");
+		ret = -EINVAL;
+		goto err_clock;
+	}
+
+	res = request_mem_region(res->start, resource_size(res),
+				dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "failed to request registers region\n");
+		ret = -EINVAL;
+		goto err_clock;
+	}
+
+	dp->res = res;
+
+	dp->reg_base = ioremap(res->start, resource_size(res));
+	if (!dp->reg_base) {
+		dev_err(&pdev->dev, "failed to ioremap\n");
+		ret = -ENOMEM;
+		goto err_req_region;
+	}
+
+	dp->irq = platform_get_irq(pdev, 0);
+	if (!dp->irq) {
+		dev_err(&pdev->dev, "failed to get irq\n");
+		ret = -ENODEV;
+		goto err_ioremap;
+	}
+
+	ret = request_irq(dp->irq, exynos_dp_irq_handler, 0,
+			"exynos-dp", dp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request irq\n");
+		goto err_ioremap;
+	}
+
+	dp->video_info = pdata->video_info;
+	if (pdata->phy_init)
+		pdata->phy_init();
+
+	exynos_dp_init_dp(dp);
+
+	ret = exynos_dp_detect_hpd(dp);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to detect hpd\n");
+		goto err_irq;
+	}
+
+	exynos_dp_handle_edid(dp);
+
+	ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
+				dp->video_info->link_rate);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to do link train\n");
+		goto err_irq;
+	}
+
+	exynos_dp_enable_scramble(dp, 1);
+	exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
+	exynos_dp_enable_enhanced_mode(dp, 1);
+
+	exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
+	exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
+
+	exynos_dp_init_video(dp);
+	ret = exynos_dp_config_video(dp, dp->video_info);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to config video\n");
+		goto err_irq;
+	}
+
+	platform_set_drvdata(pdev, dp);
+
+	return 0;
+
+err_irq:
+	free_irq(dp->irq, dp);
+err_ioremap:
+	iounmap(dp->reg_base);
+err_req_region:
+	release_mem_region(res->start, resource_size(res));
+err_clock:
+	clk_put(dp->clock);
+err_dp:
+	kfree(dp);
+
+	return ret;
+}
+
+static int __devexit exynos_dp_remove(struct platform_device *pdev)
+{
+	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
+	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+
+	if (pdata && pdata->phy_exit)
+		pdata->phy_exit();
+
+	free_irq(dp->irq, dp);
+	iounmap(dp->reg_base);
+
+	clk_disable(dp->clock);
+	clk_put(dp->clock);
+
+	release_mem_region(dp->res->start, resource_size(dp->res));
+
+	kfree(dp);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos_dp_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
+	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+
+	if (pdata && pdata->phy_exit)
+		pdata->phy_exit();
+
+	clk_disable(dp->clock);
+
+	return 0;
+}
+
+static int exynos_dp_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
+	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+
+	if (pdata && pdata->phy_init)
+		pdata->phy_init();
+
+	clk_enable(dp->clock);
+
+	exynos_dp_init_dp(dp);
+
+	exynos_dp_detect_hpd(dp);
+	exynos_dp_handle_edid(dp);
+
+	exynos_dp_set_link_train(dp, dp->video_info->lane_count,
+				dp->video_info->link_rate);
+
+	exynos_dp_enable_scramble(dp, 1);
+	exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
+	exynos_dp_enable_enhanced_mode(dp, 1);
+
+	exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
+	exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
+
+	exynos_dp_init_video(dp);
+	exynos_dp_config_video(dp, dp->video_info);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops exynos_dp_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
+};
+
+static struct platform_driver exynos_dp_driver = {
+	.probe		= exynos_dp_probe,
+	.remove		= __devexit_p(exynos_dp_remove),
+	.driver		= {
+		.name	= "exynos-dp",
+		.owner	= THIS_MODULE,
+		.pm	= &exynos_dp_pm_ops,
+	},
+};
+
+module_platform_driver(exynos_dp_driver);
+
+MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_DESCRIPTION("Samsung SoC DP Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
new file mode 100644
index 0000000..90ceaca
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -0,0 +1,206 @@
+/*
+ * Header file for Samsung DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.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.
+ */
+
+#ifndef _EXYNOS_DP_CORE_H
+#define _EXYNOS_DP_CORE_H
+
+struct link_train {
+	int eq_loop;
+	int cr_loop[4];
+
+	u8 link_rate;
+	u8 lane_count;
+	u8 training_lane[4];
+
+	enum link_training_state lt_state;
+};
+
+struct exynos_dp_device {
+	struct device		*dev;
+	struct resource		*res;
+	struct clk		*clock;
+	unsigned int		irq;
+	void __iomem		*reg_base;
+
+	struct video_info	*video_info;
+	struct link_train	link_train;
+};
+
+/* exynos_dp_reg.c */
+void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_stop_video(struct exynos_dp_device *dp);
+void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
+void exynos_dp_reset(struct exynos_dp_device *dp);
+void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
+u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
+void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
+				enum analog_power_block block,
+				bool enable);
+void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
+void exynos_dp_init_hpd(struct exynos_dp_device *dp);
+void exynos_dp_reset_aux(struct exynos_dp_device *dp);
+void exynos_dp_init_aux(struct exynos_dp_device *dp);
+int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
+void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
+int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
+int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned char data);
+int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned char *data);
+int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char data[]);
+int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char data[]);
+int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr);
+int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr,
+				unsigned int *data);
+int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char edid[]);
+void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
+void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
+void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
+void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
+void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
+void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
+void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
+void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
+void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
+				 enum pattern_set pattern);
+void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
+void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
+void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
+void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
+void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
+				u32 training_lane);
+void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
+				u32 training_lane);
+void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
+				u32 training_lane);
+void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
+				u32 training_lane);
+u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
+u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
+u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
+u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
+void exynos_dp_reset_macro(struct exynos_dp_device *dp);
+int exynos_dp_init_video(struct exynos_dp_device *dp);
+
+void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
+				u32 color_depth,
+				u32 color_space,
+				u32 dynamic_range,
+				u32 ycbcr_coeff);
+int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
+void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
+			enum clock_recovery_m_value_type type,
+			u32 m_value,
+			u32 n_value);
+void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
+void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_start_video(struct exynos_dp_device *dp);
+int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
+void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
+			struct video_info *video_info);
+void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
+void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
+
+/* I2C EDID Chip ID, Slave Address */
+#define I2C_EDID_DEVICE_ADDR			0x50
+#define I2C_E_EDID_DEVICE_ADDR			0x30
+
+#define EDID_BLOCK_LENGTH			0x80
+#define EDID_HEADER_PATTERN			0x00
+#define EDID_EXTENSION_FLAG			0x7e
+#define EDID_CHECKSUM				0x7f
+
+/* Definition for DPCD Register */
+#define DPCD_ADDR_DPCD_REV			0x0000
+#define DPCD_ADDR_MAX_LINK_RATE			0x0001
+#define DPCD_ADDR_MAX_LANE_COUNT		0x0002
+#define DPCD_ADDR_LINK_BW_SET			0x0100
+#define DPCD_ADDR_LANE_COUNT_SET		0x0101
+#define DPCD_ADDR_TRAINING_PATTERN_SET		0x0102
+#define DPCD_ADDR_TRAINING_LANE0_SET		0x0103
+#define DPCD_ADDR_LANE0_1_STATUS		0x0202
+#define DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED	0x0204
+#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1	0x0206
+#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3	0x0207
+#define DPCD_ADDR_TEST_REQUEST			0x0218
+#define DPCD_ADDR_TEST_RESPONSE			0x0260
+#define DPCD_ADDR_TEST_EDID_CHECKSUM		0x0261
+#define DPCD_ADDR_SINK_POWER_STATE		0x0600
+
+/* DPCD_ADDR_MAX_LANE_COUNT */
+#define DPCD_ENHANCED_FRAME_CAP(x)		(((x) >> 7) & 0x1)
+#define DPCD_MAX_LANE_COUNT(x)			((x) & 0x1f)
+
+/* DPCD_ADDR_LANE_COUNT_SET */
+#define DPCD_ENHANCED_FRAME_EN			(0x1 << 7)
+#define DPCD_LANE_COUNT_SET(x)			((x) & 0x1f)
+
+/* DPCD_ADDR_TRAINING_PATTERN_SET */
+#define DPCD_SCRAMBLING_DISABLED		(0x1 << 5)
+#define DPCD_SCRAMBLING_ENABLED			(0x0 << 5)
+#define DPCD_TRAINING_PATTERN_2			(0x2 << 0)
+#define DPCD_TRAINING_PATTERN_1			(0x1 << 0)
+#define DPCD_TRAINING_PATTERN_DISABLED		(0x0 << 0)
+
+/* DPCD_ADDR_TRAINING_LANE0_SET */
+#define DPCD_MAX_PRE_EMPHASIS_REACHED		(0x1 << 5)
+#define DPCD_PRE_EMPHASIS_SET(x)		(((x) & 0x3) << 3)
+#define DPCD_PRE_EMPHASIS_GET(x)		(((x) >> 3) & 0x3)
+#define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0	(0x0 << 3)
+#define DPCD_MAX_SWING_REACHED			(0x1 << 2)
+#define DPCD_VOLTAGE_SWING_SET(x)		(((x) & 0x3) << 0)
+#define DPCD_VOLTAGE_SWING_GET(x)		(((x) >> 0) & 0x3)
+#define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0	(0x0 << 0)
+
+/* DPCD_ADDR_LANE0_1_STATUS */
+#define DPCD_LANE_SYMBOL_LOCKED			(0x1 << 2)
+#define DPCD_LANE_CHANNEL_EQ_DONE		(0x1 << 1)
+#define DPCD_LANE_CR_DONE			(0x1 << 0)
+#define DPCD_CHANNEL_EQ_BITS			(DPCD_LANE_CR_DONE|	\
+						 DPCD_LANE_CHANNEL_EQ_DONE|\
+						 DPCD_LANE_SYMBOL_LOCKED)
+
+/* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */
+#define DPCD_LINK_STATUS_UPDATED		(0x1 << 7)
+#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED	(0x1 << 6)
+#define DPCD_INTERLANE_ALIGN_DONE		(0x1 << 0)
+
+/* DPCD_ADDR_TEST_REQUEST */
+#define DPCD_TEST_EDID_READ			(0x1 << 2)
+
+/* DPCD_ADDR_TEST_RESPONSE */
+#define DPCD_TEST_EDID_CHECKSUM_WRITE		(0x1 << 2)
+
+/* DPCD_ADDR_SINK_POWER_STATE */
+#define DPCD_SET_POWER_STATE_D0			(0x1 << 0)
+#define DPCD_SET_POWER_STATE_D4			(0x2 << 0)
+
+#endif /* _EXYNOS_DP_CORE_H */
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
new file mode 100644
index 0000000..6548afa
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -0,0 +1,1173 @@
+/*
+ * Samsung DP (Display port) register interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.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.
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <video/exynos_dp.h>
+
+#include <plat/cpu.h>
+
+#include "exynos_dp_core.h"
+#include "exynos_dp_reg.h"
+
+#define COMMON_INT_MASK_1 (0)
+#define COMMON_INT_MASK_2 (0)
+#define COMMON_INT_MASK_3 (0)
+#define COMMON_INT_MASK_4 (0)
+#define INT_STA_MASK (0)
+
+void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable) {
+		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+		reg |= HDCP_VIDEO_MUTE;
+		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+		reg &= ~HDCP_VIDEO_MUTE;
+		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+	}
+}
+
+void exynos_dp_stop_video(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+	reg &= ~VIDEO_EN;
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+}
+
+void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable)
+		reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
+			LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
+	else
+		reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
+			LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
+
+	writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
+}
+
+void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
+{
+	/* Set interrupt pin assertion polarity as high */
+	writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
+
+	/* Clear pending regisers */
+	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
+	writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2);
+	writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3);
+	writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
+	writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA);
+
+	/* 0:mask,1: unmask */
+	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
+	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
+	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
+	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
+	writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
+}
+
+void exynos_dp_reset(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET);
+
+	exynos_dp_stop_video(dp);
+	exynos_dp_enable_video_mute(dp, 0);
+
+	reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
+		AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
+		HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+
+	reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
+		SERDES_FIFO_FUNC_EN_N |
+		LS_CLK_DOMAIN_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+
+	udelay(20);
+
+	exynos_dp_lane_swap(dp, 0);
+
+	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+	writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+
+	writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL);
+	writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL);
+
+	writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L);
+	writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H);
+
+	writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL);
+
+	writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST);
+
+	writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD);
+	writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN);
+
+	writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH);
+	writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
+
+	writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+
+	exynos_dp_init_interrupt(dp);
+}
+
+void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	/* 0: mask, 1: unmask */
+	reg = COMMON_INT_MASK_1;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
+
+	reg = COMMON_INT_MASK_2;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
+
+	reg = COMMON_INT_MASK_3;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
+
+	reg = COMMON_INT_MASK_4;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
+
+	reg = INT_STA_MASK;
+	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
+}
+
+u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
+	if (reg & PLL_LOCK)
+		return PLL_LOCKED;
+	else
+		return PLL_UNLOCKED;
+}
+
+void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable) {
+		reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
+		reg |= DP_PLL_PD;
+		writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
+		reg &= ~DP_PLL_PD;
+		writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
+	}
+}
+
+void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
+				enum analog_power_block block,
+				bool enable)
+{
+	u32 reg;
+
+	switch (block) {
+	case AUX_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= AUX_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~AUX_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case CH0_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= CH0_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~CH0_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case CH1_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= CH1_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~CH1_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case CH2_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= CH2_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~CH2_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case CH3_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= CH3_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~CH3_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case ANALOG_TOTAL:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= DP_PHY_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~DP_PHY_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case POWER_ALL:
+		if (enable) {
+			reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
+				CH1_PD | CH0_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
+
+	reg = PLL_LOCK_CHG;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
+	reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
+	writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL);
+
+	/* Power up PLL */
+	if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED)
+		exynos_dp_set_pll_power_down(dp, 0);
+
+	/* Enable Serdes FIFO function and Link symbol clock domain module */
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+	reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
+		| AUX_FUNC_EN_N);
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+}
+
+void exynos_dp_init_hpd(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = HOTPLUG_CHG | HPD_LOST | PLUG;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
+
+	reg = INT_HPD;
+	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	reg &= ~(F_HPD | HPD_CTRL);
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+}
+
+void exynos_dp_reset_aux(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	/* Disable AUX channel module */
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+	reg |= AUX_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+}
+
+void exynos_dp_init_aux(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	/* Clear inerrupts related to AUX channel */
+	reg = RPLY_RECEIV | AUX_ERR;
+	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
+
+	exynos_dp_reset_aux(dp);
+
+	/* Disable AUX transaction H/W retry */
+	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
+		AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ;
+
+	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
+	reg = DEFER_CTRL_EN | DEFER_COUNT(1);
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL);
+
+	/* Enable AUX channel module */
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+	reg &= ~AUX_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+}
+
+int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	if (reg & HPD_STATUS)
+		return 0;
+
+	return -EINVAL;
+}
+
+void exynos_dp_enable_sw_function(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+	reg &= ~SW_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+}
+
+int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
+{
+	int reg;
+	int retval = 0;
+
+	/* Enable AUX CH operation */
+	reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
+	reg |= AUX_EN;
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
+
+	/* Is AUX CH command reply received? */
+	reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
+	while (!(reg & RPLY_RECEIV))
+		reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
+
+	/* Clear interrupt source for AUX CH command reply */
+	writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
+
+	/* Clear interrupt source for AUX CH access error */
+	reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
+	if (reg & AUX_ERR) {
+		writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA);
+		return -EREMOTEIO;
+	}
+
+	/* Check AUX CH error access status */
+	reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA);
+	if ((reg & AUX_STATUS_MASK) != 0) {
+		dev_err(dp->dev, "AUX CH error happens: %d\n\n",
+			reg & AUX_STATUS_MASK);
+		return -EREMOTEIO;
+	}
+
+	return retval;
+}
+
+int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned char data)
+{
+	u32 reg;
+	int i;
+	int retval;
+
+	for (i = 0; i < 3; i++) {
+		/* Clear AUX CH data buffer */
+		reg = BUF_CLR;
+		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+		/* Select DPCD device address */
+		reg = AUX_ADDR_7_0(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+		reg = AUX_ADDR_15_8(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+		reg = AUX_ADDR_19_16(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+		/* Write data buffer */
+		reg = (unsigned int)data;
+		writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
+
+		/*
+		 * Set DisplayPort transaction and write 1 byte
+		 * If bit 3 is 1, DisplayPort transaction.
+		 * If Bit 3 is 0, I2C transaction.
+		 */
+		reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+		/* Start AUX transaction */
+		retval = exynos_dp_start_aux_transaction(dp);
+		if (retval == 0)
+			break;
+		else
+			dev_err(dp->dev, "Aux Transaction fail!\n");
+	}
+
+	return retval;
+}
+
+int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned char *data)
+{
+	u32 reg;
+	int i;
+	int retval;
+
+	for (i = 0; i < 10; i++) {
+		/* Clear AUX CH data buffer */
+		reg = BUF_CLR;
+		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+		/* Select DPCD device address */
+		reg = AUX_ADDR_7_0(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+		reg = AUX_ADDR_15_8(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+		reg = AUX_ADDR_19_16(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+		/*
+		 * Set DisplayPort transaction and read 1 byte
+		 * If bit 3 is 1, DisplayPort transaction.
+		 * If Bit 3 is 0, I2C transaction.
+		 */
+		reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+		/* Start AUX transaction */
+		retval = exynos_dp_start_aux_transaction(dp);
+		if (retval == 0)
+			break;
+		else
+			dev_err(dp->dev, "Aux Transaction fail!\n");
+	}
+
+	/* Read data buffer */
+	reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
+	*data = (unsigned char)(reg & 0xff);
+
+	return retval;
+}
+
+int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char data[])
+{
+	u32 reg;
+	unsigned int start_offset;
+	unsigned int cur_data_count;
+	unsigned int cur_data_idx;
+	int i;
+	int retval = 0;
+
+	/* Clear AUX CH data buffer */
+	reg = BUF_CLR;
+	writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+	start_offset = 0;
+	while (start_offset < count) {
+		/* Buffer size of AUX CH is 16 * 4bytes */
+		if ((count - start_offset) > 16)
+			cur_data_count = 16;
+		else
+			cur_data_count = count - start_offset;
+
+		for (i = 0; i < 10; i++) {
+			/* Select DPCD device address */
+			reg = AUX_ADDR_7_0(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+			reg = AUX_ADDR_15_8(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+			reg = AUX_ADDR_19_16(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+			for (cur_data_idx = 0; cur_data_idx < cur_data_count;
+			     cur_data_idx++) {
+				reg = data[start_offset + cur_data_idx];
+				writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0
+							  + 4 * cur_data_idx);
+			}
+
+			/*
+			 * Set DisplayPort transaction and write
+			 * If bit 3 is 1, DisplayPort transaction.
+			 * If Bit 3 is 0, I2C transaction.
+			 */
+			reg = AUX_LENGTH(cur_data_count) |
+				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+			/* Start AUX transaction */
+			retval = exynos_dp_start_aux_transaction(dp);
+			if (retval == 0)
+				break;
+			else
+				dev_err(dp->dev, "Aux Transaction fail!\n");
+		}
+
+		start_offset += cur_data_count;
+	}
+
+	return retval;
+}
+
+int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char data[])
+{
+	u32 reg;
+	unsigned int start_offset;
+	unsigned int cur_data_count;
+	unsigned int cur_data_idx;
+	int i;
+	int retval = 0;
+
+	/* Clear AUX CH data buffer */
+	reg = BUF_CLR;
+	writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+	start_offset = 0;
+	while (start_offset < count) {
+		/* Buffer size of AUX CH is 16 * 4bytes */
+		if ((count - start_offset) > 16)
+			cur_data_count = 16;
+		else
+			cur_data_count = count - start_offset;
+
+		/* AUX CH Request Transaction process */
+		for (i = 0; i < 10; i++) {
+			/* Select DPCD device address */
+			reg = AUX_ADDR_7_0(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+			reg = AUX_ADDR_15_8(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+			reg = AUX_ADDR_19_16(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+			/*
+			 * Set DisplayPort transaction and read
+			 * If bit 3 is 1, DisplayPort transaction.
+			 * If Bit 3 is 0, I2C transaction.
+			 */
+			reg = AUX_LENGTH(cur_data_count) |
+				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+			/* Start AUX transaction */
+			retval = exynos_dp_start_aux_transaction(dp);
+			if (retval == 0)
+				break;
+			else
+				dev_err(dp->dev, "Aux Transaction fail!\n");
+		}
+
+		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
+		    cur_data_idx++) {
+			reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
+						 + 4 * cur_data_idx);
+			data[start_offset + cur_data_idx] =
+				(unsigned char)reg;
+		}
+
+		start_offset += cur_data_count;
+	}
+
+	return retval;
+}
+
+int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr)
+{
+	u32 reg;
+	int retval;
+
+	/* Set EDID device address */
+	reg = device_addr;
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+	writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+	writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+	/* Set offset from base address of EDID device */
+	writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
+
+	/*
+	 * Set I2C transaction and write address
+	 * If bit 3 is 1, DisplayPort transaction.
+	 * If Bit 3 is 0, I2C transaction.
+	 */
+	reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
+		AUX_TX_COMM_WRITE;
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+	/* Start AUX transaction */
+	retval = exynos_dp_start_aux_transaction(dp);
+	if (retval != 0)
+		dev_err(dp->dev, "Aux Transaction fail!\n");
+
+	return retval;
+}
+
+int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr,
+				unsigned int *data)
+{
+	u32 reg;
+	int i;
+	int retval;
+
+	for (i = 0; i < 10; i++) {
+		/* Clear AUX CH data buffer */
+		reg = BUF_CLR;
+		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+		/* Select EDID device */
+		retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
+		if (retval != 0) {
+			dev_err(dp->dev, "Select EDID device fail!\n");
+			continue;
+		}
+
+		/*
+		 * Set I2C transaction and read data
+		 * If bit 3 is 1, DisplayPort transaction.
+		 * If Bit 3 is 0, I2C transaction.
+		 */
+		reg = AUX_TX_COMM_I2C_TRANSACTION |
+			AUX_TX_COMM_READ;
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+		/* Start AUX transaction */
+		retval = exynos_dp_start_aux_transaction(dp);
+		if (retval == 0)
+			break;
+		else
+			dev_err(dp->dev, "Aux Transaction fail!\n");
+	}
+
+	/* Read data */
+	if (retval == 0)
+		*data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
+
+	return retval;
+}
+
+int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char edid[])
+{
+	u32 reg;
+	unsigned int i, j;
+	unsigned int cur_data_idx;
+	unsigned int defer = 0;
+	int retval = 0;
+
+	for (i = 0; i < count; i += 16) {
+		for (j = 0; j < 100; j++) {
+			/* Clear AUX CH data buffer */
+			reg = BUF_CLR;
+			writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+			/* Set normal AUX CH command */
+			reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
+			reg &= ~ADDR_ONLY;
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
+
+			/*
+			 * If Rx sends defer, Tx sends only reads
+			 * request without sending addres
+			 */
+			if (!defer)
+				retval = exynos_dp_select_i2c_device(dp,
+						device_addr, reg_addr + i);
+			else
+				defer = 0;
+
+			if (retval == 0) {
+				/*
+				 * Set I2C transaction and write data
+				 * If bit 3 is 1, DisplayPort transaction.
+				 * If Bit 3 is 0, I2C transaction.
+				 */
+				reg = AUX_LENGTH(16) |
+					AUX_TX_COMM_I2C_TRANSACTION |
+					AUX_TX_COMM_READ;
+				writel(reg, dp->reg_base +
+					EXYNOS_DP_AUX_CH_CTL_1);
+
+				/* Start AUX transaction */
+				retval = exynos_dp_start_aux_transaction(dp);
+				if (retval == 0)
+					break;
+				else
+					dev_err(dp->dev, "Aux Transaction fail!\n");
+			}
+			/* Check if Rx sends defer */
+			reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
+			if (reg == AUX_RX_COMM_AUX_DEFER ||
+				reg == AUX_RX_COMM_I2C_DEFER) {
+				dev_err(dp->dev, "Defer: %d\n\n", reg);
+				defer = 1;
+			}
+		}
+
+		for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
+			reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
+						 + 4 * cur_data_idx);
+			edid[i + cur_data_idx] = (unsigned char)reg;
+		}
+	}
+
+	return retval;
+}
+
+void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype)
+{
+	u32 reg;
+
+	reg = bwtype;
+	if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS))
+		writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET);
+}
+
+void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET);
+	*bwtype = reg;
+}
+
+void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count)
+{
+	u32 reg;
+
+	reg = count;
+	writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
+}
+
+void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
+	*count = reg;
+}
+
+void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable) {
+		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg |= ENHANCED;
+		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg &= ~ENHANCED;
+		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+	}
+}
+
+void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
+				 enum pattern_set pattern)
+{
+	u32 reg;
+
+	switch (pattern) {
+	case PRBS7:
+		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	case D10_2:
+		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	case TRAINING_PTN1:
+		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	case TRAINING_PTN2:
+		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	case DP_NONE:
+		reg = SCRAMBLING_ENABLE |
+			LINK_QUAL_PATTERN_SET_DISABLE |
+			SW_TRAINING_PATTERN_SET_NORMAL;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	default:
+		break;
+	}
+}
+
+void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
+{
+	u32 reg;
+
+	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
+{
+	u32 reg;
+
+	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
+{
+	u32 reg;
+
+	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
+{
+	u32 reg;
+
+	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
+					u32 training_lane)
+{
+	u32 reg;
+
+	reg = training_lane;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
+					u32 training_lane)
+{
+	u32 reg;
+
+	reg = training_lane;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
+					u32 training_lane)
+{
+	u32 reg;
+
+	reg = training_lane;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
+					u32 training_lane)
+{
+	u32 reg;
+
+	reg = training_lane;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
+}
+
+u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
+	return reg;
+}
+
+u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
+	return reg;
+}
+
+u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
+	return reg;
+}
+
+u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
+	return reg;
+}
+
+void exynos_dp_reset_macro(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST);
+	reg |= MACRO_RST;
+	writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
+
+	/* 10 us is the minimum reset time. */
+	udelay(10);
+
+	reg &= ~MACRO_RST;
+	writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
+}
+
+int exynos_dp_init_video(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
+
+	reg = 0x0;
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+
+	reg = CHA_CRI(4) | CHA_CTRL;
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+
+	reg = 0x0;
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+
+	reg = VID_HRES_TH(2) | VID_VRES_TH(0);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
+
+	return 0;
+}
+
+void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
+			u32 color_depth,
+			u32 color_space,
+			u32 dynamic_range,
+			u32 ycbcr_coeff)
+{
+	u32 reg;
+
+	/* Configure the input color depth, color space, dynamic range */
+	reg = (dynamic_range << IN_D_RANGE_SHIFT) |
+		(color_depth << IN_BPC_SHIFT) |
+		(color_space << IN_COLOR_F_SHIFT);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
+
+	/* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
+	reg &= ~IN_YC_COEFFI_MASK;
+	if (ycbcr_coeff)
+		reg |= IN_YC_COEFFI_ITU709;
+	else
+		reg |= IN_YC_COEFFI_ITU601;
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
+}
+
+int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+
+	if (!(reg & DET_STA)) {
+		dev_dbg(dp->dev, "Input stream clock not detected.\n");
+		return -EINVAL;
+	}
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+	dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
+
+	if (reg & CHA_STA) {
+		dev_dbg(dp->dev, "Input stream clk is changing\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
+		enum clock_recovery_m_value_type type,
+		u32 m_value,
+		u32 n_value)
+{
+	u32 reg;
+
+	if (type == REGISTER_M) {
+		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg |= FIX_M_VID;
+		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg = m_value & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0);
+		reg = (m_value >> 8) & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1);
+		reg = (m_value >> 16) & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2);
+
+		reg = n_value & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0);
+		reg = (n_value >> 8) & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1);
+		reg = (n_value >> 16) & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2);
+	} else  {
+		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg &= ~FIX_M_VID;
+		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+
+		writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0);
+		writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1);
+		writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2);
+	}
+}
+
+void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type)
+{
+	u32 reg;
+
+	if (type == VIDEO_TIMING_FROM_CAPTURE) {
+		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+		reg &= ~FORMAT_SEL;
+		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+		reg |= FORMAT_SEL;
+		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	}
+}
+
+void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable) {
+		reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+		reg &= ~VIDEO_MODE_MASK;
+		reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
+		writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+		reg &= ~VIDEO_MODE_MASK;
+		reg |= VIDEO_MODE_SLAVE_MODE;
+		writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+	}
+}
+
+void exynos_dp_start_video(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+	reg |= VIDEO_EN;
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+}
+
+int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	if (!(reg & STRM_VALID)) {
+		dev_dbg(dp->dev, "Input video stream is not detected.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
+			struct video_info *video_info)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+	reg |= MASTER_VID_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	reg &= ~INTERACE_SCAN_CFG;
+	reg |= (video_info->interlaced << 2);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	reg &= ~VSYNC_POLARITY_CFG;
+	reg |= (video_info->v_sync_polarity << 1);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	reg &= ~HSYNC_POLARITY_CFG;
+	reg |= (video_info->h_sync_polarity << 0);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+
+	reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
+	writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+}
+
+void exynos_dp_enable_scrambling(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+	reg &= ~SCRAMBLING_DISABLE;
+	writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+}
+
+void exynos_dp_disable_scrambling(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+	reg |= SCRAMBLING_DISABLE;
+	writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+}
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
new file mode 100644
index 0000000..42f608e
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -0,0 +1,335 @@
+/*
+ * Register definition file for Samsung DP driver
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * 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 _EXYNOS_DP_REG_H
+#define _EXYNOS_DP_REG_H
+
+#define EXYNOS_DP_TX_SW_RESET			0x14
+#define EXYNOS_DP_FUNC_EN_1			0x18
+#define EXYNOS_DP_FUNC_EN_2			0x1C
+#define EXYNOS_DP_VIDEO_CTL_1			0x20
+#define EXYNOS_DP_VIDEO_CTL_2			0x24
+#define EXYNOS_DP_VIDEO_CTL_3			0x28
+
+#define EXYNOS_DP_VIDEO_CTL_8			0x3C
+#define EXYNOS_DP_VIDEO_CTL_10			0x44
+
+#define EXYNOS_DP_LANE_MAP			0x35C
+
+#define EXYNOS_DP_AUX_HW_RETRY_CTL		0x390
+
+#define EXYNOS_DP_COMMON_INT_STA_1		0x3C4
+#define EXYNOS_DP_COMMON_INT_STA_2		0x3C8
+#define EXYNOS_DP_COMMON_INT_STA_3		0x3CC
+#define EXYNOS_DP_COMMON_INT_STA_4		0x3D0
+#define EXYNOS_DP_INT_STA			0x3DC
+#define EXYNOS_DP_COMMON_INT_MASK_1		0x3E0
+#define EXYNOS_DP_COMMON_INT_MASK_2		0x3E4
+#define EXYNOS_DP_COMMON_INT_MASK_3		0x3E8
+#define EXYNOS_DP_COMMON_INT_MASK_4		0x3EC
+#define EXYNOS_DP_INT_STA_MASK			0x3F8
+#define EXYNOS_DP_INT_CTL			0x3FC
+
+#define EXYNOS_DP_SYS_CTL_1			0x600
+#define EXYNOS_DP_SYS_CTL_2			0x604
+#define EXYNOS_DP_SYS_CTL_3			0x608
+#define EXYNOS_DP_SYS_CTL_4			0x60C
+
+#define EXYNOS_DP_PKT_SEND_CTL			0x640
+#define EXYNOS_DP_HDCP_CTL			0x648
+
+#define EXYNOS_DP_LINK_BW_SET			0x680
+#define EXYNOS_DP_LANE_COUNT_SET		0x684
+#define EXYNOS_DP_TRAINING_PTN_SET		0x688
+#define EXYNOS_DP_LN0_LINK_TRAINING_CTL		0x68C
+#define EXYNOS_DP_LN1_LINK_TRAINING_CTL		0x690
+#define EXYNOS_DP_LN2_LINK_TRAINING_CTL		0x694
+#define EXYNOS_DP_LN3_LINK_TRAINING_CTL		0x698
+
+#define EXYNOS_DP_DEBUG_CTL			0x6C0
+#define EXYNOS_DP_HPD_DEGLITCH_L		0x6C4
+#define EXYNOS_DP_HPD_DEGLITCH_H		0x6C8
+#define EXYNOS_DP_LINK_DEBUG_CTL		0x6E0
+
+#define EXYNOS_DP_M_VID_0			0x700
+#define EXYNOS_DP_M_VID_1			0x704
+#define EXYNOS_DP_M_VID_2			0x708
+#define EXYNOS_DP_N_VID_0			0x70C
+#define EXYNOS_DP_N_VID_1			0x710
+#define EXYNOS_DP_N_VID_2			0x714
+
+#define EXYNOS_DP_PLL_CTL			0x71C
+#define EXYNOS_DP_PHY_PD			0x720
+#define EXYNOS_DP_PHY_TEST			0x724
+
+#define EXYNOS_DP_VIDEO_FIFO_THRD		0x730
+#define EXYNOS_DP_AUDIO_MARGIN			0x73C
+
+#define EXYNOS_DP_M_VID_GEN_FILTER_TH		0x764
+#define EXYNOS_DP_M_AUD_GEN_FILTER_TH		0x778
+#define EXYNOS_DP_AUX_CH_STA			0x780
+#define EXYNOS_DP_AUX_CH_DEFER_CTL		0x788
+#define EXYNOS_DP_AUX_RX_COMM			0x78C
+#define EXYNOS_DP_BUFFER_DATA_CTL		0x790
+#define EXYNOS_DP_AUX_CH_CTL_1			0x794
+#define EXYNOS_DP_AUX_ADDR_7_0			0x798
+#define EXYNOS_DP_AUX_ADDR_15_8			0x79C
+#define EXYNOS_DP_AUX_ADDR_19_16		0x7A0
+#define EXYNOS_DP_AUX_CH_CTL_2			0x7A4
+
+#define EXYNOS_DP_BUF_DATA_0			0x7C0
+
+#define EXYNOS_DP_SOC_GENERAL_CTL		0x800
+
+/* EXYNOS_DP_TX_SW_RESET */
+#define RESET_DP_TX				(0x1 << 0)
+
+/* EXYNOS_DP_FUNC_EN_1 */
+#define MASTER_VID_FUNC_EN_N			(0x1 << 7)
+#define SLAVE_VID_FUNC_EN_N			(0x1 << 5)
+#define AUD_FIFO_FUNC_EN_N			(0x1 << 4)
+#define AUD_FUNC_EN_N				(0x1 << 3)
+#define HDCP_FUNC_EN_N				(0x1 << 2)
+#define CRC_FUNC_EN_N				(0x1 << 1)
+#define SW_FUNC_EN_N				(0x1 << 0)
+
+/* EXYNOS_DP_FUNC_EN_2 */
+#define SSC_FUNC_EN_N				(0x1 << 7)
+#define AUX_FUNC_EN_N				(0x1 << 2)
+#define SERDES_FIFO_FUNC_EN_N			(0x1 << 1)
+#define LS_CLK_DOMAIN_FUNC_EN_N			(0x1 << 0)
+
+/* EXYNOS_DP_VIDEO_CTL_1 */
+#define VIDEO_EN				(0x1 << 7)
+#define HDCP_VIDEO_MUTE				(0x1 << 6)
+
+/* EXYNOS_DP_VIDEO_CTL_1 */
+#define IN_D_RANGE_MASK				(0x1 << 7)
+#define IN_D_RANGE_SHIFT			(7)
+#define IN_D_RANGE_CEA				(0x1 << 7)
+#define IN_D_RANGE_VESA				(0x0 << 7)
+#define IN_BPC_MASK				(0x7 << 4)
+#define IN_BPC_SHIFT				(4)
+#define IN_BPC_12_BITS				(0x3 << 4)
+#define IN_BPC_10_BITS				(0x2 << 4)
+#define IN_BPC_8_BITS				(0x1 << 4)
+#define IN_BPC_6_BITS				(0x0 << 4)
+#define IN_COLOR_F_MASK				(0x3 << 0)
+#define IN_COLOR_F_SHIFT			(0)
+#define IN_COLOR_F_YCBCR444			(0x2 << 0)
+#define IN_COLOR_F_YCBCR422			(0x1 << 0)
+#define IN_COLOR_F_RGB				(0x0 << 0)
+
+/* EXYNOS_DP_VIDEO_CTL_3 */
+#define IN_YC_COEFFI_MASK			(0x1 << 7)
+#define IN_YC_COEFFI_SHIFT			(7)
+#define IN_YC_COEFFI_ITU709			(0x1 << 7)
+#define IN_YC_COEFFI_ITU601			(0x0 << 7)
+#define VID_CHK_UPDATE_TYPE_MASK		(0x1 << 4)
+#define VID_CHK_UPDATE_TYPE_SHIFT		(4)
+#define VID_CHK_UPDATE_TYPE_1			(0x1 << 4)
+#define VID_CHK_UPDATE_TYPE_0			(0x0 << 4)
+
+/* EXYNOS_DP_VIDEO_CTL_8 */
+#define VID_HRES_TH(x)				(((x) & 0xf) << 4)
+#define VID_VRES_TH(x)				(((x) & 0xf) << 0)
+
+/* EXYNOS_DP_VIDEO_CTL_10 */
+#define FORMAT_SEL				(0x1 << 4)
+#define INTERACE_SCAN_CFG			(0x1 << 2)
+#define VSYNC_POLARITY_CFG			(0x1 << 1)
+#define HSYNC_POLARITY_CFG			(0x1 << 0)
+
+/* EXYNOS_DP_LANE_MAP */
+#define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6)
+#define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6)
+#define LANE3_MAP_LOGIC_LANE_2			(0x2 << 6)
+#define LANE3_MAP_LOGIC_LANE_3			(0x3 << 6)
+#define LANE2_MAP_LOGIC_LANE_0			(0x0 << 4)
+#define LANE2_MAP_LOGIC_LANE_1			(0x1 << 4)
+#define LANE2_MAP_LOGIC_LANE_2			(0x2 << 4)
+#define LANE2_MAP_LOGIC_LANE_3			(0x3 << 4)
+#define LANE1_MAP_LOGIC_LANE_0			(0x0 << 2)
+#define LANE1_MAP_LOGIC_LANE_1			(0x1 << 2)
+#define LANE1_MAP_LOGIC_LANE_2			(0x2 << 2)
+#define LANE1_MAP_LOGIC_LANE_3			(0x3 << 2)
+#define LANE0_MAP_LOGIC_LANE_0			(0x0 << 0)
+#define LANE0_MAP_LOGIC_LANE_1			(0x1 << 0)
+#define LANE0_MAP_LOGIC_LANE_2			(0x2 << 0)
+#define LANE0_MAP_LOGIC_LANE_3			(0x3 << 0)
+
+/* EXYNOS_DP_AUX_HW_RETRY_CTL */
+#define AUX_BIT_PERIOD_EXPECTED_DELAY(x)	(((x) & 0x7) << 8)
+#define AUX_HW_RETRY_INTERVAL_MASK		(0x3 << 3)
+#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS	(0x0 << 3)
+#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS	(0x1 << 3)
+#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS	(0x2 << 3)
+#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS	(0x3 << 3)
+#define AUX_HW_RETRY_COUNT_SEL(x)		(((x) & 0x7) << 0)
+
+/* EXYNOS_DP_COMMON_INT_STA_1 */
+#define VSYNC_DET				(0x1 << 7)
+#define PLL_LOCK_CHG				(0x1 << 6)
+#define SPDIF_ERR				(0x1 << 5)
+#define SPDIF_UNSTBL				(0x1 << 4)
+#define VID_FORMAT_CHG				(0x1 << 3)
+#define AUD_CLK_CHG				(0x1 << 2)
+#define VID_CLK_CHG				(0x1 << 1)
+#define SW_INT					(0x1 << 0)
+
+/* EXYNOS_DP_COMMON_INT_STA_2 */
+#define ENC_EN_CHG				(0x1 << 6)
+#define HW_BKSV_RDY				(0x1 << 3)
+#define HW_SHA_DONE				(0x1 << 2)
+#define HW_AUTH_STATE_CHG			(0x1 << 1)
+#define HW_AUTH_DONE				(0x1 << 0)
+
+/* EXYNOS_DP_COMMON_INT_STA_3 */
+#define AFIFO_UNDER				(0x1 << 7)
+#define AFIFO_OVER				(0x1 << 6)
+#define R0_CHK_FLAG				(0x1 << 5)
+
+/* EXYNOS_DP_COMMON_INT_STA_4 */
+#define PSR_ACTIVE				(0x1 << 7)
+#define PSR_INACTIVE				(0x1 << 6)
+#define SPDIF_BI_PHASE_ERR			(0x1 << 5)
+#define HOTPLUG_CHG				(0x1 << 2)
+#define HPD_LOST				(0x1 << 1)
+#define PLUG					(0x1 << 0)
+
+/* EXYNOS_DP_INT_STA */
+#define INT_HPD					(0x1 << 6)
+#define HW_TRAINING_FINISH			(0x1 << 5)
+#define RPLY_RECEIV				(0x1 << 1)
+#define AUX_ERR					(0x1 << 0)
+
+/* EXYNOS_DP_INT_CTL */
+#define SOFT_INT_CTRL				(0x1 << 2)
+#define INT_POL					(0x1 << 0)
+
+/* EXYNOS_DP_SYS_CTL_1 */
+#define DET_STA					(0x1 << 2)
+#define FORCE_DET				(0x1 << 1)
+#define DET_CTRL				(0x1 << 0)
+
+/* EXYNOS_DP_SYS_CTL_2 */
+#define CHA_CRI(x)				(((x) & 0xf) << 4)
+#define CHA_STA					(0x1 << 2)
+#define FORCE_CHA				(0x1 << 1)
+#define CHA_CTRL				(0x1 << 0)
+
+/* EXYNOS_DP_SYS_CTL_3 */
+#define HPD_STATUS				(0x1 << 6)
+#define F_HPD					(0x1 << 5)
+#define HPD_CTRL				(0x1 << 4)
+#define HDCP_RDY				(0x1 << 3)
+#define STRM_VALID				(0x1 << 2)
+#define F_VALID					(0x1 << 1)
+#define VALID_CTRL				(0x1 << 0)
+
+/* EXYNOS_DP_SYS_CTL_4 */
+#define FIX_M_AUD				(0x1 << 4)
+#define ENHANCED				(0x1 << 3)
+#define FIX_M_VID				(0x1 << 2)
+#define M_VID_UPDATE_CTRL			(0x3 << 0)
+
+/* EXYNOS_DP_TRAINING_PTN_SET */
+#define SCRAMBLER_TYPE				(0x1 << 9)
+#define HW_LINK_TRAINING_PATTERN		(0x1 << 8)
+#define SCRAMBLING_DISABLE			(0x1 << 5)
+#define SCRAMBLING_ENABLE			(0x0 << 5)
+#define LINK_QUAL_PATTERN_SET_MASK		(0x3 << 2)
+#define LINK_QUAL_PATTERN_SET_PRBS7		(0x3 << 2)
+#define LINK_QUAL_PATTERN_SET_D10_2		(0x1 << 2)
+#define LINK_QUAL_PATTERN_SET_DISABLE		(0x0 << 2)
+#define SW_TRAINING_PATTERN_SET_MASK		(0x3 << 0)
+#define SW_TRAINING_PATTERN_SET_PTN2		(0x2 << 0)
+#define SW_TRAINING_PATTERN_SET_PTN1		(0x1 << 0)
+#define SW_TRAINING_PATTERN_SET_NORMAL		(0x0 << 0)
+
+/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
+#define PRE_EMPHASIS_SET_SHIFT			(3)
+
+/* EXYNOS_DP_DEBUG_CTL */
+#define PLL_LOCK				(0x1 << 4)
+#define F_PLL_LOCK				(0x1 << 3)
+#define PLL_LOCK_CTRL				(0x1 << 2)
+#define PN_INV					(0x1 << 0)
+
+/* EXYNOS_DP_PLL_CTL */
+#define DP_PLL_PD				(0x1 << 7)
+#define DP_PLL_RESET				(0x1 << 6)
+#define DP_PLL_LOOP_BIT_DEFAULT			(0x1 << 4)
+#define DP_PLL_REF_BIT_1_1250V			(0x5 << 0)
+#define DP_PLL_REF_BIT_1_2500V			(0x7 << 0)
+
+/* EXYNOS_DP_PHY_PD */
+#define DP_PHY_PD				(0x1 << 5)
+#define AUX_PD					(0x1 << 4)
+#define CH3_PD					(0x1 << 3)
+#define CH2_PD					(0x1 << 2)
+#define CH1_PD					(0x1 << 1)
+#define CH0_PD					(0x1 << 0)
+
+/* EXYNOS_DP_PHY_TEST */
+#define MACRO_RST				(0x1 << 5)
+#define CH1_TEST				(0x1 << 1)
+#define CH0_TEST				(0x1 << 0)
+
+/* EXYNOS_DP_AUX_CH_STA */
+#define AUX_BUSY				(0x1 << 4)
+#define AUX_STATUS_MASK				(0xf << 0)
+
+/* EXYNOS_DP_AUX_CH_DEFER_CTL */
+#define DEFER_CTRL_EN				(0x1 << 7)
+#define DEFER_COUNT(x)				(((x) & 0x7f) << 0)
+
+/* EXYNOS_DP_AUX_RX_COMM */
+#define AUX_RX_COMM_I2C_DEFER			(0x2 << 2)
+#define AUX_RX_COMM_AUX_DEFER			(0x2 << 0)
+
+/* EXYNOS_DP_BUFFER_DATA_CTL */
+#define BUF_CLR					(0x1 << 7)
+#define BUF_DATA_COUNT(x)			(((x) & 0x1f) << 0)
+
+/* EXYNOS_DP_AUX_CH_CTL_1 */
+#define AUX_LENGTH(x)				(((x - 1) & 0xf) << 4)
+#define AUX_TX_COMM_MASK			(0xf << 0)
+#define AUX_TX_COMM_DP_TRANSACTION		(0x1 << 3)
+#define AUX_TX_COMM_I2C_TRANSACTION		(0x0 << 3)
+#define AUX_TX_COMM_MOT				(0x1 << 2)
+#define AUX_TX_COMM_WRITE			(0x0 << 0)
+#define AUX_TX_COMM_READ			(0x1 << 0)
+
+/* EXYNOS_DP_AUX_ADDR_7_0 */
+#define AUX_ADDR_7_0(x)				(((x) >> 0) & 0xff)
+
+/* EXYNOS_DP_AUX_ADDR_15_8 */
+#define AUX_ADDR_15_8(x)			(((x) >> 8) & 0xff)
+
+/* EXYNOS_DP_AUX_ADDR_19_16 */
+#define AUX_ADDR_19_16(x)			(((x) >> 16) & 0x0f)
+
+/* EXYNOS_DP_AUX_CH_CTL_2 */
+#define ADDR_ONLY				(0x1 << 1)
+#define AUX_EN					(0x1 << 0)
+
+/* EXYNOS_DP_SOC_GENERAL_CTL */
+#define AUDIO_MODE_SPDIF_MODE			(0x1 << 8)
+#define AUDIO_MODE_MASTER_MODE			(0x0 << 8)
+#define MASTER_VIDEO_INTERLACE_EN		(0x1 << 4)
+#define VIDEO_MASTER_CLK_SEL			(0x1 << 2)
+#define VIDEO_MASTER_MODE_EN			(0x1 << 1)
+#define VIDEO_MODE_MASK				(0x1 << 0)
+#define VIDEO_MODE_SLAVE_MODE			(0x1 << 0)
+#define VIDEO_MODE_MASTER_MODE			(0x0 << 0)
+
+#endif /* _EXYNOS_DP_REG_H */
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
new file mode 100644
index 0000000..557091d
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -0,0 +1,600 @@
+/* linux/drivers/video/exynos/exynos_mipi_dsi.c
+ *
+ * Samsung SoC MIPI-DSIM driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ *
+ * 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.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/ctype.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/memory.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/notifier.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+
+#include <video/exynos_mipi_dsim.h>
+
+#include <plat/fb.h>
+
+#include "exynos_mipi_dsi_common.h"
+#include "exynos_mipi_dsi_lowlevel.h"
+
+struct mipi_dsim_ddi {
+	int				bus_id;
+	struct list_head		list;
+	struct mipi_dsim_lcd_device	*dsim_lcd_dev;
+	struct mipi_dsim_lcd_driver	*dsim_lcd_drv;
+};
+
+static LIST_HEAD(dsim_ddi_list);
+
+static DEFINE_MUTEX(mipi_dsim_lock);
+
+static struct mipi_dsim_platform_data *to_dsim_plat(struct platform_device
+							*pdev)
+{
+	return pdev->dev.platform_data;
+}
+
+static struct regulator_bulk_data supplies[] = {
+	{ .supply = "vdd10", },
+	{ .supply = "vdd18", },
+};
+
+static int exynos_mipi_regulator_enable(struct mipi_dsim_device *dsim)
+{
+	int ret;
+
+	mutex_lock(&dsim->lock);
+	ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
+	mutex_unlock(&dsim->lock);
+
+	return ret;
+}
+
+static int exynos_mipi_regulator_disable(struct mipi_dsim_device *dsim)
+{
+	int ret;
+
+	mutex_lock(&dsim->lock);
+	ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+	mutex_unlock(&dsim->lock);
+
+	return ret;
+}
+
+/* update all register settings to MIPI DSI controller. */
+static void exynos_mipi_update_cfg(struct mipi_dsim_device *dsim)
+{
+	/*
+	 * data from Display controller(FIMD) is not transferred in video mode
+	 * but in case of command mode, all settings is not updated to
+	 * registers.
+	 */
+	exynos_mipi_dsi_stand_by(dsim, 0);
+
+	exynos_mipi_dsi_init_dsim(dsim);
+	exynos_mipi_dsi_init_link(dsim);
+
+	exynos_mipi_dsi_set_hs_enable(dsim);
+
+	/* set display timing. */
+	exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config);
+
+	/*
+	 * data from Display controller(FIMD) is transferred in video mode
+	 * but in case of command mode, all settigs is updated to registers.
+	 */
+	exynos_mipi_dsi_stand_by(dsim, 1);
+}
+
+static int exynos_mipi_dsi_early_blank_mode(struct mipi_dsim_device *dsim,
+		int power)
+{
+	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
+	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
+
+	switch (power) {
+	case FB_BLANK_POWERDOWN:
+		if (dsim->suspended)
+			return 0;
+
+		if (client_drv && client_drv->suspend)
+			client_drv->suspend(client_dev);
+
+		clk_disable(dsim->clock);
+
+		exynos_mipi_regulator_disable(dsim);
+
+		dsim->suspended = true;
+
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
+{
+	struct platform_device *pdev = to_platform_device(dsim->dev);
+	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
+	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
+
+	switch (power) {
+	case FB_BLANK_UNBLANK:
+		if (!dsim->suspended)
+			return 0;
+
+		/* lcd panel power on. */
+		if (client_drv && client_drv->power_on)
+			client_drv->power_on(client_dev, 1);
+
+		exynos_mipi_regulator_disable(dsim);
+
+		/* enable MIPI-DSI PHY. */
+		if (dsim->pd->phy_enable)
+			dsim->pd->phy_enable(pdev, true);
+
+		clk_enable(dsim->clock);
+
+		exynos_mipi_update_cfg(dsim);
+
+		/* set lcd panel sequence commands. */
+		if (client_drv && client_drv->set_sequence)
+			client_drv->set_sequence(client_dev);
+
+		dsim->suspended = false;
+
+		break;
+	case FB_BLANK_NORMAL:
+		/* TODO. */
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
+{
+	struct mipi_dsim_ddi *dsim_ddi;
+
+	if (!lcd_dev->name) {
+		pr_err("dsim_lcd_device name is NULL.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
+	if (!dsim_ddi) {
+		pr_err("failed to allocate dsim_ddi object.\n");
+		return -ENOMEM;
+	}
+
+	dsim_ddi->dsim_lcd_dev = lcd_dev;
+
+	mutex_lock(&mipi_dsim_lock);
+	list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
+	mutex_unlock(&mipi_dsim_lock);
+
+	return 0;
+}
+
+struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
+{
+	struct mipi_dsim_ddi *dsim_ddi, *next;
+	struct mipi_dsim_lcd_device *lcd_dev;
+
+	mutex_lock(&mipi_dsim_lock);
+
+	list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
+		if (!dsim_ddi)
+			goto out;
+
+		lcd_dev = dsim_ddi->dsim_lcd_dev;
+		if (!lcd_dev)
+			continue;
+
+		if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) {
+			/**
+			 * bus_id would be used to identify
+			 * connected bus.
+			 */
+			dsim_ddi->bus_id = lcd_dev->bus_id;
+			mutex_unlock(&mipi_dsim_lock);
+
+			return dsim_ddi;
+		}
+
+		list_del(&dsim_ddi->list);
+		kfree(dsim_ddi);
+	}
+
+out:
+	mutex_unlock(&mipi_dsim_lock);
+
+	return NULL;
+}
+
+int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
+{
+	struct mipi_dsim_ddi *dsim_ddi;
+
+	if (!lcd_drv->name) {
+		pr_err("dsim_lcd_driver name is NULL.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi = exynos_mipi_dsi_find_lcd_device(lcd_drv);
+	if (!dsim_ddi) {
+		pr_err("mipi_dsim_ddi object not found.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi->dsim_lcd_drv = lcd_drv;
+
+	pr_info("registered panel driver(%s) to mipi-dsi driver.\n",
+		lcd_drv->name);
+
+	return 0;
+
+}
+
+struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
+						const char *name)
+{
+	struct mipi_dsim_ddi *dsim_ddi, *next;
+	struct mipi_dsim_lcd_driver *lcd_drv;
+	struct mipi_dsim_lcd_device *lcd_dev;
+	int ret;
+
+	mutex_lock(&dsim->lock);
+
+	list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
+		lcd_drv = dsim_ddi->dsim_lcd_drv;
+		lcd_dev = dsim_ddi->dsim_lcd_dev;
+		if (!lcd_drv || !lcd_dev ||
+			(dsim->id != dsim_ddi->bus_id))
+				continue;
+
+		dev_dbg(dsim->dev, "lcd_drv->id = %d, lcd_dev->id = %d\n",
+				lcd_drv->id, lcd_dev->id);
+		dev_dbg(dsim->dev, "lcd_dev->bus_id = %d, dsim->id = %d\n",
+				lcd_dev->bus_id, dsim->id);
+
+		if ((strcmp(lcd_drv->name, name) == 0)) {
+			lcd_dev->master = dsim;
+
+			lcd_dev->dev.parent = dsim->dev;
+			dev_set_name(&lcd_dev->dev, "%s", lcd_drv->name);
+
+			ret = device_register(&lcd_dev->dev);
+			if (ret < 0) {
+				dev_err(dsim->dev,
+					"can't register %s, status %d\n",
+					dev_name(&lcd_dev->dev), ret);
+				mutex_unlock(&dsim->lock);
+
+				return NULL;
+			}
+
+			dsim->dsim_lcd_dev = lcd_dev;
+			dsim->dsim_lcd_drv = lcd_drv;
+
+			mutex_unlock(&dsim->lock);
+
+			return dsim_ddi;
+		}
+	}
+
+	mutex_unlock(&dsim->lock);
+
+	return NULL;
+}
+
+/* define MIPI-DSI Master operations. */
+static struct mipi_dsim_master_ops master_ops = {
+	.cmd_read			= exynos_mipi_dsi_rd_data,
+	.cmd_write			= exynos_mipi_dsi_wr_data,
+	.get_dsim_frame_done		= exynos_mipi_dsi_get_frame_done_status,
+	.clear_dsim_frame_done		= exynos_mipi_dsi_clear_frame_done,
+	.set_early_blank_mode		= exynos_mipi_dsi_early_blank_mode,
+	.set_blank_mode			= exynos_mipi_dsi_blank_mode,
+};
+
+static int exynos_mipi_dsi_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct mipi_dsim_device *dsim;
+	struct mipi_dsim_config *dsim_config;
+	struct mipi_dsim_platform_data *dsim_pd;
+	struct mipi_dsim_ddi *dsim_ddi;
+	int ret = -EINVAL;
+
+	dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
+	if (!dsim) {
+		dev_err(&pdev->dev, "failed to allocate dsim object.\n");
+		return -ENOMEM;
+	}
+
+	dsim->pd = to_dsim_plat(pdev);
+	dsim->dev = &pdev->dev;
+	dsim->id = pdev->id;
+
+	/* get mipi_dsim_platform_data. */
+	dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
+	if (dsim_pd == NULL) {
+		dev_err(&pdev->dev, "failed to get platform data for dsim.\n");
+		goto err_clock_get;
+	}
+	/* get mipi_dsim_config. */
+	dsim_config = dsim_pd->dsim_config;
+	if (dsim_config == NULL) {
+		dev_err(&pdev->dev, "failed to get dsim config data.\n");
+		goto err_clock_get;
+	}
+
+	dsim->dsim_config = dsim_config;
+	dsim->master_ops = &master_ops;
+
+	mutex_init(&dsim->lock);
+
+	ret = regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies), supplies);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
+		goto err_clock_get;
+	}
+
+	dsim->clock = clk_get(&pdev->dev, "dsim0");
+	if (IS_ERR(dsim->clock)) {
+		dev_err(&pdev->dev, "failed to get dsim clock source\n");
+		goto err_clock_get;
+	}
+
+	clk_enable(dsim->clock);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get io memory region\n");
+		goto err_platform_get;
+	}
+
+	dsim->res = request_mem_region(res->start, resource_size(res),
+					dev_name(&pdev->dev));
+	if (!dsim->res) {
+		dev_err(&pdev->dev, "failed to request io memory region\n");
+		ret = -ENOMEM;
+		goto err_mem_region;
+	}
+
+	dsim->reg_base = ioremap(res->start, resource_size(res));
+	if (!dsim->reg_base) {
+		dev_err(&pdev->dev, "failed to remap io region\n");
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	mutex_init(&dsim->lock);
+
+	/* bind lcd ddi matched with panel name. */
+	dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
+	if (!dsim_ddi) {
+		dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
+		goto err_bind;
+	}
+
+	dsim->irq = platform_get_irq(pdev, 0);
+	if (dsim->irq < 0) {
+		dev_err(&pdev->dev, "failed to request dsim irq resource\n");
+		ret = -EINVAL;
+		goto err_platform_get_irq;
+	}
+
+	ret = request_irq(dsim->irq, exynos_mipi_dsi_interrupt_handler,
+			IRQF_SHARED, pdev->name, dsim);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "failed to request dsim irq\n");
+		ret = -EINVAL;
+		goto err_bind;
+	}
+
+	init_completion(&dsim_wr_comp);
+	init_completion(&dsim_rd_comp);
+
+	/* enable interrupt */
+	exynos_mipi_dsi_init_interrupt(dsim);
+
+	/* initialize mipi-dsi client(lcd panel). */
+	if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->probe)
+		dsim_ddi->dsim_lcd_drv->probe(dsim_ddi->dsim_lcd_dev);
+
+	/* in case that mipi got enabled at bootloader. */
+	if (dsim_pd->enabled)
+		goto out;
+
+	/* lcd panel power on. */
+	if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->power_on)
+		dsim_ddi->dsim_lcd_drv->power_on(dsim_ddi->dsim_lcd_dev, 1);
+
+	exynos_mipi_regulator_enable(dsim);
+
+	/* enable MIPI-DSI PHY. */
+	if (dsim->pd->phy_enable)
+		dsim->pd->phy_enable(pdev, true);
+
+	exynos_mipi_update_cfg(dsim);
+
+	/* set lcd panel sequence commands. */
+	if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->set_sequence)
+		dsim_ddi->dsim_lcd_drv->set_sequence(dsim_ddi->dsim_lcd_dev);
+
+	dsim->suspended = false;
+
+out:
+	platform_set_drvdata(pdev, dsim);
+
+	dev_dbg(&pdev->dev, "mipi-dsi driver(%s mode) has been probed.\n",
+		(dsim_config->e_interface == DSIM_COMMAND) ?
+			"CPU" : "RGB");
+
+	return 0;
+
+err_bind:
+	iounmap(dsim->reg_base);
+
+err_ioremap:
+	release_mem_region(dsim->res->start, resource_size(dsim->res));
+
+err_mem_region:
+	release_resource(dsim->res);
+
+err_platform_get:
+	clk_disable(dsim->clock);
+	clk_put(dsim->clock);
+err_clock_get:
+	kfree(dsim);
+
+err_platform_get_irq:
+	return ret;
+}
+
+static int __devexit exynos_mipi_dsi_remove(struct platform_device *pdev)
+{
+	struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
+	struct mipi_dsim_ddi *dsim_ddi, *next;
+	struct mipi_dsim_lcd_driver *dsim_lcd_drv;
+
+	iounmap(dsim->reg_base);
+
+	clk_disable(dsim->clock);
+	clk_put(dsim->clock);
+
+	release_resource(dsim->res);
+	release_mem_region(dsim->res->start, resource_size(dsim->res));
+
+	list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
+		if (dsim_ddi) {
+			if (dsim->id != dsim_ddi->bus_id)
+				continue;
+
+			dsim_lcd_drv = dsim_ddi->dsim_lcd_drv;
+
+			if (dsim_lcd_drv->remove)
+				dsim_lcd_drv->remove(dsim_ddi->dsim_lcd_dev);
+
+			kfree(dsim_ddi);
+		}
+	}
+
+	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+	kfree(dsim);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int exynos_mipi_dsi_suspend(struct platform_device *pdev,
+		pm_message_t state)
+{
+	struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
+	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
+	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
+
+	disable_irq(dsim->irq);
+
+	if (dsim->suspended)
+		return 0;
+
+	if (client_drv && client_drv->suspend)
+		client_drv->suspend(client_dev);
+
+	/* enable MIPI-DSI PHY. */
+	if (dsim->pd->phy_enable)
+		dsim->pd->phy_enable(pdev, false);
+
+	clk_disable(dsim->clock);
+
+	exynos_mipi_regulator_disable(dsim);
+
+	dsim->suspended = true;
+
+	return 0;
+}
+
+static int exynos_mipi_dsi_resume(struct platform_device *pdev)
+{
+	struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
+	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
+	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
+
+	enable_irq(dsim->irq);
+
+	if (!dsim->suspended)
+		return 0;
+
+	/* lcd panel power on. */
+	if (client_drv && client_drv->power_on)
+		client_drv->power_on(client_dev, 1);
+
+	exynos_mipi_regulator_enable(dsim);
+
+	/* enable MIPI-DSI PHY. */
+	if (dsim->pd->phy_enable)
+		dsim->pd->phy_enable(pdev, true);
+
+	clk_enable(dsim->clock);
+
+	exynos_mipi_update_cfg(dsim);
+
+	/* set lcd panel sequence commands. */
+	if (client_drv && client_drv->set_sequence)
+		client_drv->set_sequence(client_dev);
+
+	dsim->suspended = false;
+
+	return 0;
+}
+#else
+#define exynos_mipi_dsi_suspend NULL
+#define exynos_mipi_dsi_resume NULL
+#endif
+
+static struct platform_driver exynos_mipi_dsi_driver = {
+	.probe = exynos_mipi_dsi_probe,
+	.remove = __devexit_p(exynos_mipi_dsi_remove),
+	.suspend = exynos_mipi_dsi_suspend,
+	.resume = exynos_mipi_dsi_resume,
+	.driver = {
+		   .name = "exynos-mipi-dsim",
+		   .owner = THIS_MODULE,
+	},
+};
+
+module_platform_driver(exynos_mipi_dsi_driver);
+
+MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("Samusung SoC MIPI-DSI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
new file mode 100644
index 0000000..14909c1
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
@@ -0,0 +1,896 @@
+/* linux/drivers/video/exynos/exynos_mipi_dsi_common.c
+ *
+ * Samsung SoC MIPI-DSI common driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ *
+ * 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.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/ctype.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/memory.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+
+#include <video/mipi_display.h>
+#include <video/exynos_mipi_dsim.h>
+
+#include <mach/map.h>
+
+#include "exynos_mipi_dsi_regs.h"
+#include "exynos_mipi_dsi_lowlevel.h"
+#include "exynos_mipi_dsi_common.h"
+
+#define MIPI_FIFO_TIMEOUT	msecs_to_jiffies(250)
+#define MIPI_RX_FIFO_READ_DONE  0x30800002
+#define MIPI_MAX_RX_FIFO        20
+#define MHZ			(1000 * 1000)
+#define FIN_HZ			(24 * MHZ)
+
+#define DFIN_PLL_MIN_HZ		(6 * MHZ)
+#define DFIN_PLL_MAX_HZ		(12 * MHZ)
+
+#define DFVCO_MIN_HZ		(500 * MHZ)
+#define DFVCO_MAX_HZ		(1000 * MHZ)
+
+#define TRY_GET_FIFO_TIMEOUT	(5000 * 2)
+#define TRY_FIFO_CLEAR		(10)
+
+/* MIPI-DSIM status types. */
+enum {
+	DSIM_STATE_INIT,	/* should be initialized. */
+	DSIM_STATE_STOP,	/* CPU and LCDC are LP mode. */
+	DSIM_STATE_HSCLKEN,	/* HS clock was enabled. */
+	DSIM_STATE_ULPS
+};
+
+/* define DSI lane types. */
+enum {
+	DSIM_LANE_CLOCK = (1 << 0),
+	DSIM_LANE_DATA0 = (1 << 1),
+	DSIM_LANE_DATA1 = (1 << 2),
+	DSIM_LANE_DATA2 = (1 << 3),
+	DSIM_LANE_DATA3 = (1 << 4)
+};
+
+static unsigned int dpll_table[15] = {
+	100, 120, 170, 220, 270,
+	320, 390, 450, 510, 560,
+	640, 690, 770, 870, 950
+};
+
+irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id)
+{
+	unsigned int intsrc = 0;
+	unsigned int intmsk = 0;
+	struct mipi_dsim_device *dsim = NULL;
+
+	dsim = dev_id;
+	if (!dsim) {
+		dev_dbg(dsim->dev, KERN_ERR "%s:error: wrong parameter\n",
+							__func__);
+		return IRQ_HANDLED;
+	}
+
+	intsrc = exynos_mipi_dsi_read_interrupt(dsim);
+	intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim);
+
+	intmsk = ~(intmsk) & intsrc;
+
+	switch (intmsk) {
+	case INTMSK_RX_DONE:
+		complete(&dsim_rd_comp);
+		dev_dbg(dsim->dev, "MIPI INTMSK_RX_DONE\n");
+		break;
+	case INTMSK_FIFO_EMPTY:
+		complete(&dsim_wr_comp);
+		dev_dbg(dsim->dev, "MIPI INTMSK_FIFO_EMPTY\n");
+		break;
+	default:
+		break;
+	}
+
+	exynos_mipi_dsi_clear_interrupt(dsim, intmsk);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * write long packet to mipi dsi slave
+ * @dsim: mipi dsim device structure.
+ * @data0: packet data to send.
+ * @data1: size of packet data
+ */
+static void exynos_mipi_dsi_long_data_wr(struct mipi_dsim_device *dsim,
+		const unsigned char *data0, unsigned int data_size)
+{
+	unsigned int data_cnt = 0, payload = 0;
+
+	/* in case that data count is more then 4 */
+	for (data_cnt = 0; data_cnt < data_size; data_cnt += 4) {
+		/*
+		 * after sending 4bytes per one time,
+		 * send remainder data less then 4.
+		 */
+		if ((data_size - data_cnt) < 4) {
+			if ((data_size - data_cnt) == 3) {
+				payload = data0[data_cnt] |
+				    data0[data_cnt + 1] << 8 |
+					data0[data_cnt + 2] << 16;
+			dev_dbg(dsim->dev, "count = 3 payload = %x, %x %x %x\n",
+				payload, data0[data_cnt],
+				data0[data_cnt + 1],
+				data0[data_cnt + 2]);
+			} else if ((data_size - data_cnt) == 2) {
+				payload = data0[data_cnt] |
+					data0[data_cnt + 1] << 8;
+			dev_dbg(dsim->dev,
+				"count = 2 payload = %x, %x %x\n", payload,
+				data0[data_cnt],
+				data0[data_cnt + 1]);
+			} else if ((data_size - data_cnt) == 1) {
+				payload = data0[data_cnt];
+			}
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+		/* send 4bytes per one time. */
+		} else {
+			payload = data0[data_cnt] |
+				data0[data_cnt + 1] << 8 |
+				data0[data_cnt + 2] << 16 |
+				data0[data_cnt + 3] << 24;
+
+			dev_dbg(dsim->dev,
+				"count = 4 payload = %x, %x %x %x %x\n",
+				payload, *(u8 *)(data0 + data_cnt),
+				data0[data_cnt + 1],
+				data0[data_cnt + 2],
+				data0[data_cnt + 3]);
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+		}
+	}
+}
+
+int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	const unsigned char *data0, unsigned int data_size)
+{
+	unsigned int check_rx_ack = 0;
+
+	if (dsim->state == DSIM_STATE_ULPS) {
+		dev_err(dsim->dev, "state is ULPS.\n");
+
+		return -EINVAL;
+	}
+
+	/* FIXME!!! why does it need this delay? */
+	msleep(20);
+
+	mutex_lock(&dsim->lock);
+
+	switch (data_id) {
+	/* short packet types of packet types for command. */
+	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
+	case MIPI_DSI_DCS_SHORT_WRITE:
+	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0[0], data0[1]);
+		if (check_rx_ack) {
+			/* process response func should be implemented */
+			mutex_unlock(&dsim->lock);
+			return 0;
+		} else {
+			mutex_unlock(&dsim->lock);
+			return -EINVAL;
+		}
+
+	/* general command */
+	case MIPI_DSI_COLOR_MODE_OFF:
+	case MIPI_DSI_COLOR_MODE_ON:
+	case MIPI_DSI_SHUTDOWN_PERIPHERAL:
+	case MIPI_DSI_TURN_ON_PERIPHERAL:
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0[0], data0[1]);
+		if (check_rx_ack) {
+			/* process response func should be implemented. */
+			mutex_unlock(&dsim->lock);
+			return 0;
+		} else {
+			mutex_unlock(&dsim->lock);
+			return -EINVAL;
+		}
+
+	/* packet types for video data */
+	case MIPI_DSI_V_SYNC_START:
+	case MIPI_DSI_V_SYNC_END:
+	case MIPI_DSI_H_SYNC_START:
+	case MIPI_DSI_H_SYNC_END:
+	case MIPI_DSI_END_OF_TRANSMISSION:
+		mutex_unlock(&dsim->lock);
+		return 0;
+
+	/* long packet type and null packet */
+	case MIPI_DSI_NULL_PACKET:
+	case MIPI_DSI_BLANKING_PACKET:
+		mutex_unlock(&dsim->lock);
+		return 0;
+	case MIPI_DSI_GENERIC_LONG_WRITE:
+	case MIPI_DSI_DCS_LONG_WRITE:
+	{
+		unsigned int size, payload = 0;
+		INIT_COMPLETION(dsim_wr_comp);
+
+		size = data_size * 4;
+
+		/* if data count is less then 4, then send 3bytes data.  */
+		if (data_size < 4) {
+			payload = data0[0] |
+				data0[1] << 8 |
+				data0[2] << 16;
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+
+			dev_dbg(dsim->dev, "count = %d payload = %x,%x %x %x\n",
+				data_size, payload, data0[0],
+				data0[1], data0[2]);
+
+		/* in case that data count is more then 4 */
+		} else
+			exynos_mipi_dsi_long_data_wr(dsim, data0, data_size);
+
+		/* put data into header fifo */
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data_size & 0xff,
+			(data_size & 0xff00) >> 8);
+
+		if (!wait_for_completion_interruptible_timeout(&dsim_wr_comp,
+							MIPI_FIFO_TIMEOUT)) {
+			dev_warn(dsim->dev, "command write timeout.\n");
+			mutex_unlock(&dsim->lock);
+			return -EAGAIN;
+		}
+
+		if (check_rx_ack) {
+			/* process response func should be implemented. */
+			mutex_unlock(&dsim->lock);
+			return 0;
+		} else {
+			mutex_unlock(&dsim->lock);
+			return -EINVAL;
+		}
+	}
+
+	/* packet typo for video data */
+	case MIPI_DSI_PACKED_PIXEL_STREAM_16:
+	case MIPI_DSI_PACKED_PIXEL_STREAM_18:
+	case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
+	case MIPI_DSI_PACKED_PIXEL_STREAM_24:
+		if (check_rx_ack) {
+			/* process response func should be implemented. */
+			mutex_unlock(&dsim->lock);
+			return 0;
+		} else {
+			mutex_unlock(&dsim->lock);
+			return -EINVAL;
+		}
+	default:
+		dev_warn(dsim->dev,
+			"data id %x is not supported current DSI spec.\n",
+			data_id);
+
+		mutex_unlock(&dsim->lock);
+		return -EINVAL;
+	}
+
+	mutex_unlock(&dsim->lock);
+	return 0;
+}
+
+static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,
+		unsigned int req_size, unsigned int rx_data, u8 *rx_buf)
+{
+	unsigned int rcv_pkt, i, j;
+	u16 rxsize;
+
+	/* for long packet */
+	rxsize = (u16)((rx_data & 0x00ffff00) >> 8);
+	dev_dbg(dsim->dev, "mipi dsi rx size : %d\n", rxsize);
+	if (rxsize != req_size) {
+		dev_dbg(dsim->dev,
+			"received size mismatch received: %d, requested: %d\n",
+			rxsize, req_size);
+		goto err;
+	}
+
+	for (i = 0; i < (rxsize >> 2); i++) {
+		rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
+		dev_dbg(dsim->dev, "received pkt : %08x\n", rcv_pkt);
+		for (j = 0; j < 4; j++) {
+			rx_buf[(i * 4) + j] =
+					(u8)(rcv_pkt >> (j * 8)) & 0xff;
+			dev_dbg(dsim->dev, "received value : %02x\n",
+					(rcv_pkt >> (j * 8)) & 0xff);
+		}
+	}
+	if (rxsize % 4) {
+		rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
+		dev_dbg(dsim->dev, "received pkt : %08x\n", rcv_pkt);
+		for (j = 0; j < (rxsize % 4); j++) {
+			rx_buf[(i * 4) + j] =
+					(u8)(rcv_pkt >> (j * 8)) & 0xff;
+			dev_dbg(dsim->dev, "received value : %02x\n",
+					(rcv_pkt >> (j * 8)) & 0xff);
+		}
+	}
+
+	return rxsize;
+
+err:
+	return -EINVAL;
+}
+
+static unsigned int exynos_mipi_dsi_response_size(unsigned int req_size)
+{
+	switch (req_size) {
+	case 1:
+		return MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE;
+	case 2:
+		return MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE;
+	default:
+		return MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE;
+	}
+}
+
+int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	unsigned int data0, unsigned int req_size, u8 *rx_buf)
+{
+	unsigned int rx_data, rcv_pkt, i;
+	u8 response = 0;
+	u16 rxsize;
+
+	if (dsim->state == DSIM_STATE_ULPS) {
+		dev_err(dsim->dev, "state is ULPS.\n");
+
+		return -EINVAL;
+	}
+
+	/* FIXME!!! */
+	msleep(20);
+
+	mutex_lock(&dsim->lock);
+	INIT_COMPLETION(dsim_rd_comp);
+	exynos_mipi_dsi_rd_tx_header(dsim,
+		MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, req_size);
+
+	response = exynos_mipi_dsi_response_size(req_size);
+
+	switch (data_id) {
+	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
+	case MIPI_DSI_DCS_READ:
+		exynos_mipi_dsi_rd_tx_header(dsim,
+			data_id, data0);
+		/* process response func should be implemented. */
+		break;
+	default:
+		dev_warn(dsim->dev,
+			"data id %x is not supported current DSI spec.\n",
+			data_id);
+
+		return -EINVAL;
+	}
+
+	if (!wait_for_completion_interruptible_timeout(&dsim_rd_comp,
+				MIPI_FIFO_TIMEOUT)) {
+		pr_err("RX done interrupt timeout\n");
+		mutex_unlock(&dsim->lock);
+		return 0;
+	}
+
+	msleep(20);
+
+	rx_data = exynos_mipi_dsi_rd_rx_fifo(dsim);
+
+	if ((u8)(rx_data & 0xff) != response) {
+		printk(KERN_ERR
+			"mipi dsi wrong response rx_data : %x, response:%x\n",
+			rx_data, response);
+		goto clear_rx_fifo;
+	}
+
+	if (req_size <= 2) {
+		/* for short packet */
+		for (i = 0; i < req_size; i++)
+			rx_buf[i] = (rx_data >> (8 + (i * 8))) & 0xff;
+		rxsize = req_size;
+	} else {
+		/* for long packet */
+		rxsize = exynos_mipi_dsi_long_data_rd(dsim, req_size, rx_data,
+							rx_buf);
+		if (rxsize != req_size)
+			goto clear_rx_fifo;
+	}
+
+	rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
+
+	msleep(20);
+
+	if (rcv_pkt != MIPI_RX_FIFO_READ_DONE) {
+		dev_info(dsim->dev,
+			"Can't found RX FIFO READ DONE FLAG : %x\n", rcv_pkt);
+		goto clear_rx_fifo;
+	}
+
+	mutex_unlock(&dsim->lock);
+
+	return rxsize;
+
+clear_rx_fifo:
+	i = 0;
+	while (1) {
+		rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
+		if ((rcv_pkt == MIPI_RX_FIFO_READ_DONE)
+				|| (i > MIPI_MAX_RX_FIFO))
+			break;
+		dev_dbg(dsim->dev,
+				"mipi dsi clear rx fifo : %08x\n", rcv_pkt);
+		i++;
+	}
+	dev_info(dsim->dev,
+		"mipi dsi rx done count : %d, rcv_pkt : %08x\n", i, rcv_pkt);
+
+	mutex_unlock(&dsim->lock);
+
+	return 0;
+}
+
+static int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim,
+				unsigned int enable)
+{
+	int sw_timeout;
+
+	if (enable) {
+		sw_timeout = 1000;
+
+		exynos_mipi_dsi_enable_pll(dsim, 1);
+		while (1) {
+			sw_timeout--;
+			if (exynos_mipi_dsi_is_pll_stable(dsim))
+				return 0;
+			if (sw_timeout == 0)
+				return -EINVAL;
+		}
+	} else
+		exynos_mipi_dsi_enable_pll(dsim, 0);
+
+	return 0;
+}
+
+static unsigned long exynos_mipi_dsi_change_pll(struct mipi_dsim_device *dsim,
+	unsigned int pre_divider, unsigned int main_divider,
+	unsigned int scaler)
+{
+	unsigned long dfin_pll, dfvco, dpll_out;
+	unsigned int i, freq_band = 0xf;
+
+	dfin_pll = (FIN_HZ / pre_divider);
+
+	/******************************************************
+	 *	Serial Clock(=ByteClk X 8)	FreqBand[3:0] *
+	 ******************************************************
+	 *	~ 99.99 MHz			0000
+	 *	100 ~ 119.99 MHz		0001
+	 *	120 ~ 159.99 MHz		0010
+	 *	160 ~ 199.99 MHz		0011
+	 *	200 ~ 239.99 MHz		0100
+	 *	140 ~ 319.99 MHz		0101
+	 *	320 ~ 389.99 MHz		0110
+	 *	390 ~ 449.99 MHz		0111
+	 *	450 ~ 509.99 MHz		1000
+	 *	510 ~ 559.99 MHz		1001
+	 *	560 ~ 639.99 MHz		1010
+	 *	640 ~ 689.99 MHz		1011
+	 *	690 ~ 769.99 MHz		1100
+	 *	770 ~ 869.99 MHz		1101
+	 *	870 ~ 949.99 MHz		1110
+	 *	950 ~ 1000 MHz			1111
+	 ******************************************************/
+	if (dfin_pll < DFIN_PLL_MIN_HZ || dfin_pll > DFIN_PLL_MAX_HZ) {
+		dev_warn(dsim->dev, "fin_pll range should be 6MHz ~ 12MHz\n");
+		exynos_mipi_dsi_enable_afc(dsim, 0, 0);
+	} else {
+		if (dfin_pll < 7 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x1);
+		else if (dfin_pll < 8 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x0);
+		else if (dfin_pll < 9 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x3);
+		else if (dfin_pll < 10 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x2);
+		else if (dfin_pll < 11 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x5);
+		else
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x4);
+	}
+
+	dfvco = dfin_pll * main_divider;
+	dev_dbg(dsim->dev, "dfvco = %lu, dfin_pll = %lu, main_divider = %d\n",
+				dfvco, dfin_pll, main_divider);
+	if (dfvco < DFVCO_MIN_HZ || dfvco > DFVCO_MAX_HZ)
+		dev_warn(dsim->dev, "fvco range should be 500MHz ~ 1000MHz\n");
+
+	dpll_out = dfvco / (1 << scaler);
+	dev_dbg(dsim->dev, "dpll_out = %lu, dfvco = %lu, scaler = %d\n",
+		dpll_out, dfvco, scaler);
+
+	for (i = 0; i < ARRAY_SIZE(dpll_table); i++) {
+		if (dpll_out < dpll_table[i] * MHZ) {
+			freq_band = i;
+			break;
+		}
+	}
+
+	dev_dbg(dsim->dev, "freq_band = %d\n", freq_band);
+
+	exynos_mipi_dsi_pll_freq(dsim, pre_divider, main_divider, scaler);
+
+	exynos_mipi_dsi_hs_zero_ctrl(dsim, 0);
+	exynos_mipi_dsi_prep_ctrl(dsim, 0);
+
+	/* Freq Band */
+	exynos_mipi_dsi_pll_freq_band(dsim, freq_band);
+
+	/* Stable time */
+	exynos_mipi_dsi_pll_stable_time(dsim, dsim->dsim_config->pll_stable_time);
+
+	/* Enable PLL */
+	dev_dbg(dsim->dev, "FOUT of mipi dphy pll is %luMHz\n",
+		(dpll_out / MHZ));
+
+	return dpll_out;
+}
+
+static int exynos_mipi_dsi_set_clock(struct mipi_dsim_device *dsim,
+	unsigned int byte_clk_sel, unsigned int enable)
+{
+	unsigned int esc_div;
+	unsigned long esc_clk_error_rate;
+	unsigned long hs_clk = 0, byte_clk = 0, escape_clk = 0;
+
+	if (enable) {
+		dsim->e_clk_src = byte_clk_sel;
+
+		/* Escape mode clock and byte clock source */
+		exynos_mipi_dsi_set_byte_clock_src(dsim, byte_clk_sel);
+
+		/* DPHY, DSIM Link : D-PHY clock out */
+		if (byte_clk_sel == DSIM_PLL_OUT_DIV8) {
+			hs_clk = exynos_mipi_dsi_change_pll(dsim,
+				dsim->dsim_config->p, dsim->dsim_config->m,
+				dsim->dsim_config->s);
+			if (hs_clk == 0) {
+				dev_err(dsim->dev,
+					"failed to get hs clock.\n");
+				return -EINVAL;
+			}
+
+			byte_clk = hs_clk / 8;
+			exynos_mipi_dsi_enable_pll_bypass(dsim, 0);
+			exynos_mipi_dsi_pll_on(dsim, 1);
+		/* DPHY : D-PHY clock out, DSIM link : external clock out */
+		} else if (byte_clk_sel == DSIM_EXT_CLK_DIV8) {
+			dev_warn(dsim->dev, "this project is not support\n");
+			dev_warn(dsim->dev,
+				"external clock source for MIPI DSIM.\n");
+		} else if (byte_clk_sel == DSIM_EXT_CLK_BYPASS) {
+			dev_warn(dsim->dev, "this project is not support\n");
+			dev_warn(dsim->dev,
+				"external clock source for MIPI DSIM\n");
+		}
+
+		/* escape clock divider */
+		esc_div = byte_clk / (dsim->dsim_config->esc_clk);
+		dev_dbg(dsim->dev,
+			"esc_div = %d, byte_clk = %lu, esc_clk = %lu\n",
+			esc_div, byte_clk, dsim->dsim_config->esc_clk);
+		if ((byte_clk / esc_div) >= (20 * MHZ) ||
+				(byte_clk / esc_div) >
+					dsim->dsim_config->esc_clk)
+			esc_div += 1;
+
+		escape_clk = byte_clk / esc_div;
+		dev_dbg(dsim->dev,
+			"escape_clk = %lu, byte_clk = %lu, esc_div = %d\n",
+			escape_clk, byte_clk, esc_div);
+
+		/* enable escape clock. */
+		exynos_mipi_dsi_enable_byte_clock(dsim, 1);
+
+		/* enable byte clk and escape clock */
+		exynos_mipi_dsi_set_esc_clk_prs(dsim, 1, esc_div);
+		/* escape clock on lane */
+		exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
+			(DSIM_LANE_CLOCK | dsim->data_lane), 1);
+
+		dev_dbg(dsim->dev, "byte clock is %luMHz\n",
+			(byte_clk / MHZ));
+		dev_dbg(dsim->dev, "escape clock that user's need is %lu\n",
+			(dsim->dsim_config->esc_clk / MHZ));
+		dev_dbg(dsim->dev, "escape clock divider is %x\n", esc_div);
+		dev_dbg(dsim->dev, "escape clock is %luMHz\n",
+			((byte_clk / esc_div) / MHZ));
+
+		if ((byte_clk / esc_div) > escape_clk) {
+			esc_clk_error_rate = escape_clk /
+				(byte_clk / esc_div);
+			dev_warn(dsim->dev, "error rate is %lu over.\n",
+				(esc_clk_error_rate / 100));
+		} else if ((byte_clk / esc_div) < (escape_clk)) {
+			esc_clk_error_rate = (byte_clk / esc_div) /
+				escape_clk;
+			dev_warn(dsim->dev, "error rate is %lu under.\n",
+				(esc_clk_error_rate / 100));
+		}
+	} else {
+		exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
+			(DSIM_LANE_CLOCK | dsim->data_lane), 0);
+		exynos_mipi_dsi_set_esc_clk_prs(dsim, 0, 0);
+
+		/* disable escape clock. */
+		exynos_mipi_dsi_enable_byte_clock(dsim, 0);
+
+		if (byte_clk_sel == DSIM_PLL_OUT_DIV8)
+			exynos_mipi_dsi_pll_on(dsim, 0);
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim)
+{
+	dsim->state = DSIM_STATE_INIT;
+
+	switch (dsim->dsim_config->e_no_data_lane) {
+	case DSIM_DATA_LANE_1:
+		dsim->data_lane = DSIM_LANE_DATA0;
+		break;
+	case DSIM_DATA_LANE_2:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
+		break;
+	case DSIM_DATA_LANE_3:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+			DSIM_LANE_DATA2;
+		break;
+	case DSIM_DATA_LANE_4:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+			DSIM_LANE_DATA2 | DSIM_LANE_DATA3;
+		break;
+	default:
+		dev_info(dsim->dev, "data lane is invalid.\n");
+		return -EINVAL;
+	};
+
+	exynos_mipi_dsi_sw_reset(dsim);
+	exynos_mipi_dsi_func_reset(dsim);
+
+	exynos_mipi_dsi_dp_dn_swap(dsim, 0);
+
+	return 0;
+}
+
+void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim)
+{
+	unsigned int src = 0;
+
+	src = (INTSRC_SFR_FIFO_EMPTY | INTSRC_RX_DATA_DONE);
+	exynos_mipi_dsi_set_interrupt(dsim, src, 1);
+
+	src = 0;
+	src = ~(INTMSK_RX_DONE | INTMSK_FIFO_EMPTY);
+	exynos_mipi_dsi_set_interrupt_mask(dsim, src, 1);
+}
+
+int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	/* enable only frame done interrupt */
+	exynos_mipi_dsi_set_interrupt_mask(dsim, INTMSK_FRAME_DONE, enable);
+
+	return 0;
+}
+
+void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+
+	/* consider Main display and Sub display. */
+
+	exynos_mipi_dsi_set_main_stand_by(dsim, enable);
+}
+
+int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
+	struct mipi_dsim_config *dsim_config)
+{
+	struct mipi_dsim_platform_data *dsim_pd;
+	struct fb_videomode *timing;
+
+	dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
+	timing = (struct fb_videomode *)dsim_pd->lcd_panel_info;
+
+	/* in case of VIDEO MODE (RGB INTERFACE), it sets polarities. */
+	if (dsim_config->e_interface == (u32) DSIM_VIDEO) {
+		if (dsim_config->auto_vertical_cnt == 0) {
+			exynos_mipi_dsi_set_main_disp_vporch(dsim,
+				dsim_config->cmd_allow,
+				timing->upper_margin,
+				timing->lower_margin);
+			exynos_mipi_dsi_set_main_disp_hporch(dsim,
+				timing->left_margin,
+				timing->right_margin);
+			exynos_mipi_dsi_set_main_disp_sync_area(dsim,
+				timing->vsync_len,
+				timing->hsync_len);
+		}
+	}
+
+	exynos_mipi_dsi_set_main_disp_resol(dsim, timing->xres,
+			timing->yres);
+
+	exynos_mipi_dsi_display_config(dsim, dsim_config);
+
+	dev_info(dsim->dev, "lcd panel ==> width = %d, height = %d\n",
+			timing->xres, timing->yres);
+
+	return 0;
+}
+
+int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim)
+{
+	unsigned int time_out = 100;
+
+	switch (dsim->state) {
+	case DSIM_STATE_INIT:
+		exynos_mipi_dsi_init_fifo_pointer(dsim, 0x1f);
+
+		/* dsi configuration */
+		exynos_mipi_dsi_init_config(dsim);
+		exynos_mipi_dsi_enable_lane(dsim, DSIM_LANE_CLOCK, 1);
+		exynos_mipi_dsi_enable_lane(dsim, dsim->data_lane, 1);
+
+		/* set clock configuration */
+		exynos_mipi_dsi_set_clock(dsim, dsim->dsim_config->e_byte_clk, 1);
+
+		/* check clock and data lane state are stop state */
+		while (!(exynos_mipi_dsi_is_lane_state(dsim))) {
+			time_out--;
+			if (time_out == 0) {
+				dev_err(dsim->dev,
+					"DSI Master is not stop state.\n");
+				dev_err(dsim->dev,
+					"Check initialization process\n");
+
+				return -EINVAL;
+			}
+		}
+		if (time_out != 0) {
+			dev_info(dsim->dev,
+				"DSI Master driver has been completed.\n");
+			dev_info(dsim->dev, "DSI Master state is stop state\n");
+		}
+
+		dsim->state = DSIM_STATE_STOP;
+
+		/* BTA sequence counters */
+		exynos_mipi_dsi_set_stop_state_counter(dsim,
+			dsim->dsim_config->stop_holding_cnt);
+		exynos_mipi_dsi_set_bta_timeout(dsim,
+			dsim->dsim_config->bta_timeout);
+		exynos_mipi_dsi_set_lpdr_timeout(dsim,
+			dsim->dsim_config->rx_timeout);
+
+		return 0;
+	default:
+		dev_info(dsim->dev, "DSI Master is already init.\n");
+		return 0;
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim)
+{
+	if (dsim->state != DSIM_STATE_STOP) {
+		dev_warn(dsim->dev, "DSIM is not in stop state.\n");
+		return 0;
+	}
+
+	if (dsim->e_clk_src == DSIM_EXT_CLK_BYPASS) {
+		dev_warn(dsim->dev, "clock source is external bypass.\n");
+		return 0;
+	}
+
+	dsim->state = DSIM_STATE_HSCLKEN;
+
+	 /* set LCDC and CPU transfer mode to HS. */
+	exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
+	exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
+	exynos_mipi_dsi_enable_hs_clock(dsim, 1);
+
+	return 0;
+}
+
+int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int mode)
+{
+	if (mode) {
+		if (dsim->state != DSIM_STATE_HSCLKEN) {
+			dev_err(dsim->dev, "HS Clock lane is not enabled.\n");
+			return -EINVAL;
+		}
+
+		exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
+	} else {
+		if (dsim->state == DSIM_STATE_INIT || dsim->state ==
+			DSIM_STATE_ULPS) {
+			dev_err(dsim->dev,
+				"DSI Master is not STOP or HSDT state.\n");
+			return -EINVAL;
+		}
+
+		exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
+{
+	return _exynos_mipi_dsi_get_frame_done_status(dsim);
+}
+
+int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
+{
+	_exynos_mipi_dsi_clear_frame_done(dsim);
+
+	return 0;
+}
+
+int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
+				unsigned int val)
+{
+	int try = TRY_FIFO_CLEAR;
+
+	exynos_mipi_dsi_sw_reset_release(dsim);
+	exynos_mipi_dsi_func_reset(dsim);
+
+	do {
+		if (exynos_mipi_dsi_get_sw_reset_release(dsim)) {
+			exynos_mipi_dsi_init_interrupt(dsim);
+			dev_dbg(dsim->dev, "reset release done.\n");
+			return 0;
+		}
+	} while (--try);
+
+	dev_err(dsim->dev, "failed to clear dsim fifo.\n");
+	return -EAGAIN;
+}
+
+MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("Samusung SoC MIPI-DSI common driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.h b/drivers/video/exynos/exynos_mipi_dsi_common.h
new file mode 100644
index 0000000..4125522
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.h
@@ -0,0 +1,46 @@
+/* linux/drivers/video/exynos_mipi_dsi_common.h
+ *
+ * Header file for Samsung SoC MIPI-DSI common driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * 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 _EXYNOS_MIPI_DSI_COMMON_H
+#define _EXYNOS_MIPI_DSI_COMMON_H
+
+static DECLARE_COMPLETION(dsim_rd_comp);
+static DECLARE_COMPLETION(dsim_wr_comp);
+
+int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	const unsigned char *data0, unsigned int data_size);
+int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	unsigned int data0, unsigned int req_size, u8 *rx_buf);
+irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id);
+void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
+		unsigned int enable);
+int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
+			struct mipi_dsim_config *dsim_info);
+int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int mode);
+int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
+	unsigned int enable);
+int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
+
+extern struct fb_info *registered_fb[FB_MAX] __read_mostly;
+
+int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
+				unsigned int val);
+
+#endif /* _EXYNOS_MIPI_DSI_COMMON_H */
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
new file mode 100644
index 0000000..0ef38ce
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
@@ -0,0 +1,618 @@
+/* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
+ *
+ * Samsung SoC MIPI-DSI lowlevel driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ *
+ * 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.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+
+#include <video/exynos_mipi_dsim.h>
+
+#include <mach/map.h>
+
+#include "exynos_mipi_dsi_regs.h"
+
+void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
+
+	reg |= DSIM_FUNCRST;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
+}
+
+void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
+
+	reg |= DSIM_SWRST;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
+}
+
+void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+
+	reg |= INTSRC_SW_RST_RELEASE;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
+}
+
+int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim)
+{
+	return (readl(dsim->reg_base + EXYNOS_DSIM_INTSRC)) &
+			INTSRC_SW_RST_RELEASE;
+}
+
+unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_INTMSK);
+
+	return reg;
+}
+
+void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
+		unsigned int mode, unsigned int mask)
+{
+	unsigned int reg = 0;
+
+	if (mask)
+		reg |= mode;
+	else
+		reg &= ~mode;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_INTMSK);
+}
+
+void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
+		unsigned int cfg)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
+
+	writel(reg & ~(cfg), dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
+	mdelay(10);
+	reg |= cfg;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
+}
+
+/*
+ * this function set PLL P, M and S value in D-PHY
+ */
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+		unsigned int value)
+{
+	writel(DSIM_AFC_CTL(value), dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
+}
+
+void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL);
+
+	reg &= ~DSIM_MAIN_STAND_BY;
+
+	if (enable)
+		reg |= DSIM_MAIN_STAND_BY;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
+}
+
+void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
+	unsigned int width_resol, unsigned int height_resol)
+{
+	unsigned int reg;
+
+	/* standby should be set after configuration so set to not ready*/
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL)) &
+		~(DSIM_MAIN_STAND_BY);
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
+
+	reg &= ~((0x7ff << 16) | (0x7ff << 0));
+	reg |= DSIM_MAIN_VRESOL(height_resol) | DSIM_MAIN_HRESOL(width_resol);
+
+	reg |= DSIM_MAIN_STAND_BY;
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
+}
+
+void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
+	unsigned int cmd_allow, unsigned int vfront, unsigned int vback)
+{
+	unsigned int reg;
+
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_MVPORCH)) &
+		~((DSIM_CMD_ALLOW_MASK) | (DSIM_STABLE_VFP_MASK) |
+		(DSIM_MAIN_VBP_MASK));
+
+	reg |= (DSIM_CMD_ALLOW_SHIFT(cmd_allow & 0xf) |
+		DSIM_STABLE_VFP_SHIFT(vfront & 0x7ff) |
+		DSIM_MAIN_VBP_SHIFT(vback & 0x7ff));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MVPORCH);
+}
+
+void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
+	unsigned int front, unsigned int back)
+{
+	unsigned int reg;
+
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_MHPORCH)) &
+		~((DSIM_MAIN_HFP_MASK) | (DSIM_MAIN_HBP_MASK));
+
+	reg |= DSIM_MAIN_HFP_SHIFT(front) | DSIM_MAIN_HBP_SHIFT(back);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MHPORCH);
+}
+
+void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
+	unsigned int vert, unsigned int hori)
+{
+	unsigned int reg;
+
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_MSYNC)) &
+		~((DSIM_MAIN_VSA_MASK) | (DSIM_MAIN_HSA_MASK));
+
+	reg |= (DSIM_MAIN_VSA_SHIFT(vert & 0x3ff) |
+		DSIM_MAIN_HSA_SHIFT(hori));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MSYNC);
+}
+
+void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
+	unsigned int vert, unsigned int hori)
+{
+	unsigned int reg;
+
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_SDRESOL)) &
+		~(DSIM_SUB_STANDY_MASK);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
+
+	reg &= ~(DSIM_SUB_VRESOL_MASK) | ~(DSIM_SUB_HRESOL_MASK);
+	reg |= (DSIM_SUB_VRESOL_SHIFT(vert & 0x7ff) |
+		DSIM_SUB_HRESOL_SHIFT(hori & 0x7ff));
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
+
+	reg |= DSIM_SUB_STANDY_SHIFT(1);
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
+}
+
+void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim)
+{
+	struct mipi_dsim_config *dsim_config = dsim->dsim_config;
+
+	unsigned int cfg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
+		~((1 << 28) | (0x1f << 20) | (0x3 << 5));
+
+	cfg =	((DSIM_AUTO_FLUSH(dsim_config->auto_flush)) |
+		(DSIM_EOT_DISABLE(dsim_config->eot_disable)) |
+		(DSIM_AUTO_MODE_SHIFT(dsim_config->auto_vertical_cnt)) |
+		(DSIM_HSE_MODE_SHIFT(dsim_config->hse)) |
+		(DSIM_HFP_MODE_SHIFT(dsim_config->hfp)) |
+		(DSIM_HBP_MODE_SHIFT(dsim_config->hbp)) |
+		(DSIM_HSA_MODE_SHIFT(dsim_config->hsa)) |
+		(DSIM_NUM_OF_DATALANE_SHIFT(dsim_config->e_no_data_lane)));
+
+	writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
+}
+
+void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
+				struct mipi_dsim_config *dsim_config)
+{
+	u32 reg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
+		~((0x3 << 26) | (1 << 25) | (0x3 << 18) | (0x7 << 12) |
+		(0x3 << 16) | (0x7 << 8));
+
+	if (dsim_config->e_interface == DSIM_VIDEO)
+		reg |= (1 << 25);
+	else if (dsim_config->e_interface == DSIM_COMMAND)
+		reg &= ~(1 << 25);
+	else {
+		dev_err(dsim->dev, "unknown lcd type.\n");
+		return;
+	}
+
+	/* main lcd */
+	reg |= ((u8) (dsim_config->e_burst_mode) & 0x3) << 26 |
+		((u8) (dsim_config->e_virtual_ch) & 0x3) << 18 |
+		((u8) (dsim_config->e_pixel_format) & 0x7) << 12;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
+}
+
+void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
+	unsigned int enable)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_CONFIG);
+
+	if (enable)
+		reg |= DSIM_LANE_ENx(lane);
+	else
+		reg &= ~DSIM_LANE_ENx(lane);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
+}
+
+
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+	unsigned int count)
+{
+	unsigned int cfg;
+
+	/* get the data lane number. */
+	cfg = DSIM_NUM_OF_DATALANE_SHIFT(count);
+
+	writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
+}
+
+void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
+	unsigned int afc_code)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
+
+	if (enable) {
+		reg |= (1 << 14);
+		reg &= ~(0x7 << 5);
+		reg |= (afc_code & 0x7) << 5;
+	} else
+		reg &= ~(1 << 14);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
+}
+
+void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_PLL_BYPASS_SHIFT(0x1));
+
+	reg |= DSIM_PLL_BYPASS_SHIFT(enable);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
+	unsigned int m, unsigned int s)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+
+	reg |= ((p & 0x3f) << 13) | ((m & 0x1ff) << 4) | ((s & 0x7) << 1);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
+		unsigned int freq_band)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(DSIM_FREQ_BAND_SHIFT(0x1f));
+
+	reg |= DSIM_FREQ_BAND_SHIFT(freq_band & 0x1f);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
+		unsigned int pre_divider, unsigned int main_divider,
+		unsigned int scaler)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(0x7ffff << 1);
+
+	reg |= (pre_divider & 0x3f) << 13 | (main_divider & 0x1ff) << 4 |
+		(scaler & 0x7) << 1;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
+	unsigned int lock_time)
+{
+	writel(lock_time, dsim->reg_base + EXYNOS_DSIM_PLLTMR);
+}
+
+void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim, unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(DSIM_PLL_EN_SHIFT(0x1));
+
+	reg |= DSIM_PLL_EN_SHIFT(enable & 0x1);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
+		unsigned int src)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_BYTE_CLK_SRC_SHIFT(0x3));
+
+	reg |= (DSIM_BYTE_CLK_SRC_SHIFT(src));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_BYTE_CLKEN_SHIFT(0x1));
+
+	reg |= DSIM_BYTE_CLKEN_SHIFT(enable);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
+		unsigned int enable, unsigned int prs_val)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_ESC_CLKEN_SHIFT(0x1) | 0xffff);
+
+	reg |= DSIM_ESC_CLKEN_SHIFT(enable);
+	if (enable)
+		reg |= prs_val;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
+		unsigned int lane_sel, unsigned int enable)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+
+	if (enable)
+		reg |= DSIM_LANE_ESC_CLKEN(lane_sel);
+	else
+
+		reg &= ~DSIM_LANE_ESC_CLKEN(lane_sel);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
+		~(DSIM_FORCE_STOP_STATE_SHIFT(0x1));
+
+	reg |= (DSIM_FORCE_STOP_STATE_SHIFT(enable & 0x1));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+}
+
+unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
+
+	/**
+	 * check clock and data lane states.
+	 * if MIPI-DSI controller was enabled at bootloader then
+	 * TX_READY_HS_CLK is enabled otherwise STOP_STATE_CLK.
+	 * so it should be checked for two case.
+	 */
+	if ((reg & DSIM_STOP_STATE_DAT(0xf)) &&
+			((reg & DSIM_STOP_STATE_CLK) ||
+			 (reg & DSIM_TX_READY_HS_CLK)))
+		return 1;
+
+	return 0;
+}
+
+void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
+		unsigned int cnt_val)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
+		~(DSIM_STOP_STATE_CNT_SHIFT(0x7ff));
+
+	reg |= (DSIM_STOP_STATE_CNT_SHIFT(cnt_val & 0x7ff));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+}
+
+void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
+		unsigned int timeout)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
+		~(DSIM_BTA_TOUT_SHIFT(0xff));
+
+	reg |= (DSIM_BTA_TOUT_SHIFT(timeout));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
+}
+
+void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
+		unsigned int timeout)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
+		~(DSIM_LPDR_TOUT_SHIFT(0xffff));
+
+	reg |= (DSIM_LPDR_TOUT_SHIFT(timeout));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
+}
+
+void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int lp)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+
+	reg &= ~DSIM_CMD_LPDT_LP;
+
+	if (lp)
+		reg |= DSIM_CMD_LPDT_LP;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+}
+
+void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int lp)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+
+	reg &= ~DSIM_TX_LPDT_LP;
+
+	if (lp)
+		reg |= DSIM_TX_LPDT_LP;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+}
+
+void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_TX_REQUEST_HSCLK_SHIFT(0x1));
+
+	reg |= DSIM_TX_REQUEST_HSCLK_SHIFT(enable);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
+		unsigned int swap_en)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
+
+	reg &= ~(0x3 << 0);
+	reg |= (swap_en & 0x3) << 0;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
+}
+
+void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
+		unsigned int hs_zero)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(0xf << 28);
+
+	reg |= ((hs_zero & 0xf) << 28);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(0x7 << 20);
+
+	reg |= ((prep & 0x7) << 20);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim)
+{
+	return readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+}
+
+void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
+					unsigned int src)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+
+	reg |= src;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
+}
+
+void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
+					unsigned int src, unsigned int enable)
+{
+	unsigned int reg = 0;
+
+	if (enable)
+		reg |= src;
+	else
+		reg &= ~src;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
+}
+
+unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
+
+	return reg & (1 << 31) ? 1 : 0;
+}
+
+unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim)
+{
+	return readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL) & ~(0x1f);
+}
+
+void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim,
+	unsigned int di, unsigned int data0, unsigned int data1)
+{
+	unsigned int reg = (data1 << 16) | (data0 << 8) | ((di & 0x3f) << 0);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
+}
+
+void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
+	unsigned int di, unsigned int data0)
+{
+	unsigned int reg = (data0 << 8) | (di << 0);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
+}
+
+unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim)
+{
+	return readl(dsim->reg_base + EXYNOS_DSIM_RXFIFO);
+}
+
+unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+
+	return (reg & INTSRC_FRAME_DONE) ? 1 : 0;
+}
+
+void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+
+	writel(reg | INTSRC_FRAME_DONE, dsim->reg_base +
+		EXYNOS_DSIM_INTSRC);
+}
+
+void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
+		unsigned int tx_data)
+{
+	writel(tx_data, dsim->reg_base + EXYNOS_DSIM_PAYLOAD);
+}
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
new file mode 100644
index 0000000..8546070
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
@@ -0,0 +1,112 @@
+/* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
+ *
+ * Header file for Samsung SoC MIPI-DSI lowlevel driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * 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 _EXYNOS_MIPI_DSI_LOWLEVEL_H
+#define _EXYNOS_MIPI_DSI_LOWLEVEL_H
+
+void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
+	unsigned int mode, unsigned int mask);
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+					unsigned int count);
+void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
+					unsigned int cfg);
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+				unsigned int value);
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+				unsigned int value);
+void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
+		unsigned int enable);
+void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
+		unsigned int width_resol, unsigned int height_resol);
+void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
+	unsigned int cmd_allow, unsigned int vfront, unsigned int vback);
+void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
+			unsigned int front, unsigned int back);
+void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
+				unsigned int vert, unsigned int hori);
+void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
+				unsigned int vert, unsigned int hori);
+void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
+				struct mipi_dsim_config *dsim_config);
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+				unsigned int count);
+void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
+				unsigned int enable);
+void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
+				unsigned int afc_code);
+void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
+				unsigned int m, unsigned int s);
+void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
+				unsigned int freq_band);
+void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
+			unsigned int pre_divider, unsigned int main_divider,
+			unsigned int scaler);
+void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
+			unsigned int lock_time);
+void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim,
+					unsigned int enable);
+void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
+					unsigned int src);
+void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
+					unsigned int enable);
+void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
+				unsigned int enable, unsigned int prs_val);
+void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
+				unsigned int lane_sel, unsigned int enable);
+void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
+				unsigned int cnt_val);
+void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
+				unsigned int timeout);
+void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
+				unsigned int timeout);
+void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
+					unsigned int lp);
+void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
+					unsigned int lp);
+void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
+				unsigned int swap_en);
+void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
+				unsigned int hs_zero);
+void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep);
+unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim);
+unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
+					unsigned int src);
+void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
+					unsigned int src, unsigned int enable);
+unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim);
+unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim);
+unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
+void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim, unsigned int di,
+				unsigned int data0, unsigned int data1);
+void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
+		unsigned int tx_data);
+void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
+		unsigned int data0, unsigned int data1);
+unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim);
+
+#endif /* _EXYNOS_MIPI_DSI_LOWLEVEL_H */
diff --git a/drivers/video/exynos/exynos_mipi_dsi_regs.h b/drivers/video/exynos/exynos_mipi_dsi_regs.h
new file mode 100644
index 0000000..4227106
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_regs.h
@@ -0,0 +1,149 @@
+/* linux/driver/video/exynos/exynos_mipi_dsi_regs.h
+ *
+ * Register definition file for Samsung MIPI-DSIM driver
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * 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 _EXYNOS_MIPI_DSI_REGS_H
+#define _EXYNOS_MIPI_DSI_REGS_H
+
+#define EXYNOS_DSIM_STATUS		0x0	/* Status register */
+#define EXYNOS_DSIM_SWRST		0x4	/* Software reset register */
+#define EXYNOS_DSIM_CLKCTRL		0x8	/* Clock control register */
+#define EXYNOS_DSIM_TIMEOUT		0xc	/* Time out register */
+#define EXYNOS_DSIM_CONFIG		0x10	/* Configuration register */
+#define EXYNOS_DSIM_ESCMODE		0x14	/* Escape mode register */
+
+/* Main display image resolution register */
+#define EXYNOS_DSIM_MDRESOL		0x18
+#define EXYNOS_DSIM_MVPORCH		0x1c	/* Main display Vporch register */
+#define EXYNOS_DSIM_MHPORCH		0x20	/* Main display Hporch register */
+#define EXYNOS_DSIM_MSYNC		0x24	/* Main display sync area register */
+
+/* Sub display image resolution register */
+#define EXYNOS_DSIM_SDRESOL		0x28
+#define EXYNOS_DSIM_INTSRC		0x2c	/* Interrupt source register */
+#define EXYNOS_DSIM_INTMSK		0x30	/* Interrupt mask register */
+#define EXYNOS_DSIM_PKTHDR		0x34	/* Packet Header FIFO register */
+#define EXYNOS_DSIM_PAYLOAD		0x38	/* Payload FIFO register */
+#define EXYNOS_DSIM_RXFIFO		0x3c	/* Read FIFO register */
+#define EXYNOS_DSIM_FIFOTHLD		0x40	/* FIFO threshold level register */
+#define EXYNOS_DSIM_FIFOCTRL		0x44	/* FIFO status and control register */
+
+/* FIFO memory AC characteristic register */
+#define EXYNOS_DSIM_PLLCTRL		0x4c	/* PLL control register */
+#define EXYNOS_DSIM_PLLTMR		0x50	/* PLL timer register */
+#define EXYNOS_DSIM_PHYACCHR		0x54	/* D-PHY AC characteristic register */
+#define EXYNOS_DSIM_PHYACCHR1		0x58	/* D-PHY AC characteristic register1 */
+
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x)		(((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK		(1 << 8)
+#define DSIM_TX_READY_HS_CLK		(1 << 10)
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST			(1 << 16)
+#define DSIM_SWRST			(1 << 0)
+
+/* EXYNOS_DSIM_TIMEOUT */
+#define DSIM_LPDR_TOUT_SHIFT(x)		((x) << 0)
+#define DSIM_BTA_TOUT_SHIFT(x)		((x) << 16)
+
+/* EXYNOS_DSIM_CLKCTRL */
+#define DSIM_LANE_ESC_CLKEN(x)		(((x) & 0x1f) << 19)
+#define DSIM_BYTE_CLKEN_SHIFT(x)	((x) << 24)
+#define DSIM_BYTE_CLK_SRC_SHIFT(x)	((x) <<	25)
+#define DSIM_PLL_BYPASS_SHIFT(x)	((x) <<	27)
+#define DSIM_ESC_CLKEN_SHIFT(x)		((x) << 28)
+#define DSIM_TX_REQUEST_HSCLK_SHIFT(x)	((x) << 31)
+
+/* EXYNOS_DSIM_CONFIG */
+#define DSIM_LANE_ENx(x)		(((x) & 0x1f) << 0)
+#define DSIM_NUM_OF_DATALANE_SHIFT(x)	((x) << 5)
+#define DSIM_HSA_MODE_SHIFT(x)		((x) << 20)
+#define DSIM_HBP_MODE_SHIFT(x)		((x) << 21)
+#define DSIM_HFP_MODE_SHIFT(x)		((x) << 22)
+#define DSIM_HSE_MODE_SHIFT(x)		((x) << 23)
+#define DSIM_AUTO_MODE_SHIFT(x)		((x) << 24)
+#define DSIM_EOT_DISABLE(x)		((x) << 28)
+#define DSIM_AUTO_FLUSH(x)		((x) << 29)
+
+#define DSIM_NUM_OF_DATA_LANE(x)	((x) << DSIM_NUM_OF_DATALANE_SHIFT)
+
+/* EXYNOS_DSIM_ESCMODE */
+#define DSIM_TX_LPDT_LP			(1 << 6)
+#define DSIM_CMD_LPDT_LP		(1 << 7)
+#define DSIM_FORCE_STOP_STATE_SHIFT(x)	((x) << 20)
+#define DSIM_STOP_STATE_CNT_SHIFT(x)	((x) << 21)
+
+/* EXYNOS_DSIM_MDRESOL */
+#define DSIM_MAIN_STAND_BY		(1 << 31)
+#define DSIM_MAIN_VRESOL(x)		(((x) & 0x7ff) << 16)
+#define DSIM_MAIN_HRESOL(x)		(((x) & 0X7ff) << 0)
+
+/* EXYNOS_DSIM_MVPORCH */
+#define DSIM_CMD_ALLOW_SHIFT(x)		((x) << 28)
+#define DSIM_STABLE_VFP_SHIFT(x)	((x) << 16)
+#define DSIM_MAIN_VBP_SHIFT(x)		((x) << 0)
+#define DSIM_CMD_ALLOW_MASK		(0xf << 28)
+#define DSIM_STABLE_VFP_MASK		(0x7ff << 16)
+#define DSIM_MAIN_VBP_MASK		(0x7ff << 0)
+
+/* EXYNOS_DSIM_MHPORCH */
+#define DSIM_MAIN_HFP_SHIFT(x)		((x) << 16)
+#define DSIM_MAIN_HBP_SHIFT(x)		((x) << 0)
+#define DSIM_MAIN_HFP_MASK		((0xffff) << 16)
+#define DSIM_MAIN_HBP_MASK		((0xffff) << 0)
+
+/* EXYNOS_DSIM_MSYNC */
+#define DSIM_MAIN_VSA_SHIFT(x)		((x) << 22)
+#define DSIM_MAIN_HSA_SHIFT(x)		((x) << 0)
+#define DSIM_MAIN_VSA_MASK		((0x3ff) << 22)
+#define DSIM_MAIN_HSA_MASK		((0xffff) << 0)
+
+/* EXYNOS_DSIM_SDRESOL */
+#define DSIM_SUB_STANDY_SHIFT(x)	((x) << 31)
+#define DSIM_SUB_VRESOL_SHIFT(x)	((x) << 16)
+#define DSIM_SUB_HRESOL_SHIFT(x)	((x) << 0)
+#define DSIM_SUB_STANDY_MASK		((0x1) << 31)
+#define DSIM_SUB_VRESOL_MASK		((0x7ff) << 16)
+#define DSIM_SUB_HRESOL_MASK		((0x7ff) << 0)
+
+/* EXYNOS_DSIM_INTSRC */
+#define INTSRC_PLL_STABLE		(1 << 31)
+#define INTSRC_SW_RST_RELEASE		(1 << 30)
+#define INTSRC_SFR_FIFO_EMPTY		(1 << 29)
+#define INTSRC_FRAME_DONE		(1 << 24)
+#define INTSRC_RX_DATA_DONE		(1 << 18)
+
+/* EXYNOS_DSIM_INTMSK */
+#define INTMSK_FIFO_EMPTY		(1 << 29)
+#define INTMSK_BTA			(1 << 25)
+#define INTMSK_FRAME_DONE		(1 << 24)
+#define INTMSK_RX_TIMEOUT		(1 << 21)
+#define INTMSK_BTA_TIMEOUT		(1 << 20)
+#define INTMSK_RX_DONE			(1 << 18)
+#define INTMSK_RX_TE			(1 << 17)
+#define INTMSK_RX_ACK			(1 << 16)
+#define INTMSK_RX_ECC_ERR		(1 << 15)
+#define INTMSK_RX_CRC_ERR		(1 << 14)
+
+/* EXYNOS_DSIM_FIFOCTRL */
+#define SFR_HEADER_EMPTY		(1 << 22)
+
+/* EXYNOS_DSIM_PHYACCHR */
+#define DSIM_AFC_CTL(x)			(((x) & 0x7) << 5)
+
+/* EXYNOS_DSIM_PLLCTRL */
+#define DSIM_PLL_EN_SHIFT(x)		((x) << 23)
+#define DSIM_FREQ_BAND_SHIFT(x)		((x) << 24)
+
+#endif /* _EXYNOS_MIPI_DSI_REGS_H */
diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/exynos/s6e8ax0.c
new file mode 100644
index 0000000..4aa9ac6
--- /dev/null
+++ b/drivers/video/exynos/s6e8ax0.c
@@ -0,0 +1,898 @@
+/* linux/drivers/video/exynos/s6e8ax0.c
+ *
+ * MIPI-DSI based s6e8ax0 AMOLED lcd 4.65 inch panel driver.
+ *
+ * Inki Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ *
+ * 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.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/lcd.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+#include <video/exynos_mipi_dsim.h>
+
+#define LDI_MTP_LENGTH		24
+#define DSIM_PM_STABLE_TIME	10
+#define MIN_BRIGHTNESS		0
+#define MAX_BRIGHTNESS		24
+#define GAMMA_TABLE_COUNT	26
+
+#define POWER_IS_ON(pwr)	((pwr) == FB_BLANK_UNBLANK)
+#define POWER_IS_OFF(pwr)	((pwr) == FB_BLANK_POWERDOWN)
+#define POWER_IS_NRM(pwr)	((pwr) == FB_BLANK_NORMAL)
+
+#define lcd_to_master(a)	(a->dsim_dev->master)
+#define lcd_to_master_ops(a)	((lcd_to_master(a))->master_ops)
+
+enum {
+	DSIM_NONE_STATE = 0,
+	DSIM_RESUME_COMPLETE = 1,
+	DSIM_FRAME_DONE = 2,
+};
+
+struct s6e8ax0 {
+	struct device	*dev;
+	unsigned int			power;
+	unsigned int			id;
+	unsigned int			gamma;
+	unsigned int			acl_enable;
+	unsigned int			cur_acl;
+
+	struct lcd_device	*ld;
+	struct backlight_device	*bd;
+
+	struct mipi_dsim_lcd_device	*dsim_dev;
+	struct lcd_platform_data	*ddi_pd;
+	struct mutex			lock;
+	bool  enabled;
+};
+
+
+static struct regulator_bulk_data supplies[] = {
+	{ .supply = "vdd3", },
+	{ .supply = "vci", },
+};
+
+static void s6e8ax0_regulator_enable(struct s6e8ax0 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+
+	pd = lcd->ddi_pd;
+	mutex_lock(&lcd->lock);
+	if (!lcd->enabled) {
+		ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
+		if (ret)
+			goto out;
+
+		lcd->enabled = true;
+	}
+	msleep(pd->power_on_delay);
+out:
+	mutex_unlock(&lcd->lock);
+}
+
+static void s6e8ax0_regulator_disable(struct s6e8ax0 *lcd)
+{
+	int ret = 0;
+
+	mutex_lock(&lcd->lock);
+	if (lcd->enabled) {
+		ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+		if (ret)
+			goto out;
+
+		lcd->enabled = false;
+	}
+out:
+	mutex_unlock(&lcd->lock);
+}
+
+static const unsigned char s6e8ax0_22_gamma_30[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xf5, 0x00, 0xff, 0xad, 0xaf,
+	0xbA, 0xc3, 0xd8, 0xc5, 0x9f, 0xc6, 0x9e, 0xc1, 0xdc, 0xc0,
+	0x00, 0x61, 0x00, 0x5a, 0x00, 0x74,
+};
+
+static const unsigned char s6e8ax0_22_gamma_50[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xe8, 0x1f, 0xf7, 0xad, 0xc0,
+	0xb5, 0xc4, 0xdc, 0xc4, 0x9e, 0xc6, 0x9c, 0xbb, 0xd8, 0xbb,
+	0x00, 0x70, 0x00, 0x68, 0x00, 0x86,
+};
+
+static const unsigned char s6e8ax0_22_gamma_60[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xde, 0x1f, 0xef, 0xad, 0xc4,
+	0xb3, 0xc3, 0xdd, 0xc4, 0x9e, 0xc6, 0x9c, 0xbc, 0xd6, 0xba,
+	0x00, 0x75, 0x00, 0x6e, 0x00, 0x8d,
+};
+
+static const unsigned char s6e8ax0_22_gamma_70[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xd8, 0x1f, 0xe7, 0xaf, 0xc8,
+	0xb4, 0xc4, 0xdd, 0xc3, 0x9d, 0xc6, 0x9c, 0xbb, 0xd6, 0xb9,
+	0x00, 0x7a, 0x00, 0x72, 0x00, 0x93,
+};
+
+static const unsigned char s6e8ax0_22_gamma_80[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xc9, 0x1f, 0xde, 0xae, 0xc9,
+	0xb1, 0xc3, 0xdd, 0xc2, 0x9d, 0xc5, 0x9b, 0xbc, 0xd6, 0xbb,
+	0x00, 0x7f, 0x00, 0x77, 0x00, 0x99,
+};
+
+static const unsigned char s6e8ax0_22_gamma_90[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xc7, 0x1f, 0xd9, 0xb0, 0xcc,
+	0xb2, 0xc3, 0xdc, 0xc1, 0x9c, 0xc6, 0x9c, 0xbc, 0xd4, 0xb9,
+	0x00, 0x83, 0x00, 0x7b, 0x00, 0x9e,
+};
+
+static const unsigned char s6e8ax0_22_gamma_100[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xbd, 0x80, 0xcd, 0xba, 0xce,
+	0xb3, 0xc4, 0xde, 0xc3, 0x9c, 0xc4, 0x9, 0xb8, 0xd3, 0xb6,
+	0x00, 0x88, 0x00, 0x80, 0x00, 0xa5,
+};
+
+static const unsigned char s6e8ax0_22_gamma_120[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb9, 0x95, 0xc8, 0xb1, 0xcf,
+	0xb2, 0xc6, 0xdf, 0xc5, 0x9b, 0xc3, 0x99, 0xb6, 0xd2, 0xb6,
+	0x00, 0x8f, 0x00, 0x86, 0x00, 0xac,
+};
+
+static const unsigned char s6e8ax0_22_gamma_130[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb7, 0xa0, 0xc7, 0xb1, 0xd0,
+	0xb2, 0xc4, 0xdd, 0xc3, 0x9a, 0xc3, 0x98, 0xb6, 0xd0, 0xb4,
+	0x00, 0x92, 0x00, 0x8a, 0x00, 0xb1,
+};
+
+static const unsigned char s6e8ax0_22_gamma_140[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb7, 0xa0, 0xc5, 0xb2, 0xd0,
+	0xb3, 0xc3, 0xde, 0xc3, 0x9b, 0xc2, 0x98, 0xb6, 0xd0, 0xb4,
+	0x00, 0x95, 0x00, 0x8d, 0x00, 0xb5,
+};
+
+static const unsigned char s6e8ax0_22_gamma_150[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xa0, 0xc2, 0xb2, 0xd0,
+	0xb2, 0xc1, 0xdd, 0xc2, 0x9b, 0xc2, 0x98, 0xb4, 0xcf, 0xb1,
+	0x00, 0x99, 0x00, 0x90, 0x00, 0xba,
+};
+
+static const unsigned char s6e8ax0_22_gamma_160[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xa5, 0xbf, 0xb0, 0xd0,
+	0xb1, 0xc3, 0xde, 0xc2, 0x99, 0xc1, 0x97, 0xb4, 0xce, 0xb1,
+	0x00, 0x9c, 0x00, 0x93, 0x00, 0xbe,
+};
+
+static const unsigned char s6e8ax0_22_gamma_170[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb5, 0xbf, 0xb1, 0xd1,
+	0xb1, 0xc3, 0xde, 0xc3, 0x99, 0xc0, 0x96, 0xb4, 0xce, 0xb1,
+	0x00, 0x9f, 0x00, 0x96, 0x00, 0xc2,
+};
+
+static const unsigned char s6e8ax0_22_gamma_180[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb7, 0xbe, 0xb3, 0xd2,
+	0xb3, 0xc3, 0xde, 0xc2, 0x97, 0xbf, 0x95, 0xb4, 0xcd, 0xb1,
+	0x00, 0xa2, 0x00, 0x99, 0x00, 0xc5,
+};
+
+static const unsigned char s6e8ax0_22_gamma_190[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb9, 0xbe, 0xb2, 0xd2,
+	0xb2, 0xc3, 0xdd, 0xc3, 0x98, 0xbf, 0x95, 0xb2, 0xcc, 0xaf,
+	0x00, 0xa5, 0x00, 0x9c, 0x00, 0xc9,
+};
+
+static const unsigned char s6e8ax0_22_gamma_200[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb9, 0xbc, 0xb2, 0xd2,
+	0xb1, 0xc4, 0xdd, 0xc3, 0x97, 0xbe, 0x95, 0xb1, 0xcb, 0xae,
+	0x00, 0xa8, 0x00, 0x9f, 0x00, 0xcd,
+};
+
+static const unsigned char s6e8ax0_22_gamma_210[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc1, 0xbd, 0xb1, 0xd1,
+	0xb1, 0xc2, 0xde, 0xc2, 0x97, 0xbe, 0x94, 0xB0, 0xc9, 0xad,
+	0x00, 0xae, 0x00, 0xa4, 0x00, 0xd4,
+};
+
+static const unsigned char s6e8ax0_22_gamma_220[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc7, 0xbd, 0xb1, 0xd1,
+	0xb1, 0xc2, 0xdd, 0xc2, 0x97, 0xbd, 0x94, 0xb0, 0xc9, 0xad,
+	0x00, 0xad, 0x00, 0xa2, 0x00, 0xd3,
+};
+
+static const unsigned char s6e8ax0_22_gamma_230[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc3, 0xbd, 0xb2, 0xd1,
+	0xb1, 0xc3, 0xdd, 0xc1, 0x96, 0xbd, 0x94, 0xb0, 0xc9, 0xad,
+	0x00, 0xb0, 0x00, 0xa7, 0x00, 0xd7,
+};
+
+static const unsigned char s6e8ax0_22_gamma_240[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xcb, 0xbd, 0xb1, 0xd2,
+	0xb1, 0xc3, 0xdD, 0xc2, 0x95, 0xbd, 0x93, 0xaf, 0xc8, 0xab,
+	0x00, 0xb3, 0x00, 0xa9, 0x00, 0xdb,
+};
+
+static const unsigned char s6e8ax0_22_gamma_250[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xcc, 0xbe, 0xb0, 0xd2,
+	0xb0, 0xc3, 0xdD, 0xc2, 0x94, 0xbc, 0x92, 0xae, 0xc8, 0xab,
+	0x00, 0xb6, 0x00, 0xab, 0x00, 0xde,
+};
+
+static const unsigned char s6e8ax0_22_gamma_260[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xd0, 0xbe, 0xaf, 0xd1,
+	0xaf, 0xc2, 0xdd, 0xc1, 0x96, 0xbc, 0x93, 0xaf, 0xc8, 0xac,
+	0x00, 0xb7, 0x00, 0xad, 0x00, 0xe0,
+};
+
+static const unsigned char s6e8ax0_22_gamma_270[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb2, 0xcF, 0xbd, 0xb0, 0xd2,
+	0xaf, 0xc2, 0xdc, 0xc1, 0x95, 0xbd, 0x93, 0xae, 0xc6, 0xaa,
+	0x00, 0xba, 0x00, 0xb0, 0x00, 0xe4,
+};
+
+static const unsigned char s6e8ax0_22_gamma_280[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb2, 0xd0, 0xbd, 0xaf, 0xd0,
+	0xad, 0xc4, 0xdd, 0xc3, 0x95, 0xbd, 0x93, 0xac, 0xc5, 0xa9,
+	0x00, 0xbd, 0x00, 0xb2, 0x00, 0xe7,
+};
+
+static const unsigned char s6e8ax0_22_gamma_300[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb5, 0xd3, 0xbd, 0xb1, 0xd2,
+	0xb0, 0xc0, 0xdc, 0xc0, 0x94, 0xba, 0x91, 0xac, 0xc5, 0xa9,
+	0x00, 0xc2, 0x00, 0xb7, 0x00, 0xed,
+};
+
+static const unsigned char *s6e8ax0_22_gamma_table[] = {
+	s6e8ax0_22_gamma_30,
+	s6e8ax0_22_gamma_50,
+	s6e8ax0_22_gamma_60,
+	s6e8ax0_22_gamma_70,
+	s6e8ax0_22_gamma_80,
+	s6e8ax0_22_gamma_90,
+	s6e8ax0_22_gamma_100,
+	s6e8ax0_22_gamma_120,
+	s6e8ax0_22_gamma_130,
+	s6e8ax0_22_gamma_140,
+	s6e8ax0_22_gamma_150,
+	s6e8ax0_22_gamma_160,
+	s6e8ax0_22_gamma_170,
+	s6e8ax0_22_gamma_180,
+	s6e8ax0_22_gamma_190,
+	s6e8ax0_22_gamma_200,
+	s6e8ax0_22_gamma_210,
+	s6e8ax0_22_gamma_220,
+	s6e8ax0_22_gamma_230,
+	s6e8ax0_22_gamma_240,
+	s6e8ax0_22_gamma_250,
+	s6e8ax0_22_gamma_260,
+	s6e8ax0_22_gamma_270,
+	s6e8ax0_22_gamma_280,
+	s6e8ax0_22_gamma_300,
+};
+
+static void s6e8ax0_panel_cond(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+
+	static const unsigned char data_to_send[] = {
+		0xf8, 0x3d, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3c, 0x7d,
+		0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08,
+		0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xc0,
+		0xc8, 0x08, 0x48, 0xc1, 0x00, 0xc1, 0xff, 0xff, 0xc8
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_display_cond(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xf2, 0x80, 0x03, 0x0d
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+/* Gamma 2.2 Setting (200cd, 7500K, 10MPCD) */
+static void s6e8ax0_gamma_cond(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	unsigned int gamma = lcd->bd->props.brightness;
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+			s6e8ax0_22_gamma_table[gamma],
+			GAMMA_TABLE_COUNT);
+}
+
+static void s6e8ax0_gamma_update(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xf7, 0x03
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE_PARAM, data_to_send,
+		ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond1(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xd1, 0xfe, 0x80, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x40,
+		0x0d, 0x00, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond2(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0,
+		0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond3(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xe1, 0x10, 0x1c, 0x17, 0x08, 0x1d
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond4(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xe2, 0xed, 0x07, 0xc3, 0x13, 0x0d, 0x03
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond5(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x19, 0x33, 0x02
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+static void s6e8ax0_etc_cond6(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xe3, 0x40
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE_PARAM,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond7(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xe4, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_elvss_set(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xb1, 0x04, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_elvss_nvm_set(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xd9, 0x5c, 0x20, 0x0c, 0x0f, 0x41, 0x00, 0x10, 0x11,
+		0x12, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcb, 0xed,
+		0x64, 0xaf
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_sleep_in(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0x10, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_sleep_out(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0x11, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_display_on(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0x29, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_display_off(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0x28, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_apply_level2_key(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xf0, 0x5a, 0x5a
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_acl_on(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xc0, 0x01
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_acl_off(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xc0, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+/* Full white 50% reducing setting */
+static void s6e8ax0_acl_ctrl_set(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	/* Full white 50% reducing setting */
+	static const unsigned char cutoff_50[] = {
+		0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
+		0x00, 0x00, 0x04, 0xff,	0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x08, 0x0f, 0x16, 0x1d, 0x24, 0x2a, 0x31, 0x38,
+		0x3f, 0x46
+	};
+	/* Full white 45% reducing setting */
+	static const unsigned char cutoff_45[] = {
+		0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
+		0x00, 0x00, 0x04, 0xff,	0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x07, 0x0d, 0x13, 0x19, 0x1f, 0x25, 0x2b, 0x31,
+		0x37, 0x3d
+	};
+	/* Full white 40% reducing setting */
+	static const unsigned char cutoff_40[] = {
+		0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
+		0x00, 0x00, 0x04, 0xff,	0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x06, 0x0c, 0x11, 0x16, 0x1c, 0x21, 0x26, 0x2b,
+		0x31, 0x36
+	};
+
+	if (lcd->acl_enable) {
+		if (lcd->cur_acl == 0) {
+			if (lcd->gamma == 0 || lcd->gamma == 1) {
+				s6e8ax0_acl_off(lcd);
+				dev_dbg(&lcd->ld->dev,
+					"cur_acl=%d\n", lcd->cur_acl);
+			} else
+				s6e8ax0_acl_on(lcd);
+		}
+		switch (lcd->gamma) {
+		case 0: /* 30cd */
+			s6e8ax0_acl_off(lcd);
+			lcd->cur_acl = 0;
+			break;
+		case 1 ... 3: /* 50cd ~ 90cd */
+			ops->cmd_write(lcd_to_master(lcd),
+				MIPI_DSI_DCS_LONG_WRITE,
+				cutoff_40,
+				ARRAY_SIZE(cutoff_40));
+			lcd->cur_acl = 40;
+			break;
+		case 4 ... 7: /* 120cd ~ 210cd */
+			ops->cmd_write(lcd_to_master(lcd),
+				MIPI_DSI_DCS_LONG_WRITE,
+				cutoff_45,
+				ARRAY_SIZE(cutoff_45));
+			lcd->cur_acl = 45;
+			break;
+		case 8 ... 10: /* 220cd ~ 300cd */
+			ops->cmd_write(lcd_to_master(lcd),
+				MIPI_DSI_DCS_LONG_WRITE,
+				cutoff_50,
+				ARRAY_SIZE(cutoff_50));
+			lcd->cur_acl = 50;
+			break;
+		default:
+			break;
+		}
+	} else {
+		s6e8ax0_acl_off(lcd);
+		lcd->cur_acl = 0;
+		dev_dbg(&lcd->ld->dev, "cur_acl = %d\n", lcd->cur_acl);
+	}
+}
+
+static void s6e8ax0_read_id(struct s6e8ax0 *lcd, u8 *mtp_id)
+{
+	unsigned int ret;
+	unsigned int addr = 0xd1;	/* MTP ID */
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+
+	ret = ops->cmd_read(lcd_to_master(lcd),
+			MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM,
+			addr, 3, mtp_id);
+}
+
+static int s6e8ax0_panel_init(struct s6e8ax0 *lcd)
+{
+	s6e8ax0_apply_level2_key(lcd);
+	s6e8ax0_sleep_out(lcd);
+	msleep(1);
+	s6e8ax0_panel_cond(lcd);
+	s6e8ax0_display_cond(lcd);
+	s6e8ax0_gamma_cond(lcd);
+	s6e8ax0_gamma_update(lcd);
+
+	s6e8ax0_etc_cond1(lcd);
+	s6e8ax0_etc_cond2(lcd);
+	s6e8ax0_etc_cond3(lcd);
+	s6e8ax0_etc_cond4(lcd);
+	s6e8ax0_etc_cond5(lcd);
+	s6e8ax0_etc_cond6(lcd);
+	s6e8ax0_etc_cond7(lcd);
+
+	s6e8ax0_elvss_nvm_set(lcd);
+	s6e8ax0_elvss_set(lcd);
+
+	s6e8ax0_acl_ctrl_set(lcd);
+	s6e8ax0_acl_on(lcd);
+
+	/* if ID3 value is not 33h, branch private elvss mode */
+	msleep(lcd->ddi_pd->power_on_delay);
+
+	return 0;
+}
+
+static int s6e8ax0_update_gamma_ctrl(struct s6e8ax0 *lcd, int brightness)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+			s6e8ax0_22_gamma_table[brightness],
+			ARRAY_SIZE(s6e8ax0_22_gamma_table));
+
+	/* update gamma table. */
+	s6e8ax0_gamma_update(lcd);
+	lcd->gamma = brightness;
+
+	return 0;
+}
+
+static int s6e8ax0_gamma_ctrl(struct s6e8ax0 *lcd, int gamma)
+{
+	s6e8ax0_update_gamma_ctrl(lcd, gamma);
+
+	return 0;
+}
+
+static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+{
+	struct s6e8ax0 *lcd = lcd_get_data(ld);
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	int ret = 0;
+
+	if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+			power != FB_BLANK_NORMAL) {
+		dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
+		return -EINVAL;
+	}
+
+	if ((power == FB_BLANK_UNBLANK) && ops->set_blank_mode) {
+		/* LCD power on */
+		if ((POWER_IS_ON(power) && POWER_IS_OFF(lcd->power))
+			|| (POWER_IS_ON(power) && POWER_IS_NRM(lcd->power))) {
+			ret = ops->set_blank_mode(lcd_to_master(lcd), power);
+			if (!ret && lcd->power != power)
+				lcd->power = power;
+		}
+	} else if ((power == FB_BLANK_POWERDOWN) && ops->set_early_blank_mode) {
+		/* LCD power off */
+		if ((POWER_IS_OFF(power) && POWER_IS_ON(lcd->power)) ||
+		(POWER_IS_ON(lcd->power) && POWER_IS_NRM(power))) {
+			ret = ops->set_early_blank_mode(lcd_to_master(lcd),
+							power);
+			if (!ret && lcd->power != power)
+				lcd->power = power;
+		}
+	}
+
+	return ret;
+}
+
+static int s6e8ax0_get_power(struct lcd_device *ld)
+{
+	struct s6e8ax0 *lcd = lcd_get_data(ld);
+
+	return lcd->power;
+}
+
+static int s6e8ax0_get_brightness(struct backlight_device *bd)
+{
+	return bd->props.brightness;
+}
+
+static int s6e8ax0_set_brightness(struct backlight_device *bd)
+{
+	int ret = 0, brightness = bd->props.brightness;
+	struct s6e8ax0 *lcd = bl_get_data(bd);
+
+	if (brightness < MIN_BRIGHTNESS ||
+		brightness > bd->props.max_brightness) {
+		dev_err(lcd->dev, "lcd brightness should be %d to %d.\n",
+			MIN_BRIGHTNESS, MAX_BRIGHTNESS);
+		return -EINVAL;
+	}
+
+	ret = s6e8ax0_gamma_ctrl(lcd, brightness);
+	if (ret) {
+		dev_err(&bd->dev, "lcd brightness setting failed.\n");
+		return -EIO;
+	}
+
+	return ret;
+}
+
+static struct lcd_ops s6e8ax0_lcd_ops = {
+	.set_power = s6e8ax0_set_power,
+	.get_power = s6e8ax0_get_power,
+};
+
+static const struct backlight_ops s6e8ax0_backlight_ops = {
+	.get_brightness = s6e8ax0_get_brightness,
+	.update_status = s6e8ax0_set_brightness,
+};
+
+static void s6e8ax0_power_on(struct mipi_dsim_lcd_device *dsim_dev, int power)
+{
+	struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+
+	msleep(lcd->ddi_pd->power_on_delay);
+
+	/* lcd power on */
+	if (power)
+		s6e8ax0_regulator_enable(lcd);
+	else
+		s6e8ax0_regulator_disable(lcd);
+
+	msleep(lcd->ddi_pd->reset_delay);
+
+	/* lcd reset */
+	if (lcd->ddi_pd->reset)
+		lcd->ddi_pd->reset(lcd->ld);
+	msleep(5);
+}
+
+static void s6e8ax0_set_sequence(struct mipi_dsim_lcd_device *dsim_dev)
+{
+	struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+
+	s6e8ax0_panel_init(lcd);
+	s6e8ax0_display_on(lcd);
+
+	lcd->power = FB_BLANK_UNBLANK;
+}
+
+static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
+{
+	struct s6e8ax0 *lcd;
+	int ret;
+	u8 mtp_id[3] = {0, };
+
+	lcd = kzalloc(sizeof(struct s6e8ax0), GFP_KERNEL);
+	if (!lcd) {
+		dev_err(&dsim_dev->dev, "failed to allocate s6e8ax0 structure.\n");
+		return -ENOMEM;
+	}
+
+	lcd->dsim_dev = dsim_dev;
+	lcd->ddi_pd = (struct lcd_platform_data *)dsim_dev->platform_data;
+	lcd->dev = &dsim_dev->dev;
+
+	mutex_init(&lcd->lock);
+
+	ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
+	if (ret) {
+		dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
+		goto err_lcd_register;
+	}
+
+	lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd,
+			&s6e8ax0_lcd_ops);
+	if (IS_ERR(lcd->ld)) {
+		dev_err(lcd->dev, "failed to register lcd ops.\n");
+		ret = PTR_ERR(lcd->ld);
+		goto err_lcd_register;
+	}
+
+	lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd,
+			&s6e8ax0_backlight_ops, NULL);
+	if (IS_ERR(lcd->bd)) {
+		dev_err(lcd->dev, "failed to register backlight ops.\n");
+		ret = PTR_ERR(lcd->bd);
+		goto err_backlight_register;
+	}
+
+	lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+	lcd->bd->props.brightness = MAX_BRIGHTNESS;
+
+	s6e8ax0_read_id(lcd, mtp_id);
+	if (mtp_id[0] == 0x00)
+		dev_err(lcd->dev, "read id failed\n");
+
+	dev_info(lcd->dev, "Read ID : %x, %x, %x\n",
+			mtp_id[0], mtp_id[1], mtp_id[2]);
+
+	if (mtp_id[2] == 0x33)
+		dev_info(lcd->dev,
+			"ID-3 is 0xff does not support dynamic elvss\n");
+	else
+		dev_info(lcd->dev,
+			"ID-3 is 0x%x support dynamic elvss\n", mtp_id[2]);
+
+	lcd->acl_enable = 1;
+	lcd->cur_acl = 0;
+
+	dev_set_drvdata(&dsim_dev->dev, lcd);
+
+	dev_dbg(lcd->dev, "probed s6e8ax0 panel driver.\n");
+
+	return 0;
+
+err_backlight_register:
+	lcd_device_unregister(lcd->ld);
+
+err_lcd_register:
+	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+	kfree(lcd);
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int s6e8ax0_suspend(struct mipi_dsim_lcd_device *dsim_dev)
+{
+	struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+
+	s6e8ax0_sleep_in(lcd);
+	msleep(lcd->ddi_pd->power_off_delay);
+	s6e8ax0_display_off(lcd);
+
+	s6e8ax0_regulator_disable(lcd);
+
+	return 0;
+}
+
+static int s6e8ax0_resume(struct mipi_dsim_lcd_device *dsim_dev)
+{
+	struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+
+	s6e8ax0_sleep_out(lcd);
+	msleep(lcd->ddi_pd->power_on_delay);
+
+	s6e8ax0_regulator_enable(lcd);
+	s6e8ax0_set_sequence(dsim_dev);
+
+	return 0;
+}
+#else
+#define s6e8ax0_suspend		NULL
+#define s6e8ax0_resume		NULL
+#endif
+
+static struct mipi_dsim_lcd_driver s6e8ax0_dsim_ddi_driver = {
+	.name = "s6e8ax0",
+	.id = -1,
+
+	.power_on = s6e8ax0_power_on,
+	.set_sequence = s6e8ax0_set_sequence,
+	.probe = s6e8ax0_probe,
+	.suspend = s6e8ax0_suspend,
+	.resume = s6e8ax0_resume,
+};
+
+static int s6e8ax0_init(void)
+{
+	exynos_mipi_dsi_register_lcd_driver(&s6e8ax0_dsim_ddi_driver);
+
+	return 0;
+}
+
+static void s6e8ax0_exit(void)
+{
+	return;
+}
+
+module_init(s6e8ax0_init);
+module_exit(s6e8ax0_exit);
+
+MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
+MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("MIPI-DSI based s6e8ax0 AMOLED LCD Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/s6e8ax0.h b/drivers/video/exynos/s6e8ax0.h
new file mode 100644
index 0000000..1f1b270
--- /dev/null
+++ b/drivers/video/exynos/s6e8ax0.h
@@ -0,0 +1,21 @@
+/* linux/drivers/video/backlight/s6e8ax0.h
+ *
+ * MIPI-DSI based s6e8ax0 AMOLED LCD Panel definitions.
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * Inki Dae, <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * 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 _S6E8AX0_H
+#define _S6E8AX0_H
+
+extern void s6e8ax0_init(void);
+
+#endif
+
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index ac9141b..c6ce416 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1665,6 +1665,7 @@
 	if (ret)
 		return -EINVAL;
 
+	unlink_framebuffer(fb_info);
 	if (fb_info->pixmap.addr &&
 	    (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
 		kfree(fb_info->pixmap.addr);
@@ -1672,7 +1673,6 @@
 	registered_fb[i] = NULL;
 	num_registered_fb--;
 	fb_cleanup_device(fb_info);
-	device_destroy(fb_class, MKDEV(FB_MAJOR, i));
 	event.info = fb_info;
 	fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
 
@@ -1681,6 +1681,22 @@
 	return 0;
 }
 
+int unlink_framebuffer(struct fb_info *fb_info)
+{
+	int i;
+
+	i = fb_info->node;
+	if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
+		return -EINVAL;
+
+	if (fb_info->dev) {
+		device_destroy(fb_class, MKDEV(FB_MAJOR, i));
+		fb_info->dev = NULL;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(unlink_framebuffer);
+
 void remove_conflicting_framebuffers(struct apertures_struct *a,
 				     const char *name, bool primary)
 {
diff --git a/drivers/video/i740_reg.h b/drivers/video/i740_reg.h
new file mode 100644
index 0000000..91bac76
--- /dev/null
+++ b/drivers/video/i740_reg.h
@@ -0,0 +1,309 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <kevin@precisioninsight.com>
+ */
+
+/* I/O register offsets */
+#define SRX VGA_SEQ_I
+#define GRX VGA_GFX_I
+#define ARX VGA_ATT_IW
+#define XRX 0x3D6
+#define MRX 0x3D2
+
+/* VGA Color Palette Registers */
+#define DACMASK		0x3C6
+#define DACSTATE	0x3C7
+#define DACRX		0x3C7
+#define DACWX		0x3C8
+#define DACDATA		0x3C9
+
+/* CRT Controller Registers (CRX) */
+#define START_ADDR_HI		0x0C
+#define START_ADDR_LO		0x0D
+#define VERT_SYNC_END		0x11
+#define EXT_VERT_TOTAL		0x30
+#define EXT_VERT_DISPLAY	0x31
+#define EXT_VERT_SYNC_START	0x32
+#define EXT_VERT_BLANK_START	0x33
+#define EXT_HORIZ_TOTAL		0x35
+#define EXT_HORIZ_BLANK		0x39
+#define EXT_START_ADDR		0x40
+#define EXT_START_ADDR_ENABLE	0x80
+#define EXT_OFFSET		0x41
+#define EXT_START_ADDR_HI	0x42
+#define INTERLACE_CNTL		0x70
+#define INTERLACE_ENABLE	0x80
+#define INTERLACE_DISABLE	0x00
+
+/* Miscellaneous Output Register */
+#define MSR_R		0x3CC
+#define MSR_W		0x3C2
+#define IO_ADDR_SELECT	0x01
+
+#define MDA_BASE	0x3B0
+#define CGA_BASE	0x3D0
+
+/* System Configuration Extension Registers (XRX) */
+#define IO_CTNL		0x09
+#define EXTENDED_ATTR_CNTL	0x02
+#define EXTENDED_CRTC_CNTL	0x01
+
+#define ADDRESS_MAPPING	0x0A
+#define PACKED_MODE_ENABLE	0x04
+#define LINEAR_MODE_ENABLE	0x02
+#define PAGE_MAPPING_ENABLE	0x01
+
+#define BITBLT_CNTL	0x20
+#define COLEXP_MODE		0x30
+#define COLEXP_8BPP		0x00
+#define COLEXP_16BPP		0x10
+#define COLEXP_24BPP		0x20
+#define COLEXP_RESERVED		0x30
+#define CHIP_RESET		0x02
+#define BITBLT_STATUS		0x01
+
+#define DISPLAY_CNTL	0x40
+#define VGA_WRAP_MODE		0x02
+#define VGA_WRAP_AT_256KB	0x00
+#define VGA_NO_WRAP		0x02
+#define GUI_MODE		0x01
+#define STANDARD_VGA_MODE	0x00
+#define HIRES_MODE		0x01
+
+#define DRAM_ROW_TYPE	0x50
+#define DRAM_ROW_0		0x07
+#define DRAM_ROW_0_SDRAM	0x00
+#define DRAM_ROW_0_EMPTY	0x07
+#define DRAM_ROW_1		0x38
+#define DRAM_ROW_1_SDRAM	0x00
+#define DRAM_ROW_1_EMPTY	0x38
+#define DRAM_ROW_CNTL_LO 0x51
+#define DRAM_CAS_LATENCY	0x10
+#define DRAM_RAS_TIMING		0x08
+#define DRAM_RAS_PRECHARGE	0x04
+#define DRAM_ROW_CNTL_HI 0x52
+#define DRAM_EXT_CNTL	0x53
+#define DRAM_REFRESH_RATE	0x03
+#define DRAM_REFRESH_DISABLE	0x00
+#define DRAM_REFRESH_60HZ	0x01
+#define DRAM_REFRESH_FAST_TEST	0x02
+#define DRAM_REFRESH_RESERVED	0x03
+#define DRAM_TIMING	0x54
+#define DRAM_ROW_BNDRY_0 0x55
+#define DRAM_ROW_BNDRY_1 0x56
+
+#define DPMS_SYNC_SELECT 0x61
+#define VSYNC_CNTL		0x08
+#define VSYNC_ON		0x00
+#define VSYNC_OFF		0x08
+#define HSYNC_CNTL		0x02
+#define HSYNC_ON		0x00
+#define HSYNC_OFF		0x02
+
+#define PIXPIPE_CONFIG_0 0x80
+#define DAC_8_BIT		0x80
+#define DAC_6_BIT		0x00
+#define HW_CURSOR_ENABLE	0x10
+#define EXTENDED_PALETTE	0x01
+
+#define PIXPIPE_CONFIG_1 0x81
+#define DISPLAY_COLOR_MODE	0x0F
+#define DISPLAY_VGA_MODE	0x00
+#define DISPLAY_8BPP_MODE	0x02
+#define DISPLAY_15BPP_MODE	0x04
+#define DISPLAY_16BPP_MODE	0x05
+#define DISPLAY_24BPP_MODE	0x06
+#define DISPLAY_32BPP_MODE	0x07
+
+#define PIXPIPE_CONFIG_2 0x82
+#define DISPLAY_GAMMA_ENABLE	0x08
+#define DISPLAY_GAMMA_DISABLE	0x00
+#define OVERLAY_GAMMA_ENABLE	0x04
+#define OVERLAY_GAMMA_DISABLE	0x00
+
+#define CURSOR_CONTROL	0xA0
+#define CURSOR_ORIGIN_SCREEN	0x00
+#define CURSOR_ORIGIN_DISPLAY	0x10
+#define CURSOR_MODE		0x07
+#define CURSOR_MODE_DISABLE	0x00
+#define CURSOR_MODE_32_4C_AX	0x01
+#define CURSOR_MODE_128_2C	0x02
+#define CURSOR_MODE_128_1C	0x03
+#define CURSOR_MODE_64_3C	0x04
+#define CURSOR_MODE_64_4C_AX	0x05
+#define CURSOR_MODE_64_4C	0x06
+#define CURSOR_MODE_RESERVED	0x07
+#define CURSOR_BASEADDR_LO 0xA2
+#define CURSOR_BASEADDR_HI 0xA3
+#define CURSOR_X_LO	0xA4
+#define CURSOR_X_HI	0xA5
+#define CURSOR_X_POS		0x00
+#define CURSOR_X_NEG		0x80
+#define CURSOR_Y_LO	0xA6
+#define CURSOR_Y_HI	0xA7
+#define CURSOR_Y_POS		0x00
+#define CURSOR_Y_NEG		0x80
+
+#define VCLK2_VCO_M	0xC8
+#define VCLK2_VCO_N	0xC9
+#define VCLK2_VCO_MN_MSBS 0xCA
+#define VCO_N_MSBS		0x30
+#define VCO_M_MSBS		0x03
+#define VCLK2_VCO_DIV_SEL 0xCB
+#define POST_DIV_SELECT		0x70
+#define POST_DIV_1		0x00
+#define POST_DIV_2		0x10
+#define POST_DIV_4		0x20
+#define POST_DIV_8		0x30
+#define POST_DIV_16		0x40
+#define POST_DIV_32		0x50
+#define VCO_LOOP_DIV_BY_4M	0x00
+#define VCO_LOOP_DIV_BY_16M	0x04
+#define REF_CLK_DIV_BY_5	0x02
+#define REF_DIV_4		0x00
+#define REF_DIV_1		0x01
+
+#define PLL_CNTL	0xCE
+#define PLL_MEMCLK_SEL		0x03
+#define PLL_MEMCLK__66667KHZ	0x00
+#define PLL_MEMCLK__75000KHZ	0x01
+#define PLL_MEMCLK__88889KHZ	0x02
+#define PLL_MEMCLK_100000KHZ	0x03
+
+/* Multimedia Extension Registers (MRX) */
+#define ACQ_CNTL_1	0x02
+#define ACQ_CNTL_2	0x03
+#define FRAME_CAP_MODE		0x01
+#define CONT_CAP_MODE		0x00
+#define SINGLE_CAP_MODE		0x01
+#define ACQ_CNTL_3	0x04
+#define COL_KEY_CNTL_1		0x3C
+#define BLANK_DISP_OVERLAY	0x20
+
+/* FIFOs */
+#define LP_FIFO		0x1000
+#define HP_FIFO		0x2000
+#define INSTPNT		0x3040
+#define LP_FIFO_COUNT	0x3040
+#define HP_FIFO_COUNT	0x3041
+
+/* FIFO Commands */
+#define CLIENT		0xE0000000
+#define CLIENT_2D	0x60000000
+
+/* Command Parser Mode Register */
+#define COMPARS		0x3038
+#define TWO_D_INST_DISABLE		0x08
+#define THREE_D_INST_DISABLE		0x04
+#define STATE_VAR_UPDATE_DISABLE	0x02
+#define PAL_STIP_DISABLE		0x01
+
+/* Interrupt Control Registers */
+#define IER		0x3030
+#define IIR		0x3032
+#define IMR		0x3034
+#define ISR		0x3036
+#define VMIINTB_EVENT		0x2000
+#define GPIO4_INT		0x1000
+#define DISP_FLIP_EVENT		0x0800
+#define DVD_PORT_DMA		0x0400
+#define DISP_VBLANK		0x0200
+#define FIFO_EMPTY_DMA_DONE	0x0100
+#define INST_PARSER_ERROR	0x0080
+#define USER_DEFINED		0x0040
+#define BREAKPOINT		0x0020
+#define DISP_HORIZ_COUNT	0x0010
+#define DISP_VSYNC		0x0008
+#define CAPTURE_HORIZ_COUNT	0x0004
+#define CAPTURE_VSYNC		0x0002
+#define THREE_D_PIPE_FLUSHED	0x0001
+
+/* FIFO Watermark and Burst Length Control Register */
+#define FWATER_BLC	0x00006000
+#define LMI_BURST_LENGTH	0x7F000000
+#define LMI_FIFO_WATERMARK	0x003F0000
+#define AGP_BURST_LENGTH	0x00007F00
+#define AGP_FIFO_WATERMARK	0x0000003F
+
+/* BitBLT Registers */
+#define SRC_DST_PITCH	0x00040000
+#define DST_PITCH		0x1FFF0000
+#define SRC_PITCH		0x00001FFF
+#define COLEXP_BG_COLOR	0x00040004
+#define COLEXP_FG_COLOR	0x00040008
+#define MONO_SRC_CNTL	0x0004000C
+#define MONO_USE_COLEXP		0x00000000
+#define MONO_USE_SRCEXP		0x08000000
+#define MONO_DATA_ALIGN		0x07000000
+#define MONO_BIT_ALIGN		0x01000000
+#define MONO_BYTE_ALIGN		0x02000000
+#define MONO_WORD_ALIGN		0x03000000
+#define MONO_DWORD_ALIGN	0x04000000
+#define MONO_QWORD_ALIGN	0x05000000
+#define MONO_SRC_INIT_DSCRD	0x003F0000
+#define MONO_SRC_RIGHT_CLIP	0x00003F00
+#define MONO_SRC_LEFT_CLIP	0x0000003F
+#define BITBLT_CONTROL	0x00040010
+#define BLTR_STATUS		0x80000000
+#define DYN_DEPTH		0x03000000
+#define DYN_DEPTH_8BPP		0x00000000
+#define DYN_DEPTH_16BPP		0x01000000
+#define DYN_DEPTH_24BPP		0x02000000
+#define DYN_DEPTH_32BPP		0x03000000	/* Unimplemented on the i740 */
+#define DYN_DEPTH_ENABLE	0x00800000
+#define PAT_VERT_ALIGN		0x00700000
+#define SOLID_PAT_SELECT	0x00080000
+#define PAT_IS_IN_COLOR		0x00000000
+#define PAT_IS_MONO		0x00040000
+#define MONO_PAT_TRANSP		0x00020000
+#define COLOR_TRANSP_ROP	0x00000000
+#define COLOR_TRANSP_DST	0x00008000
+#define COLOR_TRANSP_EQ		0x00000000
+#define COLOR_TRANSP_NOT_EQ	0x00010000
+#define COLOR_TRANSP_ENABLE	0x00004000
+#define MONO_SRC_TRANSP		0x00002000
+#define SRC_IS_IN_COLOR		0x00000000
+#define SRC_IS_MONO		0x00001000
+#define SRC_USE_SRC_ADDR	0x00000000
+#define SRC_USE_BLTDATA		0x00000400
+#define BLT_TOP_TO_BOT		0x00000000
+#define BLT_BOT_TO_TOP		0x00000200
+#define BLT_LEFT_TO_RIGHT	0x00000000
+#define BLT_RIGHT_TO_LEFT	0x00000100
+#define BLT_ROP			0x000000FF
+#define BLT_PAT_ADDR	0x00040014
+#define BLT_SRC_ADDR	0x00040018
+#define BLT_DST_ADDR	0x0004001C
+#define BLT_DST_H_W	0x00040020
+#define BLT_DST_HEIGHT		0x1FFF0000
+#define BLT_DST_WIDTH		0x00001FFF
+#define SRCEXP_BG_COLOR	0x00040024
+#define SRCEXP_FG_COLOR	0x00040028
+#define BLTDATA		0x00050000
diff --git a/drivers/video/i740fb.c b/drivers/video/i740fb.c
new file mode 100644
index 0000000..fe574d8
--- /dev/null
+++ b/drivers/video/i740fb.c
@@ -0,0 +1,1337 @@
+/*
+ * i740fb - framebuffer driver for Intel740
+ * Copyright (c) 2011 Ondrej Zary
+ *
+ * Based on old i740fb driver (c) 2001-2002 Andrey Ulanov <drey@rt.mipt.ru>
+ * which was partially based on:
+ *  VGA 16-color framebuffer driver (c) 1999 Ben Pfaff <pfaffben@debian.org>
+ *	and Petr Vandrovec <VANDROVE@vc.cvut.cz>
+ *  i740 driver from XFree86 (c) 1998-1999 Precision Insight, Inc., Cedar Park,
+ *	Texas.
+ *  i740fb by Patrick LERDA, v0.9
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/console.h>
+#include <video/vga.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include "i740_reg.h"
+
+static char *mode_option __devinitdata;
+
+#ifdef CONFIG_MTRR
+static int mtrr __devinitdata = 1;
+#endif
+
+struct i740fb_par {
+	unsigned char __iomem *regs;
+	bool has_sgram;
+#ifdef CONFIG_MTRR
+	int mtrr_reg;
+#endif
+	bool ddc_registered;
+	struct i2c_adapter ddc_adapter;
+	struct i2c_algo_bit_data ddc_algo;
+	u32 pseudo_palette[16];
+	struct mutex open_lock;
+	unsigned int ref_count;
+
+	u8 crtc[VGA_CRT_C];
+	u8 atc[VGA_ATT_C];
+	u8 gdc[VGA_GFX_C];
+	u8 seq[VGA_SEQ_C];
+	u8 misc;
+	u8 vss;
+
+	/* i740 specific registers */
+	u8 display_cntl;
+	u8 pixelpipe_cfg0;
+	u8 pixelpipe_cfg1;
+	u8 pixelpipe_cfg2;
+	u8 video_clk2_m;
+	u8 video_clk2_n;
+	u8 video_clk2_mn_msbs;
+	u8 video_clk2_div_sel;
+	u8 pll_cntl;
+	u8 address_mapping;
+	u8 io_cntl;
+	u8 bitblt_cntl;
+	u8 ext_vert_total;
+	u8 ext_vert_disp_end;
+	u8 ext_vert_sync_start;
+	u8 ext_vert_blank_start;
+	u8 ext_horiz_total;
+	u8 ext_horiz_blank;
+	u8 ext_offset;
+	u8 interlace_cntl;
+	u32 lmi_fifo_watermark;
+	u8 ext_start_addr;
+	u8 ext_start_addr_hi;
+};
+
+#define DACSPEED8	203
+#define DACSPEED16	163
+#define DACSPEED24_SG	136
+#define DACSPEED24_SD	128
+#define DACSPEED32	86
+
+static struct fb_fix_screeninfo i740fb_fix __devinitdata = {
+	.id =		"i740fb",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_TRUECOLOR,
+	.xpanstep =	8,
+	.ypanstep =	1,
+	.accel =	FB_ACCEL_NONE,
+};
+
+static inline void i740outb(struct i740fb_par *par, u16 port, u8 val)
+{
+	vga_mm_w(par->regs, port, val);
+}
+static inline u8 i740inb(struct i740fb_par *par, u16 port)
+{
+	return vga_mm_r(par->regs, port);
+}
+static inline void i740outreg(struct i740fb_par *par, u16 port, u8 reg, u8 val)
+{
+	vga_mm_w_fast(par->regs, port, reg, val);
+}
+static inline u8 i740inreg(struct i740fb_par *par, u16 port, u8 reg)
+{
+	vga_mm_w(par->regs, port, reg);
+	return vga_mm_r(par->regs, port+1);
+}
+static inline void i740outreg_mask(struct i740fb_par *par, u16 port, u8 reg,
+				   u8 val, u8 mask)
+{
+	vga_mm_w_fast(par->regs, port, reg, (val & mask)
+		| (i740inreg(par, port, reg) & ~mask));
+}
+
+#define REG_DDC_DRIVE	0x62
+#define REG_DDC_STATE	0x63
+#define DDC_SCL		(1 << 3)
+#define DDC_SDA		(1 << 2)
+
+static void i740fb_ddc_setscl(void *data, int val)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, DDC_SCL, DDC_SCL);
+	i740outreg_mask(par, XRX, REG_DDC_STATE, val ? DDC_SCL : 0, DDC_SCL);
+}
+
+static void i740fb_ddc_setsda(void *data, int val)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, DDC_SDA, DDC_SDA);
+	i740outreg_mask(par, XRX, REG_DDC_STATE, val ? DDC_SDA : 0, DDC_SDA);
+}
+
+static int i740fb_ddc_getscl(void *data)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, 0, DDC_SCL);
+
+	return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SCL);
+}
+
+static int i740fb_ddc_getsda(void *data)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, 0, DDC_SDA);
+
+	return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SDA);
+}
+
+static int __devinit i740fb_setup_ddc_bus(struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+
+	strlcpy(par->ddc_adapter.name, info->fix.id,
+		sizeof(par->ddc_adapter.name));
+	par->ddc_adapter.owner		= THIS_MODULE;
+	par->ddc_adapter.class		= I2C_CLASS_DDC;
+	par->ddc_adapter.algo_data	= &par->ddc_algo;
+	par->ddc_adapter.dev.parent	= info->device;
+	par->ddc_algo.setsda		= i740fb_ddc_setsda;
+	par->ddc_algo.setscl		= i740fb_ddc_setscl;
+	par->ddc_algo.getsda		= i740fb_ddc_getsda;
+	par->ddc_algo.getscl		= i740fb_ddc_getscl;
+	par->ddc_algo.udelay		= 10;
+	par->ddc_algo.timeout		= 20;
+	par->ddc_algo.data		= par;
+
+	i2c_set_adapdata(&par->ddc_adapter, par);
+
+	return i2c_bit_add_bus(&par->ddc_adapter);
+}
+
+static int i740fb_open(struct fb_info *info, int user)
+{
+	struct i740fb_par *par = info->par;
+
+	mutex_lock(&(par->open_lock));
+	par->ref_count++;
+	mutex_unlock(&(par->open_lock));
+
+	return 0;
+}
+
+static int i740fb_release(struct fb_info *info, int user)
+{
+	struct i740fb_par *par = info->par;
+
+	mutex_lock(&(par->open_lock));
+	if (par->ref_count == 0) {
+		printk(KERN_ERR "fb%d: release called with zero refcount\n",
+			info->node);
+		mutex_unlock(&(par->open_lock));
+		return -EINVAL;
+	}
+
+	par->ref_count--;
+	mutex_unlock(&(par->open_lock));
+
+	return 0;
+}
+
+static u32 i740_calc_fifo(struct i740fb_par *par, u32 freq, int bpp)
+{
+	/*
+	 * Would like to calculate these values automatically, but a generic
+	 * algorithm does not seem possible.  Note: These FIFO water mark
+	 * values were tested on several cards and seem to eliminate the
+	 * all of the snow and vertical banding, but fine adjustments will
+	 * probably be required for other cards.
+	 */
+
+	u32 wm;
+
+	switch (bpp) {
+	case 8:
+		if	(freq > 200)
+			wm = 0x18120000;
+		else if (freq > 175)
+			wm = 0x16110000;
+		else if (freq > 135)
+			wm = 0x120E0000;
+		else
+			wm = 0x100D0000;
+		break;
+	case 15:
+	case 16:
+		if (par->has_sgram) {
+			if	(freq > 140)
+				wm = 0x2C1D0000;
+			else if (freq > 120)
+				wm = 0x2C180000;
+			else if (freq > 100)
+				wm = 0x24160000;
+			else if (freq >  90)
+				wm = 0x18120000;
+			else if (freq >  50)
+				wm = 0x16110000;
+			else if (freq >  32)
+				wm = 0x13100000;
+			else
+				wm = 0x120E0000;
+		} else {
+			if	(freq > 160)
+				wm = 0x28200000;
+			else if (freq > 140)
+				wm = 0x2A1E0000;
+			else if (freq > 130)
+				wm = 0x2B1A0000;
+			else if (freq > 120)
+				wm = 0x2C180000;
+			else if (freq > 100)
+				wm = 0x24180000;
+			else if (freq >  90)
+				wm = 0x18120000;
+			else if (freq >  50)
+				wm = 0x16110000;
+			else if (freq >  32)
+				wm = 0x13100000;
+			else
+				wm = 0x120E0000;
+		}
+		break;
+	case 24:
+		if (par->has_sgram) {
+			if	(freq > 130)
+				wm = 0x31200000;
+			else if (freq > 120)
+				wm = 0x2E200000;
+			else if (freq > 100)
+				wm = 0x2C1D0000;
+			else if (freq >  80)
+				wm = 0x25180000;
+			else if (freq >  64)
+				wm = 0x24160000;
+			else if (freq >  49)
+				wm = 0x18120000;
+			else if (freq >  32)
+				wm = 0x16110000;
+			else
+				wm = 0x13100000;
+		} else {
+			if	(freq > 120)
+				wm = 0x311F0000;
+			else if (freq > 100)
+				wm = 0x2C1D0000;
+			else if (freq >  80)
+				wm = 0x25180000;
+			else if (freq >  64)
+				wm = 0x24160000;
+			else if (freq >  49)
+				wm = 0x18120000;
+			else if (freq >  32)
+				wm = 0x16110000;
+			else
+				wm = 0x13100000;
+		}
+		break;
+	case 32:
+		if (par->has_sgram) {
+			if	(freq >  80)
+				wm = 0x2A200000;
+			else if (freq >  60)
+				wm = 0x281A0000;
+			else if (freq >  49)
+				wm = 0x25180000;
+			else if (freq >  32)
+				wm = 0x18120000;
+			else
+				wm = 0x16110000;
+		} else {
+			if	(freq >  80)
+				wm = 0x29200000;
+			else if (freq >  60)
+				wm = 0x281A0000;
+			else if (freq >  49)
+				wm = 0x25180000;
+			else if (freq >  32)
+				wm = 0x18120000;
+			else
+				wm = 0x16110000;
+		}
+		break;
+	}
+
+	return wm;
+}
+
+/* clock calculation from i740fb by Patrick LERDA */
+
+#define I740_RFREQ		1000000
+#define TARGET_MAX_N		30
+#define I740_FFIX		(1 << 8)
+#define I740_RFREQ_FIX		(I740_RFREQ / I740_FFIX)
+#define I740_REF_FREQ		(6667 * I740_FFIX / 100)	/* 66.67 MHz */
+#define I740_MAX_VCO_FREQ	(450 * I740_FFIX)		/* 450 MHz */
+
+static void i740_calc_vclk(u32 freq, struct i740fb_par *par)
+{
+	const u32 err_max    = freq / (200  * I740_RFREQ / I740_FFIX);
+	const u32 err_target = freq / (1000 * I740_RFREQ / I740_FFIX);
+	u32 err_best = 512 * I740_FFIX;
+	u32 f_err, f_vco;
+	int m_best = 0, n_best = 0, p_best = 0, d_best = 0;
+	int m, n;
+
+	p_best = min(15, ilog2(I740_MAX_VCO_FREQ / (freq / I740_RFREQ_FIX)));
+	d_best = 0;
+	f_vco = (freq * (1 << p_best)) / I740_RFREQ_FIX;
+	freq = freq / I740_RFREQ_FIX;
+
+	n = 2;
+	do {
+		n++;
+		m = ((f_vco * n) / I740_REF_FREQ + 2) / 4;
+
+		if (m < 3)
+			m = 3;
+
+		{
+			u32 f_out = (((m * I740_REF_FREQ * (4 << 2 * d_best))
+				 / n) + ((1 << p_best) / 2)) / (1 << p_best);
+
+			f_err = (freq - f_out);
+
+			if (abs(f_err) < err_max) {
+				m_best = m;
+				n_best = n;
+				err_best = f_err;
+			}
+		}
+	} while ((abs(f_err) >= err_target) &&
+		 ((n <= TARGET_MAX_N) || (abs(err_best) > err_max)));
+
+	if (abs(f_err) < err_target) {
+		m_best = m;
+		n_best = n;
+	}
+
+	par->video_clk2_m = (m_best - 2) & 0xFF;
+	par->video_clk2_n = (n_best - 2) & 0xFF;
+	par->video_clk2_mn_msbs = ((((n_best - 2) >> 4) & VCO_N_MSBS)
+				 | (((m_best - 2) >> 8) & VCO_M_MSBS));
+	par->video_clk2_div_sel =
+		((p_best << 4) | (d_best ? 4 : 0) | REF_DIV_1);
+}
+
+static int i740fb_decode_var(const struct fb_var_screeninfo *var,
+			     struct i740fb_par *par, struct fb_info *info)
+{
+	/*
+	 * Get the video params out of 'var'.
+	 * If a value doesn't fit, round it up, if it's too big, return -EINVAL.
+	 */
+
+	u32 xres, right, hslen, left, xtotal;
+	u32 yres, lower, vslen, upper, ytotal;
+	u32 vxres, xoffset, vyres, yoffset;
+	u32 bpp, base, dacspeed24, mem;
+	u8 r7;
+	int i;
+
+	dev_dbg(info->device, "decode_var: xres: %i, yres: %i, xres_v: %i, xres_v: %i\n",
+		  var->xres, var->yres, var->xres_virtual, var->xres_virtual);
+	dev_dbg(info->device, "	xoff: %i, yoff: %i, bpp: %i, graysc: %i\n",
+		  var->xoffset, var->yoffset, var->bits_per_pixel,
+		  var->grayscale);
+	dev_dbg(info->device, "	activate: %i, nonstd: %i, vmode: %i\n",
+		  var->activate, var->nonstd, var->vmode);
+	dev_dbg(info->device, "	pixclock: %i, hsynclen:%i, vsynclen:%i\n",
+		  var->pixclock, var->hsync_len, var->vsync_len);
+	dev_dbg(info->device, "	left: %i, right: %i, up:%i, lower:%i\n",
+		  var->left_margin, var->right_margin, var->upper_margin,
+		  var->lower_margin);
+
+
+	bpp = var->bits_per_pixel;
+	switch (bpp) {
+	case 1 ... 8:
+		bpp = 8;
+		if ((1000000 / var->pixclock) > DACSPEED8) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 8bpp)\n",
+				1000000 / var->pixclock, DACSPEED8);
+			return -EINVAL;
+		}
+		break;
+	case 9 ... 15:
+		bpp = 15;
+	case 16:
+		if ((1000000 / var->pixclock) > DACSPEED16) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 15/16bpp)\n",
+				1000000 / var->pixclock, DACSPEED16);
+			return -EINVAL;
+		}
+		break;
+	case 17 ... 24:
+		bpp = 24;
+		dacspeed24 = par->has_sgram ? DACSPEED24_SG : DACSPEED24_SD;
+		if ((1000000 / var->pixclock) > dacspeed24) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 24bpp)\n",
+				1000000 / var->pixclock, dacspeed24);
+			return -EINVAL;
+		}
+		break;
+	case 25 ... 32:
+		bpp = 32;
+		if ((1000000 / var->pixclock) > DACSPEED32) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 32bpp)\n",
+				1000000 / var->pixclock, DACSPEED32);
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	xres = ALIGN(var->xres, 8);
+	vxres = ALIGN(var->xres_virtual, 16);
+	if (vxres < xres)
+		vxres = xres;
+
+	xoffset = ALIGN(var->xoffset, 8);
+	if (xres + xoffset > vxres)
+		xoffset = vxres - xres;
+
+	left = ALIGN(var->left_margin, 8);
+	right = ALIGN(var->right_margin, 8);
+	hslen = ALIGN(var->hsync_len, 8);
+
+	yres = var->yres;
+	vyres = var->yres_virtual;
+	if (yres > vyres)
+		vyres = yres;
+
+	yoffset = var->yoffset;
+	if (yres + yoffset > vyres)
+		yoffset = vyres - yres;
+
+	lower = var->lower_margin;
+	vslen = var->vsync_len;
+	upper = var->upper_margin;
+
+	mem = vxres * vyres * ((bpp + 1) / 8);
+	if (mem > info->screen_size) {
+		dev_err(info->device, "not enough video memory (%d KB requested, %ld KB avaliable)\n",
+			mem >> 10, info->screen_size >> 10);
+		return -ENOMEM;
+	}
+
+	if (yoffset + yres > vyres)
+		yoffset = vyres - yres;
+
+	xtotal = xres + right + hslen + left;
+	ytotal = yres + lower + vslen + upper;
+
+	par->crtc[VGA_CRTC_H_TOTAL] = (xtotal >> 3) - 5;
+	par->crtc[VGA_CRTC_H_DISP] = (xres >> 3) - 1;
+	par->crtc[VGA_CRTC_H_BLANK_START] = ((xres + right) >> 3) - 1;
+	par->crtc[VGA_CRTC_H_SYNC_START] = (xres + right) >> 3;
+	par->crtc[VGA_CRTC_H_SYNC_END] = (((xres + right + hslen) >> 3) & 0x1F)
+		| ((((xres + right + hslen) >> 3) & 0x20) << 2);
+	par->crtc[VGA_CRTC_H_BLANK_END] = ((xres + right + hslen) >> 3 & 0x1F)
+		| 0x80;
+
+	par->crtc[VGA_CRTC_V_TOTAL] = ytotal - 2;
+
+	r7 = 0x10;	/* disable linecompare */
+	if (ytotal & 0x100)
+		r7 |= 0x01;
+	if (ytotal & 0x200)
+		r7 |= 0x20;
+
+	par->crtc[VGA_CRTC_PRESET_ROW] = 0;
+	par->crtc[VGA_CRTC_MAX_SCAN] = 0x40;	/* 1 scanline, no linecmp */
+	if (var->vmode & FB_VMODE_DOUBLE)
+		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
+	par->crtc[VGA_CRTC_CURSOR_START] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_END] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_HI] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_LO] = 0x00;
+	par->crtc[VGA_CRTC_V_DISP_END] = yres-1;
+	if ((yres-1) & 0x100)
+		r7 |= 0x02;
+	if ((yres-1) & 0x200)
+		r7 |= 0x40;
+
+	par->crtc[VGA_CRTC_V_BLANK_START] = yres + lower - 1;
+	par->crtc[VGA_CRTC_V_SYNC_START] = yres + lower - 1;
+	if ((yres + lower - 1) & 0x100)
+		r7 |= 0x0C;
+	if ((yres + lower - 1) & 0x200) {
+		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20;
+		r7 |= 0x80;
+	}
+
+	/* disabled IRQ */
+	par->crtc[VGA_CRTC_V_SYNC_END] =
+		((yres + lower - 1 + vslen) & 0x0F) & ~0x10;
+	/* 0x7F for VGA, but some SVGA chips require all 8 bits to be set */
+	par->crtc[VGA_CRTC_V_BLANK_END] = (yres + lower - 1 + vslen) & 0xFF;
+
+	par->crtc[VGA_CRTC_UNDERLINE] = 0x00;
+	par->crtc[VGA_CRTC_MODE] = 0xC3 ;
+	par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
+	par->crtc[VGA_CRTC_OVERFLOW] = r7;
+
+	par->vss = 0x00;	/* 3DA */
+
+	for (i = 0x00; i < 0x10; i++)
+		par->atc[i] = i;
+	par->atc[VGA_ATC_MODE] = 0x81;
+	par->atc[VGA_ATC_OVERSCAN] = 0x00;	/* 0 for EGA, 0xFF for VGA */
+	par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
+	par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
+
+	par->misc = 0xC3;
+	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+		par->misc &= ~0x40;
+	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+		par->misc &= ~0x80;
+
+	par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
+	par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
+	par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
+	par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
+
+	par->gdc[VGA_GFX_SR_VALUE] = 0x00;
+	par->gdc[VGA_GFX_SR_ENABLE] = 0x00;
+	par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
+	par->gdc[VGA_GFX_DATA_ROTATE] = 0x00;
+	par->gdc[VGA_GFX_PLANE_READ] = 0;
+	par->gdc[VGA_GFX_MODE] = 0x02;
+	par->gdc[VGA_GFX_MISC] = 0x05;
+	par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
+	par->gdc[VGA_GFX_BIT_MASK] = 0xFF;
+
+	base = (yoffset * vxres + (xoffset & ~7)) >> 2;
+	switch (bpp) {
+	case 8:
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 3;
+		par->ext_offset = vxres >> 11;
+		par->pixelpipe_cfg1 = DISPLAY_8BPP_MODE;
+		par->bitblt_cntl = COLEXP_8BPP;
+		break;
+	case 15: /* 0rrrrrgg gggbbbbb */
+	case 16: /* rrrrrggg gggbbbbb */
+		par->pixelpipe_cfg1 = (var->green.length == 6) ?
+			DISPLAY_16BPP_MODE : DISPLAY_15BPP_MODE;
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 2;
+		par->ext_offset = vxres >> 10;
+		par->bitblt_cntl = COLEXP_16BPP;
+		base *= 2;
+		break;
+	case 24:
+		par->crtc[VGA_CRTC_OFFSET] = (vxres * 3) >> 3;
+		par->ext_offset = (vxres * 3) >> 11;
+		par->pixelpipe_cfg1 = DISPLAY_24BPP_MODE;
+		par->bitblt_cntl = COLEXP_24BPP;
+		base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+		base *= 3;
+		break;
+	case 32:
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
+		par->ext_offset = vxres >> 9;
+		par->pixelpipe_cfg1 = DISPLAY_32BPP_MODE;
+		par->bitblt_cntl = COLEXP_RESERVED; /* Unimplemented on i740 */
+		base *= 4;
+		break;
+	}
+
+	par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+	par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >>  8;
+	par->ext_start_addr =
+		((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+	par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+
+	par->pixelpipe_cfg0 = DAC_8_BIT;
+
+	par->pixelpipe_cfg2 = DISPLAY_GAMMA_ENABLE | OVERLAY_GAMMA_ENABLE;
+	par->io_cntl = EXTENDED_CRTC_CNTL;
+	par->address_mapping = LINEAR_MODE_ENABLE | PAGE_MAPPING_ENABLE;
+	par->display_cntl = HIRES_MODE;
+
+	/* Set the MCLK freq */
+	par->pll_cntl = PLL_MEMCLK_100000KHZ; /* 100 MHz -- use as default */
+
+	/* Calculate the extended CRTC regs */
+	par->ext_vert_total = (ytotal - 2) >> 8;
+	par->ext_vert_disp_end = (yres - 1) >> 8;
+	par->ext_vert_sync_start = (yres + lower) >> 8;
+	par->ext_vert_blank_start = (yres + lower) >> 8;
+	par->ext_horiz_total = ((xtotal >> 3) - 5) >> 8;
+	par->ext_horiz_blank = (((xres + right) >> 3) & 0x40) >> 6;
+
+	par->interlace_cntl = INTERLACE_DISABLE;
+
+	/* Set the overscan color to 0. (NOTE: This only affects >8bpp mode) */
+	par->atc[VGA_ATC_OVERSCAN] = 0;
+
+	/* Calculate VCLK that most closely matches the requested dot clock */
+	i740_calc_vclk((((u32)1e9) / var->pixclock) * (u32)(1e3), par);
+
+	/* Since we program the clocks ourselves, always use VCLK2. */
+	par->misc |= 0x0C;
+
+	/* Calculate the FIFO Watermark and Burst Length. */
+	par->lmi_fifo_watermark =
+		i740_calc_fifo(par, 1000000 / var->pixclock, bpp);
+
+	return 0;
+}
+
+static int i740fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset	= var->green.offset = var->blue.offset = 0;
+		var->red.length	= var->green.length = var->blue.length = 8;
+		break;
+	case 16:
+		switch (var->green.length) {
+		default:
+		case 5:
+			var->red.offset = 10;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length	= 5;
+			var->green.length = 5;
+			var->blue.length = 5;
+			break;
+		case 6:
+			var->red.offset = 11;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length = var->blue.length = 5;
+			break;
+		}
+		break;
+	case 24:
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length	= var->green.length = var->blue.length = 8;
+		break;
+	case 32:
+		var->transp.offset = 24;
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->transp.length = 8;
+		var->red.length = var->green.length = var->blue.length = 8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (var->xres > var->xres_virtual)
+		var->xres_virtual = var->xres;
+
+	if (var->yres > var->yres_virtual)
+		var->yres_virtual = var->yres;
+
+	if (info->monspecs.hfmax && info->monspecs.vfmax &&
+	    info->monspecs.dclkmax && fb_validate_mode(var, info) < 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void vga_protect(struct i740fb_par *par)
+{
+	/* disable the display */
+	i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0x20, 0x20);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, VGA_ATT_W, 0x00);	/* enable pallete access */
+}
+
+static void vga_unprotect(struct i740fb_par *par)
+{
+	/* reenable display */
+	i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0, 0x20);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, VGA_ATT_W, 0x20);	/* disable pallete access */
+}
+
+static int i740fb_set_par(struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+	u32 itemp;
+	int i;
+
+	i = i740fb_decode_var(&info->var, par, info);
+	if (i)
+		return i;
+
+	memset(info->screen_base, 0, info->screen_size);
+
+	vga_protect(par);
+
+	i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_DISABLE);
+
+	mdelay(1);
+
+	i740outreg(par, XRX, VCLK2_VCO_M, par->video_clk2_m);
+	i740outreg(par, XRX, VCLK2_VCO_N, par->video_clk2_n);
+	i740outreg(par, XRX, VCLK2_VCO_MN_MSBS, par->video_clk2_mn_msbs);
+	i740outreg(par, XRX, VCLK2_VCO_DIV_SEL, par->video_clk2_div_sel);
+
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0,
+			par->pixelpipe_cfg0 & DAC_8_BIT, 0x80);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, 0x3C0, 0x00);
+
+	/* update misc output register */
+	i740outb(par, VGA_MIS_W, par->misc | 0x01);
+
+	/* synchronous reset on */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x01);
+	/* write sequencer registers */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE,
+			par->seq[VGA_SEQ_CLOCK_MODE] | 0x20);
+	for (i = 2; i < VGA_SEQ_C; i++)
+		i740outreg(par, VGA_SEQ_I, i, par->seq[i]);
+
+	/* synchronous reset off */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x03);
+
+	/* deprotect CRT registers 0-7 */
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_V_SYNC_END,
+			par->crtc[VGA_CRTC_V_SYNC_END]);
+
+	/* write CRT registers */
+	for (i = 0; i < VGA_CRT_C; i++)
+		i740outreg(par, VGA_CRT_IC, i, par->crtc[i]);
+
+	/* write graphics controller registers */
+	for (i = 0; i < VGA_GFX_C; i++)
+		i740outreg(par, VGA_GFX_I, i, par->gdc[i]);
+
+	/* write attribute controller registers */
+	for (i = 0; i < VGA_ATT_C; i++) {
+		i740inb(par, VGA_IS1_RC);		/* reset flip-flop */
+		i740outb(par, VGA_ATT_IW, i);
+		i740outb(par, VGA_ATT_IW, par->atc[i]);
+	}
+
+	i740inb(par, VGA_IS1_RC);
+	i740outb(par, VGA_ATT_IW, 0x20);
+
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_TOTAL, par->ext_vert_total);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_DISPLAY, par->ext_vert_disp_end);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_SYNC_START,
+			par->ext_vert_sync_start);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_BLANK_START,
+			par->ext_vert_blank_start);
+	i740outreg(par, VGA_CRT_IC, EXT_HORIZ_TOTAL, par->ext_horiz_total);
+	i740outreg(par, VGA_CRT_IC, EXT_HORIZ_BLANK, par->ext_horiz_blank);
+	i740outreg(par, VGA_CRT_IC, EXT_OFFSET, par->ext_offset);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI, par->ext_start_addr_hi);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR, par->ext_start_addr);
+
+	i740outreg_mask(par, VGA_CRT_IC, INTERLACE_CNTL,
+			par->interlace_cntl, INTERLACE_ENABLE);
+	i740outreg_mask(par, XRX, ADDRESS_MAPPING, par->address_mapping, 0x1F);
+	i740outreg_mask(par, XRX, BITBLT_CNTL, par->bitblt_cntl, COLEXP_MODE);
+	i740outreg_mask(par, XRX, DISPLAY_CNTL,
+			par->display_cntl, VGA_WRAP_MODE | GUI_MODE);
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0, par->pixelpipe_cfg0, 0x9B);
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_2, par->pixelpipe_cfg2, 0x0C);
+
+	i740outreg(par, XRX, PLL_CNTL, par->pll_cntl);
+
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_1,
+			par->pixelpipe_cfg1, DISPLAY_COLOR_MODE);
+
+	itemp = readl(par->regs + FWATER_BLC);
+	itemp &= ~(LMI_BURST_LENGTH | LMI_FIFO_WATERMARK);
+	itemp |= par->lmi_fifo_watermark;
+	writel(itemp, par->regs + FWATER_BLC);
+
+	i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_60HZ);
+
+	i740outreg_mask(par, MRX, COL_KEY_CNTL_1, 0, BLANK_DISP_OVERLAY);
+	i740outreg_mask(par, XRX, IO_CTNL,
+			par->io_cntl, EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL);
+
+	if (par->pixelpipe_cfg1 != DISPLAY_8BPP_MODE) {
+		i740outb(par, VGA_PEL_MSK, 0xFF);
+		i740outb(par, VGA_PEL_IW, 0x00);
+		for (i = 0; i < 256; i++) {
+			itemp = (par->pixelpipe_cfg0 & DAC_8_BIT) ? i : i >> 2;
+			i740outb(par, VGA_PEL_D, itemp);
+			i740outb(par, VGA_PEL_D, itemp);
+			i740outb(par, VGA_PEL_D, itemp);
+		}
+	}
+
+	/* Wait for screen to stabilize. */
+	mdelay(50);
+	vga_unprotect(par);
+
+	info->fix.line_length =
+			info->var.xres_virtual * info->var.bits_per_pixel / 8;
+	if (info->var.bits_per_pixel == 8)
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+	else
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	return 0;
+}
+
+static int i740fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	u32 r, g, b;
+
+	dev_dbg(info->device, "setcolreg: regno: %i, red=%d, green=%d, blue=%d, transp=%d, bpp=%d\n",
+		regno, red, green, blue, transp, info->var.bits_per_pixel);
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_PSEUDOCOLOR:
+		if (regno >= 256)
+			return -EINVAL;
+		i740outb(info->par, VGA_PEL_IW, regno);
+		i740outb(info->par, VGA_PEL_D, red >> 8);
+		i740outb(info->par, VGA_PEL_D, green >> 8);
+		i740outb(info->par, VGA_PEL_D, blue >> 8);
+		break;
+	case FB_VISUAL_TRUECOLOR:
+		if (regno >= 16)
+			return -EINVAL;
+		r = (red >> (16 - info->var.red.length))
+			<< info->var.red.offset;
+		b = (blue >> (16 - info->var.blue.length))
+			<< info->var.blue.offset;
+		g = (green >> (16 - info->var.green.length))
+			<< info->var.green.offset;
+		((u32 *) info->pseudo_palette)[regno] = r | g | b;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int i740fb_pan_display(struct fb_var_screeninfo *var,
+				 struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+	u32 base = (var->yoffset * info->var.xres_virtual
+		 + (var->xoffset & ~7)) >> 2;
+
+	dev_dbg(info->device, "pan_display: xoffset: %i yoffset: %i base: %i\n",
+		var->xoffset, var->yoffset, base);
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		break;
+	case 15:
+	case 16:
+		base *= 2;
+		break;
+	case 24:
+		/*
+		 * The last bit does not seem to have any effect on the start
+		 * address register in 24bpp mode, so...
+		 */
+		base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+		base *= 3;
+		break;
+	case 32:
+		base *= 4;
+		break;
+	}
+
+	par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+	par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >>  8;
+	par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+	par->ext_start_addr =
+			((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_LO,  base & 0x000000FF);
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_HI,
+			(base & 0x0000FF00) >> 8);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI,
+			(base & 0x3FC00000) >> 22);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR,
+			((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE);
+
+	return 0;
+}
+
+static int i740fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+
+	unsigned char SEQ01;
+	int DPMSSyncSelect;
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+	case FB_BLANK_NORMAL:
+		SEQ01 = 0x00;
+		DPMSSyncSelect = HSYNC_ON | VSYNC_ON;
+		break;
+	case FB_BLANK_VSYNC_SUSPEND:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_ON | VSYNC_OFF;
+		break;
+	case FB_BLANK_HSYNC_SUSPEND:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_OFF | VSYNC_ON;
+		break;
+	case FB_BLANK_POWERDOWN:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_OFF | VSYNC_OFF;
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* Turn the screen on/off */
+	i740outb(par, SRX, 0x01);
+	SEQ01 |= i740inb(par, SRX + 1) & ~0x20;
+	i740outb(par, SRX, 0x01);
+	i740outb(par, SRX + 1, SEQ01);
+
+	/* Set the DPMS mode */
+	i740outreg(par, XRX, DPMS_SYNC_SELECT, DPMSSyncSelect);
+
+	/* Let fbcon do a soft blank for us */
+	return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
+}
+
+static struct fb_ops i740fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_open	= i740fb_open,
+	.fb_release	= i740fb_release,
+	.fb_check_var	= i740fb_check_var,
+	.fb_set_par	= i740fb_set_par,
+	.fb_setcolreg	= i740fb_setcolreg,
+	.fb_blank	= i740fb_blank,
+	.fb_pan_display	= i740fb_pan_display,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static int __devinit i740fb_probe(struct pci_dev *dev,
+				  const struct pci_device_id *ent)
+{
+	struct fb_info *info;
+	struct i740fb_par *par;
+	int ret, tmp;
+	bool found = false;
+	u8 *edid;
+
+	info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev));
+	if (!info) {
+		dev_err(&(dev->dev), "cannot allocate framebuffer\n");
+		return -ENOMEM;
+	}
+
+	par = info->par;
+	mutex_init(&par->open_lock);
+
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->var.bits_per_pixel = 8;
+	info->fbops = &i740fb_ops;
+	info->pseudo_palette = par->pseudo_palette;
+
+	ret = pci_enable_device(dev);
+	if (ret) {
+		dev_err(info->device, "cannot enable PCI device\n");
+		goto err_enable_device;
+	}
+
+	ret = pci_request_regions(dev, info->fix.id);
+	if (ret) {
+		dev_err(info->device, "error requesting regions\n");
+		goto err_request_regions;
+	}
+
+	info->screen_base = pci_ioremap_bar(dev, 0);
+	if (!info->screen_base) {
+		dev_err(info->device, "error remapping base\n");
+		ret = -ENOMEM;
+		goto err_ioremap_1;
+	}
+
+	par->regs = pci_ioremap_bar(dev, 1);
+	if (!par->regs) {
+		dev_err(info->device, "error remapping MMIO\n");
+		ret = -ENOMEM;
+		goto err_ioremap_2;
+	}
+
+	/* detect memory size */
+	if ((i740inreg(par, XRX, DRAM_ROW_TYPE) & DRAM_ROW_1)
+							== DRAM_ROW_1_SDRAM)
+		i740outb(par, XRX, DRAM_ROW_BNDRY_1);
+	else
+		i740outb(par, XRX, DRAM_ROW_BNDRY_0);
+	info->screen_size = i740inb(par, XRX + 1) * 1024 * 1024;
+	/* detect memory type */
+	tmp = i740inreg(par, XRX, DRAM_ROW_CNTL_LO);
+	par->has_sgram = !((tmp & DRAM_RAS_TIMING) ||
+			   (tmp & DRAM_RAS_PRECHARGE));
+
+	printk(KERN_INFO "fb%d: Intel740 on %s, %ld KB %s\n", info->node,
+		pci_name(dev), info->screen_size >> 10,
+		par->has_sgram ? "SGRAM" : "SDRAM");
+
+	info->fix = i740fb_fix;
+	info->fix.mmio_start = pci_resource_start(dev, 1);
+	info->fix.mmio_len = pci_resource_len(dev, 1);
+	info->fix.smem_start = pci_resource_start(dev, 0);
+	info->fix.smem_len = info->screen_size;
+	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+
+	if (i740fb_setup_ddc_bus(info) == 0) {
+		par->ddc_registered = true;
+		edid = fb_ddc_read(&par->ddc_adapter);
+		if (edid) {
+			fb_edid_to_monspecs(edid, &info->monspecs);
+			kfree(edid);
+			if (!info->monspecs.modedb)
+				dev_err(info->device,
+					"error getting mode database\n");
+			else {
+				const struct fb_videomode *m;
+
+				fb_videomode_to_modelist(
+					info->monspecs.modedb,
+					info->monspecs.modedb_len,
+					&info->modelist);
+				m = fb_find_best_display(&info->monspecs,
+							 &info->modelist);
+				if (m) {
+					fb_videomode_to_var(&info->var, m);
+					/* fill all other info->var's fields */
+					if (!i740fb_check_var(&info->var, info))
+						found = true;
+				}
+			}
+		}
+	}
+
+	if (!mode_option && !found)
+		mode_option = "640x480-8@60";
+
+	if (mode_option) {
+		ret = fb_find_mode(&info->var, info, mode_option,
+				   info->monspecs.modedb,
+				   info->monspecs.modedb_len,
+				   NULL, info->var.bits_per_pixel);
+		if (!ret || ret == 4) {
+			dev_err(info->device, "mode %s not found\n",
+				mode_option);
+			ret = -EINVAL;
+		}
+	}
+
+	fb_destroy_modedb(info->monspecs.modedb);
+	info->monspecs.modedb = NULL;
+
+	/* maximize virtual vertical size for fast scrolling */
+	info->var.yres_virtual = info->fix.smem_len * 8 /
+			(info->var.bits_per_pixel * info->var.xres_virtual);
+
+	if (ret == -EINVAL)
+		goto err_find_mode;
+
+	ret = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (ret) {
+		dev_err(info->device, "cannot allocate colormap\n");
+		goto err_alloc_cmap;
+	}
+
+	ret = register_framebuffer(info);
+	if (ret) {
+		dev_err(info->device, "error registering framebuffer\n");
+		goto err_reg_framebuffer;
+	}
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+		info->node, info->fix.id);
+	pci_set_drvdata(dev, info);
+#ifdef CONFIG_MTRR
+	if (mtrr) {
+		par->mtrr_reg = -1;
+		par->mtrr_reg = mtrr_add(info->fix.smem_start,
+				info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
+	}
+#endif
+	return 0;
+
+err_reg_framebuffer:
+	fb_dealloc_cmap(&info->cmap);
+err_alloc_cmap:
+err_find_mode:
+	if (par->ddc_registered)
+		i2c_del_adapter(&par->ddc_adapter);
+	pci_iounmap(dev, par->regs);
+err_ioremap_2:
+	pci_iounmap(dev, info->screen_base);
+err_ioremap_1:
+	pci_release_regions(dev);
+err_request_regions:
+/*	pci_disable_device(dev); */
+err_enable_device:
+	framebuffer_release(info);
+	return ret;
+}
+
+static void __devexit i740fb_remove(struct pci_dev *dev)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+
+	if (info) {
+		struct i740fb_par *par = info->par;
+
+#ifdef CONFIG_MTRR
+		if (par->mtrr_reg >= 0) {
+			mtrr_del(par->mtrr_reg, 0, 0);
+			par->mtrr_reg = -1;
+		}
+#endif
+		unregister_framebuffer(info);
+		fb_dealloc_cmap(&info->cmap);
+		if (par->ddc_registered)
+			i2c_del_adapter(&par->ddc_adapter);
+		pci_iounmap(dev, par->regs);
+		pci_iounmap(dev, info->screen_base);
+		pci_release_regions(dev);
+/*		pci_disable_device(dev); */
+		pci_set_drvdata(dev, NULL);
+		framebuffer_release(info);
+	}
+}
+
+#ifdef CONFIG_PM
+static int i740fb_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i740fb_par *par = info->par;
+
+	/* don't disable console during hibernation and wakeup from it */
+	if (state.event == PM_EVENT_FREEZE || state.event == PM_EVENT_PRETHAW)
+		return 0;
+
+	console_lock();
+	mutex_lock(&(par->open_lock));
+
+	/* do nothing if framebuffer is not active */
+	if (par->ref_count == 0) {
+		mutex_unlock(&(par->open_lock));
+		console_unlock();
+		return 0;
+	}
+
+	fb_set_suspend(info, 1);
+
+	pci_save_state(dev);
+	pci_disable_device(dev);
+	pci_set_power_state(dev, pci_choose_state(dev, state));
+
+	mutex_unlock(&(par->open_lock));
+	console_unlock();
+
+	return 0;
+}
+
+static int i740fb_resume(struct pci_dev *dev)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i740fb_par *par = info->par;
+
+	console_lock();
+	mutex_lock(&(par->open_lock));
+
+	if (par->ref_count == 0)
+		goto fail;
+
+	pci_set_power_state(dev, PCI_D0);
+	pci_restore_state(dev);
+	if (pci_enable_device(dev))
+		goto fail;
+
+	i740fb_set_par(info);
+	fb_set_suspend(info, 0);
+
+fail:
+	mutex_unlock(&(par->open_lock));
+	console_unlock();
+	return 0;
+}
+#else
+#define i740fb_suspend NULL
+#define i740fb_resume NULL
+#endif /* CONFIG_PM */
+
+#define I740_ID_PCI 0x00d1
+#define I740_ID_AGP 0x7800
+
+static DEFINE_PCI_DEVICE_TABLE(i740fb_id_table) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_PCI) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_AGP) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, i740fb_id_table);
+
+static struct pci_driver i740fb_driver = {
+	.name		= "i740fb",
+	.id_table	= i740fb_id_table,
+	.probe		= i740fb_probe,
+	.remove		= __devexit_p(i740fb_remove),
+	.suspend	= i740fb_suspend,
+	.resume		= i740fb_resume,
+};
+
+#ifndef MODULE
+static int  __init i740fb_setup(char *options)
+{
+	char *opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+#ifdef CONFIG_MTRR
+		else if (!strncmp(opt, "mtrr:", 5))
+			mtrr = simple_strtoul(opt + 5, NULL, 0);
+#endif
+		else
+			mode_option = opt;
+	}
+
+	return 0;
+}
+#endif
+
+int __init i740fb_init(void)
+{
+#ifndef MODULE
+	char *option = NULL;
+
+	if (fb_get_options("i740fb", &option))
+		return -ENODEV;
+	i740fb_setup(option);
+#endif
+
+	return pci_register_driver(&i740fb_driver);
+}
+
+static void __exit i740fb_exit(void)
+{
+	pci_unregister_driver(&i740fb_driver);
+}
+
+module_init(i740fb_init);
+module_exit(i740fb_exit);
+
+MODULE_AUTHOR("(c) 2011 Ondrej Zary <linux@rainbow-software.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("fbdev driver for Intel740");
+
+module_param(mode_option, charp, 0444);
+MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
+
+#ifdef CONFIG_MTRR
+module_param(mtrr, int, 0444);
+MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
+#endif
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index f239f4a..7fcd67e 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -155,14 +155,10 @@
 		ret = 0;
 		goto uninit;
 	}
-	ret = gpio_request(gpio, "vsync");
+	ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
 	if (ret)
 		goto err_request_gpio_failed;
 
-	ret = gpio_direction_input(gpio);
-	if (ret)
-		goto err_gpio_direction_input_failed;
-
 	ret = irq = gpio_to_irq(gpio);
 	if (ret < 0)
 		goto err_get_irq_num_failed;
@@ -180,7 +176,6 @@
 	free_irq(gpio_to_irq(gpio), panel->client_data);
 err_request_irq_failed:
 err_get_irq_num_failed:
-err_gpio_direction_input_failed:
 	gpio_free(gpio);
 err_request_gpio_failed:
 	return ret;
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
index f9bc932..053eb68 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -186,14 +186,10 @@
 		ret = 0;
 		goto uninit;
 	}
-	ret = gpio_request(gpio, "vsync");
+	ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
 	if (ret)
 		goto err_request_gpio_failed;
 
-	ret = gpio_direction_input(gpio);
-	if (ret)
-		goto err_gpio_direction_input_failed;
-
 	ret = irq = gpio_to_irq(gpio);
 	if (ret < 0)
 		goto err_get_irq_num_failed;
@@ -210,7 +206,6 @@
 	free_irq(gpio_to_irq(gpio), panel);
 err_request_irq_failed:
 err_get_irq_num_failed:
-err_gpio_direction_input_failed:
 	gpio_free(gpio);
 err_request_gpio_failed:
 	return ret;
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 7e8bd8e..e3d3d13 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <asm/gpio.h>
+#include <linux/gpio.h>
 #include "omapfb.h"
 
 #define MODULE_NAME	"omapfb-lcd_h3"
@@ -32,20 +32,18 @@
 {
 	int r = 0;
 
-	if (gpio_request(14, "lcd_en0")) {
+	/* configure GPIO(14, 15) as outputs */
+	if (gpio_request_one(14, GPIOF_OUT_INIT_LOW, "lcd_en0")) {
 		pr_err(MODULE_NAME ": can't request GPIO 14\n");
 		r = -1;
 		goto exit;
 	}
-	if (gpio_request(15, "lcd_en1")) {
+	if (gpio_request_one(15, GPIOF_OUT_INIT_LOW, "lcd_en1")) {
 		pr_err(MODULE_NAME ": can't request GPIO 15\n");
 		gpio_free(14);
 		r = -1;
 		goto exit;
 	}
-	/* configure GPIO(14, 15) as outputs */
-	gpio_direction_output(14, 0);
-	gpio_direction_output(15, 0);
 exit:
 	return r;
 }
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
index 8d546dd..e3880c4 100644
--- a/drivers/video/omap/lcd_mipid.c
+++ b/drivers/video/omap/lcd_mipid.c
@@ -609,19 +609,7 @@
 	.remove	= __devexit_p(mipid_spi_remove),
 };
 
-static int __init mipid_drv_init(void)
-{
-	spi_register_driver(&mipid_spi_driver);
-
-	return 0;
-}
-module_init(mipid_drv_init);
-
-static void __exit mipid_drv_cleanup(void)
-{
-	spi_unregister_driver(&mipid_spi_driver);
-}
-module_exit(mipid_drv_cleanup);
+module_spi_driver(mipid_spi_driver);
 
 MODULE_DESCRIPTION("MIPI display driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 74d29b5..408a992 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -12,7 +12,7 @@
 
 config PANEL_DVI
 	tristate "DVI output"
-	depends on OMAP2_DSS_DPI
+	depends on OMAP2_DSS_DPI && I2C
 	help
 	  Driver for external monitors, connected via DVI. The driver uses i2c
 	  to read EDID information from the monitor.
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 51a87e1..d26f37a 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -809,18 +809,7 @@
 	.remove	= __devexit_p(acx565akm_spi_remove),
 };
 
-static int __init acx565akm_init(void)
-{
-	return spi_register_driver(&acx565akm_spi_driver);
-}
-
-static void __exit acx565akm_exit(void)
-{
-	spi_unregister_driver(&acx565akm_spi_driver);
-}
-
-module_init(acx565akm_init);
-module_exit(acx565akm_exit);
+module_spi_driver(acx565akm_spi_driver);
 
 MODULE_AUTHOR("Nokia Corporation");
 MODULE_DESCRIPTION("acx565akm LCD Driver");
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index e0eb35b..0841cc2 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -264,16 +264,6 @@
 	.remove		= __devexit_p(lb035q02_panel_spi_remove),
 };
 
-static int __init lb035q02_panel_drv_init(void)
-{
-	return spi_register_driver(&lb035q02_spi_driver);
-}
+module_spi_driver(lb035q02_spi_driver);
 
-static void __exit lb035q02_panel_drv_exit(void)
-{
-	spi_unregister_driver(&lb035q02_spi_driver);
-}
-
-module_init(lb035q02_panel_drv_init);
-module_exit(lb035q02_panel_drv_exit);
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 0eb31ca..8b38b39 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -350,18 +350,8 @@
 	},
 };
 
-static int __init nec_8048_lcd_init(void)
-{
-	return spi_register_driver(&nec_8048_spi_driver);
-}
+module_spi_driver(nec_8048_spi_driver);
 
-static void __exit nec_8048_lcd_exit(void)
-{
-	return spi_unregister_driver(&nec_8048_spi_driver);
-}
-
-module_init(nec_8048_lcd_init);
-module_exit(nec_8048_lcd_exit);
 MODULE_AUTHOR("Erik Gilling <konkers@android.com>");
 MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 00c5c61..0f21fa5 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1019,14 +1019,12 @@
 	if (panel_data->use_ext_te) {
 		int gpio = panel_data->ext_te_gpio;
 
-		r = gpio_request(gpio, "taal irq");
+		r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
 		if (r) {
 			dev_err(&dssdev->dev, "GPIO request failed\n");
 			goto err_gpio;
 		}
 
-		gpio_direction_input(gpio);
-
 		r = request_irq(gpio_to_irq(gpio), taal_te_isr,
 				IRQF_TRIGGER_RISING,
 				"taal vsync", dssdev);
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index e6649aa..0ca9644 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -408,17 +408,12 @@
 	}
 
 	if (gpio_is_valid(nreset_gpio)) {
-		ret = gpio_request(nreset_gpio, "lcd reset");
+		ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW,
+					"lcd reset");
 		if (ret < 0) {
 			dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
 			goto fail_gpio_req;
 		}
-
-		ret = gpio_direction_output(nreset_gpio, 0);
-		if (ret < 0) {
-			dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
-			goto fail_gpio_direction;
-		}
 	}
 
 	ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
@@ -427,8 +422,6 @@
 
 	return 0;
 
-fail_gpio_direction:
-	gpio_free(nreset_gpio);
 fail_gpio_req:
 	regulator_put(tpo_td043->vcc_reg);
 fail_regulator:
@@ -518,18 +511,7 @@
 	.remove	= __devexit_p(tpo_td043_spi_remove),
 };
 
-static int __init tpo_td043_init(void)
-{
-	return spi_register_driver(&tpo_td043_spi_driver);
-}
-
-static void __exit tpo_td043_exit(void)
-{
-	spi_unregister_driver(&tpo_td043_spi_driver);
-}
-
-module_init(tpo_td043_init);
-module_exit(tpo_td043_exit);
+module_spi_driver(tpo_td043_spi_driver);
 
 MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
 MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 052dc87..87b3e25 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1276,6 +1276,9 @@
 
 	spin_unlock_irqrestore(&data_lock, flags);
 
+	/* wait for overlay to be enabled */
+	wait_pending_extra_info_updates();
+
 	mutex_unlock(&apply_lock);
 
 	return 0;
@@ -1313,6 +1316,9 @@
 
 	spin_unlock_irqrestore(&data_lock, flags);
 
+	/* wait for the overlay to be disabled */
+	wait_pending_extra_info_updates();
+
 	mutex_unlock(&apply_lock);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 395d658..faaf305 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -180,6 +180,11 @@
 {
 	int r;
 
+	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+		DSSERR("no VDSS_DSI regulator\n");
+		return -ENODEV;
+	}
+
 	if (dssdev->manager == NULL) {
 		DSSERR("failed to enable display: no manager\n");
 		return -ENODEV;
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index d7aa3b0..a36b934 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -165,9 +165,25 @@
 
 	DSSDBG("hdmi_runtime_get\n");
 
+	/*
+	 * HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled.
+	 * This should be removed later.
+	 */
+	r = dss_runtime_get();
+	if (r < 0)
+		goto err_get_dss;
+
 	r = pm_runtime_get_sync(&hdmi.pdev->dev);
 	WARN_ON(r < 0);
-	return r < 0 ? r : 0;
+	if (r < 0)
+		goto err_get_hdmi;
+
+	return 0;
+
+err_get_hdmi:
+	dss_runtime_put();
+err_get_dss:
+	return r;
 }
 
 static void hdmi_runtime_put(void)
@@ -178,6 +194,12 @@
 
 	r = pm_runtime_put_sync(&hdmi.pdev->dev);
 	WARN_ON(r < 0);
+
+	/*
+	 * HACK: This is added to complement the dss_runtime_get() call in
+	 * hdmi_runtime_get(). This should be removed later.
+	 */
+	dss_runtime_put();
 }
 
 int hdmi_init_display(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 2d72334..6847a47 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -479,14 +479,7 @@
 
 bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
 {
-	int r;
-
-	void __iomem *base = hdmi_core_sys_base(ip_data);
-
-	/* HPD */
-	r = REG_GET(base, HDMI_CORE_SYS_SYS_STAT, 1, 1);
-
-	return r == 1;
+	return gpio_get_value(ip_data->hpd_gpio);
 }
 
 static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index f997510..bcd44c3 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -895,7 +895,7 @@
 
 #ifdef CONFIG_PVR2_DMA
 	if (request_dma(pvr2dma, "pvr2") != 0) {
-		free_irq(HW_EVENT_VSYNC, 0);
+		free_irq(HW_EVENT_VSYNC, fb_info);
 		return -EBUSY;
 	}
 #endif
@@ -914,7 +914,7 @@
 		currentpar->mmio_base = 0;
 	}
 
-	free_irq(HW_EVENT_VSYNC, 0);
+	free_irq(HW_EVENT_VSYNC, fb_info);
 #ifdef CONFIG_PVR2_DMA
 	free_dma(pvr2dma);
 #endif
@@ -1061,7 +1061,7 @@
 	int (*init)(void);
 	void (*exit)(void);
 	char name[16];
-} board_driver[] = {
+} board_driver[] __refdata = {
 #ifdef CONFIG_SH_DREAMCAST
 	{ pvr2fb_dc_init, pvr2fb_dc_exit, "Sega DC PVR2" },
 #endif
diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c
index 8384b94..f146089 100644
--- a/drivers/video/pxa168fb.c
+++ b/drivers/video/pxa168fb.c
@@ -21,6 +21,7 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
@@ -670,7 +671,8 @@
 	/*
 	 * Map LCD controller registers.
 	 */
-	fbi->reg_base = ioremap_nocache(res->start, resource_size(res));
+	fbi->reg_base = devm_ioremap_nocache(&pdev->dev, res->start,
+					     resource_size(res));
 	if (fbi->reg_base == NULL) {
 		ret = -ENOMEM;
 		goto failed_free_info;
@@ -739,8 +741,8 @@
 	/*
 	 * Register irq handler.
 	 */
-	ret = request_irq(irq, pxa168fb_handle_irq, IRQF_SHARED,
-					info->fix.id, fbi);
+	ret = devm_request_irq(&pdev->dev, irq, pxa168fb_handle_irq,
+			       IRQF_SHARED, info->fix.id, fbi);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "unable to request IRQ\n");
 		ret = -ENXIO;
@@ -759,14 +761,12 @@
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to register pxa168-fb: %d\n", ret);
 		ret = -ENXIO;
-		goto failed_free_irq;
+		goto failed_free_cmap;
 	}
 
 	platform_set_drvdata(pdev, fbi);
 	return 0;
 
-failed_free_irq:
-	free_irq(irq, fbi);
 failed_free_cmap:
 	fb_dealloc_cmap(&info->cmap);
 failed_free_clk:
@@ -808,13 +808,10 @@
 		fb_dealloc_cmap(&info->cmap);
 
 	irq = platform_get_irq(pdev, 0);
-	free_irq(irq, fbi);
 
 	dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
 				info->screen_base, info->fix.smem_start);
 
-	iounmap(fbi->reg_base);
-
 	clk_disable(fbi->clk);
 	clk_put(fbi->clk);
 
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 1d1e4f1..c176561 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -54,6 +54,7 @@
 #include <linux/mutex.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/console.h>
 
 #include <mach/hardware.h>
 #include <asm/io.h>
@@ -730,9 +731,12 @@
 	if (user == 0)
 		return -ENODEV;
 
-	if (ofb->usage++ == 0)
+	if (ofb->usage++ == 0) {
 		/* unblank the base framebuffer */
+		console_lock();
 		fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
+		console_unlock();
+	}
 
 	return 0;
 }
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 2f58cf9..90df1a6 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1816,6 +1816,8 @@
 			     specs->modedb, specs->modedb_len,
 			     NULL, 8);
 	} else if (specs->modedb != NULL) {
+		/* get first mode in database as fallback */
+		modedb = specs->modedb[0];
 		/* get preferred timing */
 		if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
 			int i;
@@ -1826,9 +1828,6 @@
 					break;
 				}
 			}
-		} else {
-			/* otherwise, get first mode in database */
-			modedb = specs->modedb[0];
 		}
 		var->bits_per_pixel = 8;
 		riva_update_var(var, &modedb);
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 0c63b69..f310516 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -48,7 +48,8 @@
 #undef writel
 #define writel(v, r) do { \
 	printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \
-	__raw_writel(v, r); } while (0)
+	__raw_writel(v, r); \
+} while (0)
 #endif /* FB_S3C_DEBUG_REGWRITE */
 
 /* irq_flags bits */
@@ -81,12 +82,14 @@
  * @palette: Address of palette memory, or 0 if none.
  * @has_prtcon: Set if has PRTCON register.
  * @has_shadowcon: Set if has SHADOWCON register.
+ * @has_blendcon: Set if has BLENDCON register.
  * @has_clksel: Set if VIDCON0 register has CLKSEL bit.
+ * @has_fixvclk: Set if VIDCON1 register has FIXVCLK bits.
  */
 struct s3c_fb_variant {
 	unsigned int	is_2443:1;
 	unsigned short	nr_windows;
-	unsigned short	vidtcon;
+	unsigned int	vidtcon;
 	unsigned short	wincon;
 	unsigned short	winmap;
 	unsigned short	keycon;
@@ -99,7 +102,9 @@
 
 	unsigned int	has_prtcon:1;
 	unsigned int	has_shadowcon:1;
+	unsigned int	has_blendcon:1;
 	unsigned int	has_clksel:1;
+	unsigned int	has_fixvclk:1;
 };
 
 /**
@@ -186,7 +191,6 @@
  * struct s3c_fb - overall hardware state of the hardware
  * @slock: The spinlock protection for this data sturcture.
  * @dev: The device that we bound to, for printing, etc.
- * @regs_res: The resource we claimed for the IO registers.
  * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
  * @lcd_clk: The clk (sclk) feeding pixclk.
  * @regs: The mapped hardware registers.
@@ -202,7 +206,6 @@
 struct s3c_fb {
 	spinlock_t		slock;
 	struct device		*dev;
-	struct resource		*regs_res;
 	struct clk		*bus_clk;
 	struct clk		*lcd_clk;
 	void __iomem		*regs;
@@ -565,7 +568,9 @@
 		writel(data, regs + sfb->variant.vidtcon + 4);
 
 		data = VIDTCON2_LINEVAL(var->yres - 1) |
-		       VIDTCON2_HOZVAL(var->xres - 1);
+		       VIDTCON2_HOZVAL(var->xres - 1) |
+		       VIDTCON2_LINEVAL_E(var->yres - 1) |
+		       VIDTCON2_HOZVAL_E(var->xres - 1);
 		writel(data, regs + sfb->variant.vidtcon + 8);
 	}
 
@@ -581,17 +586,23 @@
 
 	pagewidth = (var->xres * var->bits_per_pixel) >> 3;
 	data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) |
-	       VIDW_BUF_SIZE_PAGEWIDTH(pagewidth);
+	       VIDW_BUF_SIZE_PAGEWIDTH(pagewidth) |
+	       VIDW_BUF_SIZE_OFFSET_E(info->fix.line_length - pagewidth) |
+	       VIDW_BUF_SIZE_PAGEWIDTH_E(pagewidth);
 	writel(data, regs + sfb->variant.buf_size + (win_no * 4));
 
 	/* write 'OSD' registers to control position of framebuffer */
 
-	data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0);
+	data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0) |
+	       VIDOSDxA_TOPLEFT_X_E(0) | VIDOSDxA_TOPLEFT_Y_E(0);
 	writel(data, regs + VIDOSD_A(win_no, sfb->variant));
 
 	data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel,
 						     var->xres - 1)) |
-	       VIDOSDxB_BOTRIGHT_Y(var->yres - 1);
+	       VIDOSDxB_BOTRIGHT_Y(var->yres - 1) |
+	       VIDOSDxB_BOTRIGHT_X_E(s3c_fb_align_word(var->bits_per_pixel,
+						     var->xres - 1)) |
+	       VIDOSDxB_BOTRIGHT_Y_E(var->yres - 1);
 
 	writel(data, regs + VIDOSD_B(win_no, sfb->variant));
 
@@ -692,6 +703,17 @@
 	writel(data, regs + sfb->variant.wincon + (win_no * 4));
 	writel(0x0, regs + sfb->variant.winmap + (win_no * 4));
 
+	/* Set alpha value width */
+	if (sfb->variant.has_blendcon) {
+		data = readl(sfb->regs + BLENDCON);
+		data &= ~BLENDCON_NEW_MASK;
+		if (var->transp.length > 4)
+			data |= BLENDCON_NEW_8BIT_ALPHA_VALUE;
+		else
+			data |= BLENDCON_NEW_4BIT_ALPHA_VALUE;
+		writel(data, sfb->regs + BLENDCON);
+	}
+
 	shadow_protect_win(win, 0);
 
 	pm_runtime_put_sync(sfb->dev);
@@ -1346,6 +1368,7 @@
 	struct resource *res;
 	int win;
 	int ret = 0;
+	u32 reg;
 
 	platid = platform_get_device_id(pdev);
 	fbdrv = (struct s3c_fb_driverdata *)platid->driver_data;
@@ -1361,7 +1384,7 @@
 		return -EINVAL;
 	}
 
-	sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL);
+	sfb = devm_kzalloc(dev, sizeof(struct s3c_fb), GFP_KERNEL);
 	if (!sfb) {
 		dev_err(dev, "no memory for framebuffers\n");
 		return -ENOMEM;
@@ -1404,33 +1427,25 @@
 		goto err_lcd_clk;
 	}
 
-	sfb->regs_res = request_mem_region(res->start, resource_size(res),
-					   dev_name(dev));
-	if (!sfb->regs_res) {
-		dev_err(dev, "failed to claim register region\n");
-		ret = -ENOENT;
-		goto err_lcd_clk;
-	}
-
-	sfb->regs = ioremap(res->start, resource_size(res));
+	sfb->regs = devm_request_and_ioremap(dev, res);
 	if (!sfb->regs) {
 		dev_err(dev, "failed to map registers\n");
 		ret = -ENXIO;
-		goto err_req_region;
+		goto err_lcd_clk;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
 		dev_err(dev, "failed to acquire irq resource\n");
 		ret = -ENOENT;
-		goto err_ioremap;
+		goto err_lcd_clk;
 	}
 	sfb->irq_no = res->start;
-	ret = request_irq(sfb->irq_no, s3c_fb_irq,
+	ret = devm_request_irq(dev, sfb->irq_no, s3c_fb_irq,
 			  0, "s3c_fb", sfb);
 	if (ret) {
 		dev_err(dev, "irq request failed\n");
-		goto err_ioremap;
+		goto err_lcd_clk;
 	}
 
 	dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs);
@@ -1444,6 +1459,14 @@
 
 	writel(pd->vidcon1, sfb->regs + VIDCON1);
 
+	/* set video clock running at under-run */
+	if (sfb->variant.has_fixvclk) {
+		reg = readl(sfb->regs + VIDCON1);
+		reg &= ~VIDCON1_VCLK_MASK;
+		reg |= VIDCON1_VCLK_RUN;
+		writel(reg, sfb->regs + VIDCON1);
+	}
+
 	/* zero all windows before we do anything */
 
 	for (win = 0; win < fbdrv->variant.nr_windows; win++)
@@ -1484,13 +1507,6 @@
 
 err_pm_runtime:
 	pm_runtime_put_sync(sfb->dev);
-	free_irq(sfb->irq_no, sfb);
-
-err_ioremap:
-	iounmap(sfb->regs);
-
-err_req_region:
-	release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
 
 err_lcd_clk:
 	pm_runtime_disable(sfb->dev);
@@ -1505,7 +1521,6 @@
 	clk_put(sfb->bus_clk);
 
 err_sfb:
-	kfree(sfb);
 	return ret;
 }
 
@@ -1527,10 +1542,6 @@
 		if (sfb->windows[win])
 			s3c_fb_release_win(sfb, sfb->windows[win]);
 
-	free_irq(sfb->irq_no, sfb);
-
-	iounmap(sfb->regs);
-
 	if (!sfb->variant.has_clksel) {
 		clk_disable(sfb->lcd_clk);
 		clk_put(sfb->lcd_clk);
@@ -1539,12 +1550,9 @@
 	clk_disable(sfb->bus_clk);
 	clk_put(sfb->bus_clk);
 
-	release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
-
 	pm_runtime_put_sync(sfb->dev);
 	pm_runtime_disable(sfb->dev);
 
-	kfree(sfb);
 	return 0;
 }
 
@@ -1579,6 +1587,7 @@
 	struct s3c_fb_platdata *pd = sfb->pdata;
 	struct s3c_fb_win *win;
 	int win_no;
+	u32 reg;
 
 	clk_enable(sfb->bus_clk);
 
@@ -1589,6 +1598,14 @@
 	pd->setup_gpio();
 	writel(pd->vidcon1, sfb->regs + VIDCON1);
 
+	/* set video clock running at under-run */
+	if (sfb->variant.has_fixvclk) {
+		reg = readl(sfb->regs + VIDCON1);
+		reg &= ~VIDCON1_VCLK_MASK;
+		reg |= VIDCON1_VCLK_RUN;
+		writel(reg, sfb->regs + VIDCON1);
+	}
+
 	/* zero all windows before we do anything */
 	for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++)
 		s3c_fb_clear_win(sfb, win_no);
@@ -1819,6 +1836,7 @@
 		},
 
 		.has_prtcon	= 1,
+		.has_blendcon	= 1,
 		.has_clksel	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
@@ -1850,7 +1868,9 @@
 		},
 
 		.has_shadowcon	= 1,
+		.has_blendcon	= 1,
 		.has_clksel	= 1,
+		.has_fixvclk	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
 	.win[1]	= &s3c_fb_data_s5p_wins[1],
@@ -1881,6 +1901,39 @@
 		},
 
 		.has_shadowcon	= 1,
+		.has_blendcon	= 1,
+		.has_fixvclk	= 1,
+	},
+	.win[0]	= &s3c_fb_data_s5p_wins[0],
+	.win[1]	= &s3c_fb_data_s5p_wins[1],
+	.win[2]	= &s3c_fb_data_s5p_wins[2],
+	.win[3]	= &s3c_fb_data_s5p_wins[3],
+	.win[4]	= &s3c_fb_data_s5p_wins[4],
+};
+
+static struct s3c_fb_driverdata s3c_fb_data_exynos5 = {
+	.variant = {
+		.nr_windows	= 5,
+		.vidtcon	= VIDTCON0,
+		.wincon		= WINCON(0),
+		.winmap		= WINxMAP(0),
+		.keycon		= WKEYCON,
+		.osd		= VIDOSD_BASE,
+		.osd_stride	= 16,
+		.buf_start	= VIDW_BUF_START(0),
+		.buf_size	= VIDW_BUF_SIZE(0),
+		.buf_end	= VIDW_BUF_END(0),
+
+		.palette = {
+			[0] = 0x2400,
+			[1] = 0x2800,
+			[2] = 0x2c00,
+			[3] = 0x3000,
+			[4] = 0x3400,
+		},
+		.has_shadowcon	= 1,
+		.has_blendcon	= 1,
+		.has_fixvclk	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
 	.win[1]	= &s3c_fb_data_s5p_wins[1],
@@ -1944,6 +1997,9 @@
 			[1] = 0x2800,
 			[2] = 0x2c00,
 		},
+
+		.has_blendcon	= 1,
+		.has_fixvclk	= 1,
 	},
 	.win[0] = &s3c_fb_data_s5p_wins[0],
 	.win[1] = &s3c_fb_data_s5p_wins[1],
@@ -1964,6 +2020,9 @@
 		.name		= "exynos4-fb",
 		.driver_data	= (unsigned long)&s3c_fb_data_exynos4,
 	}, {
+		.name		= "exynos5-fb",
+		.driver_data	= (unsigned long)&s3c_fb_data_exynos5,
+	}, {
 		.name		= "s3c2443-fb",
 		.driver_data	= (unsigned long)&s3c_fb_data_s3c2443,
 	}, {
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 05151b8..42ad0f7 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -24,6 +24,8 @@
 #include <video/sh_mipi_dsi.h>
 #include <video/sh_mobile_lcdc.h>
 
+#include "sh_mobile_lcdcfb.h"
+
 #define SYSCTRL		0x0000
 #define SYSCONF		0x0004
 #define TIMSET		0x0008
@@ -50,16 +52,16 @@
 #define MAX_SH_MIPI_DSI 2
 
 struct sh_mipi {
+	struct sh_mobile_lcdc_entity entity;
+
 	void __iomem	*base;
 	void __iomem	*linkbase;
 	struct clk	*dsit_clk;
 	struct platform_device *pdev;
-
-	void	*next_board_data;
-	void	(*next_display_on)(void *board_data, struct fb_info *info);
-	void	(*next_display_off)(void *board_data);
 };
 
+#define to_sh_mipi(e)	container_of(e, struct sh_mipi, entity)
+
 static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI];
 
 /* Protect the above array */
@@ -120,7 +122,7 @@
 
 static void sh_mipi_shutdown(struct platform_device *pdev)
 {
-	struct sh_mipi *mipi = platform_get_drvdata(pdev);
+	struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
 
 	sh_mipi_dsi_enable(mipi, false);
 }
@@ -145,77 +147,77 @@
 		pctype = 0;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
 		pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
-		linelength = ch->lcd_cfg[0].xres * 3;
+		linelength = ch->lcd_modes[0].xres * 3;
 		yuv = false;
 		break;
 	case MIPI_RGB565:
 		pctype = 1;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
 		pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
-		linelength = ch->lcd_cfg[0].xres * 2;
+		linelength = ch->lcd_modes[0].xres * 2;
 		yuv = false;
 		break;
 	case MIPI_RGB666_LP:
 		pctype = 2;
 		datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
 		pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
-		linelength = ch->lcd_cfg[0].xres * 3;
+		linelength = ch->lcd_modes[0].xres * 3;
 		yuv = false;
 		break;
 	case MIPI_RGB666:
 		pctype = 3;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
 		pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
-		linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8;
+		linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8;
 		yuv = false;
 		break;
 	case MIPI_BGR888:
 		pctype = 8;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
 		pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
-		linelength = ch->lcd_cfg[0].xres * 3;
+		linelength = ch->lcd_modes[0].xres * 3;
 		yuv = false;
 		break;
 	case MIPI_BGR565:
 		pctype = 9;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
 		pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
-		linelength = ch->lcd_cfg[0].xres * 2;
+		linelength = ch->lcd_modes[0].xres * 2;
 		yuv = false;
 		break;
 	case MIPI_BGR666_LP:
 		pctype = 0xa;
 		datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
 		pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
-		linelength = ch->lcd_cfg[0].xres * 3;
+		linelength = ch->lcd_modes[0].xres * 3;
 		yuv = false;
 		break;
 	case MIPI_BGR666:
 		pctype = 0xb;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
 		pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
-		linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8;
+		linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8;
 		yuv = false;
 		break;
 	case MIPI_YUYV:
 		pctype = 4;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
 		pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
-		linelength = ch->lcd_cfg[0].xres * 2;
+		linelength = ch->lcd_modes[0].xres * 2;
 		yuv = true;
 		break;
 	case MIPI_UYVY:
 		pctype = 5;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
 		pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
-		linelength = ch->lcd_cfg[0].xres * 2;
+		linelength = ch->lcd_modes[0].xres * 2;
 		yuv = true;
 		break;
 	case MIPI_YUV420_L:
 		pctype = 6;
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
 		pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
-		linelength = (ch->lcd_cfg[0].xres * 12 + 7) / 8;
+		linelength = (ch->lcd_modes[0].xres * 12 + 7) / 8;
 		yuv = true;
 		break;
 	case MIPI_YUV420:
@@ -223,7 +225,7 @@
 		datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
 		pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
 		/* Length of U/V line */
-		linelength = (ch->lcd_cfg[0].xres + 1) / 2;
+		linelength = (ch->lcd_modes[0].xres + 1) / 2;
 		yuv = true;
 		break;
 	default:
@@ -292,7 +294,7 @@
 	 */
 	iowrite32(0x00000006, mipi->linkbase + DTCTR);
 	/* VSYNC width = 2 (<< 17) */
-	iowrite32((ch->lcd_cfg[0].vsync_len << pdata->vsynw_offset) |
+	iowrite32((ch->lcd_modes[0].vsync_len << pdata->vsynw_offset) |
 		  (pdata->clksrc << 16) | (pctype << 12) | datatype,
 		  mipi->linkbase + VMCTR1);
 
@@ -326,7 +328,7 @@
 	top = linelength << 16; /* RGBLEN */
 	bottom = 0x00000001;
 	if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */
-		bottom = (pdata->lane * ch->lcd_cfg[0].hsync_len) - 10;
+		bottom = (pdata->lane * ch->lcd_modes[0].hsync_len) - 10;
 	iowrite32(top | bottom , mipi->linkbase + VMLEN1);
 
 	/*
@@ -346,18 +348,18 @@
 		div = 2;
 
 	if (pdata->flags & SH_MIPI_DSI_HFPBM) {	/* HBPLEN */
-		top = ch->lcd_cfg[0].hsync_len + ch->lcd_cfg[0].left_margin;
+		top = ch->lcd_modes[0].hsync_len + ch->lcd_modes[0].left_margin;
 		top = ((pdata->lane * top / div) - 10) << 16;
 	}
 	if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */
-		bottom = ch->lcd_cfg[0].right_margin;
+		bottom = ch->lcd_modes[0].right_margin;
 		bottom = (pdata->lane * bottom / div) - 12;
 	}
 
-	bpp = linelength / ch->lcd_cfg[0].xres; /* byte / pixel */
+	bpp = linelength / ch->lcd_modes[0].xres; /* byte / pixel */
 	if ((pdata->lane / div) > bpp) {
-		tmp = ch->lcd_cfg[0].xres / bpp; /* output cycle */
-		tmp = ch->lcd_cfg[0].xres - tmp; /* (input - output) cycle */
+		tmp = ch->lcd_modes[0].xres / bpp; /* output cycle */
+		tmp = ch->lcd_modes[0].xres - tmp; /* (input - output) cycle */
 		delay = (pdata->lane * tmp);
 	}
 
@@ -392,9 +394,9 @@
 	return 0;
 }
 
-static void mipi_display_on(void *arg, struct fb_info *info)
+static int mipi_display_on(struct sh_mobile_lcdc_entity *entity)
 {
-	struct sh_mipi *mipi = arg;
+	struct sh_mipi *mipi = to_sh_mipi(entity);
 	struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
 	int ret;
 
@@ -410,25 +412,21 @@
 
 	sh_mipi_dsi_enable(mipi, true);
 
-	if (mipi->next_display_on)
-		mipi->next_display_on(mipi->next_board_data, info);
-
-	return;
+	return SH_MOBILE_LCDC_DISPLAY_CONNECTED;
 
 mipi_display_on_fail1:
 	pm_runtime_put_sync(&mipi->pdev->dev);
 mipi_display_on_fail2:
 	pdata->set_dot_clock(mipi->pdev, mipi->base, 0);
+
+	return ret;
 }
 
-static void mipi_display_off(void *arg)
+static void mipi_display_off(struct sh_mobile_lcdc_entity *entity)
 {
-	struct sh_mipi *mipi = arg;
+	struct sh_mipi *mipi = to_sh_mipi(entity);
 	struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
 
-	if (mipi->next_display_off)
-		mipi->next_display_off(mipi->next_board_data);
-
 	sh_mipi_dsi_enable(mipi, false);
 
 	pdata->set_dot_clock(mipi->pdev, mipi->base, 0);
@@ -436,6 +434,11 @@
 	pm_runtime_put_sync(&mipi->pdev->dev);
 }
 
+static const struct sh_mobile_lcdc_entity_ops mipi_ops = {
+	.display_on = mipi_display_on,
+	.display_off = mipi_display_off,
+};
+
 static int __init sh_mipi_probe(struct platform_device *pdev)
 {
 	struct sh_mipi *mipi;
@@ -467,6 +470,9 @@
 		goto ealloc;
 	}
 
+	mipi->entity.owner = THIS_MODULE;
+	mipi->entity.ops = &mipi_ops;
+
 	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
 		dev_err(&pdev->dev, "MIPI register region already claimed\n");
 		ret = -EBUSY;
@@ -521,18 +527,7 @@
 	pm_runtime_resume(&pdev->dev);
 
 	mutex_unlock(&array_lock);
-	platform_set_drvdata(pdev, mipi);
-
-	/* Save original LCDC callbacks */
-	mipi->next_board_data = pdata->lcd_chan->board_cfg.board_data;
-	mipi->next_display_on = pdata->lcd_chan->board_cfg.display_on;
-	mipi->next_display_off = pdata->lcd_chan->board_cfg.display_off;
-
-	/* Set up LCDC callbacks */
-	pdata->lcd_chan->board_cfg.board_data = mipi;
-	pdata->lcd_chan->board_cfg.display_on = mipi_display_on;
-	pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
-	pdata->lcd_chan->board_cfg.owner = THIS_MODULE;
+	platform_set_drvdata(pdev, &mipi->entity);
 
 	return 0;
 
@@ -558,10 +553,9 @@
 
 static int __exit sh_mipi_remove(struct platform_device *pdev)
 {
-	struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	struct sh_mipi *mipi = platform_get_drvdata(pdev);
+	struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
 	int i, ret;
 
 	mutex_lock(&array_lock);
@@ -581,11 +575,6 @@
 	if (ret < 0)
 		return ret;
 
-	pdata->lcd_chan->board_cfg.owner = NULL;
-	pdata->lcd_chan->board_cfg.display_on = NULL;
-	pdata->lcd_chan->board_cfg.display_off = NULL;
-	pdata->lcd_chan->board_cfg.board_data = NULL;
-
 	pm_runtime_disable(&pdev->dev);
 	clk_disable(mipi->dsit_clk);
 	clk_put(mipi->dsit_clk);
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 647ba98..eafb19d 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -208,6 +208,8 @@
 };
 
 struct sh_hdmi {
+	struct sh_mobile_lcdc_entity entity;
+
 	void __iomem *base;
 	enum hotplug_state hp_state;	/* hot-plug status */
 	u8 preprogrammed_vic;		/* use a pre-programmed VIC or
@@ -217,14 +219,13 @@
 	u8 edid_blocks;
 	struct clk *hdmi_clk;
 	struct device *dev;
-	struct fb_info *info;
-	struct mutex mutex;		/* Protect the info pointer */
 	struct delayed_work edid_work;
-	struct fb_var_screeninfo var;
+	struct fb_videomode mode;
 	struct fb_monspecs monspec;
-	struct notifier_block notifier;
 };
 
+#define entity_to_sh_hdmi(e)	container_of(e, struct sh_hdmi, entity)
+
 static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
 {
 	iowrite8(data, hdmi->base + reg);
@@ -290,24 +291,24 @@
 /* External video parameter settings */
 static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi)
 {
-	struct fb_var_screeninfo *var = &hdmi->var;
+	struct fb_videomode *mode = &hdmi->mode;
 	u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset;
 	u8 sync = 0;
 
-	htotal = var->xres + var->right_margin + var->left_margin + var->hsync_len;
-
-	hdelay = var->hsync_len + var->left_margin;
-	hblank = var->right_margin + hdelay;
+	htotal = mode->xres + mode->right_margin + mode->left_margin
+	       + mode->hsync_len;
+	hdelay = mode->hsync_len + mode->left_margin;
+	hblank = mode->right_margin + hdelay;
 
 	/*
 	 * Vertical timing looks a bit different in Figure 18,
 	 * but let's try the same first by setting offset = 0
 	 */
-	vtotal = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
-
-	vdelay = var->vsync_len + var->upper_margin;
-	vblank = var->lower_margin + vdelay;
-	voffset = min(var->upper_margin / 2, 6U);
+	vtotal = mode->yres + mode->upper_margin + mode->lower_margin
+	       + mode->vsync_len;
+	vdelay = mode->vsync_len + mode->upper_margin;
+	vblank = mode->lower_margin + vdelay;
+	voffset = min(mode->upper_margin / 2, 6U);
 
 	/*
 	 * [3]: VSYNC polarity: Positive
@@ -315,14 +316,14 @@
 	 * [1]: Interlace/Progressive: Progressive
 	 * [0]: External video settings enable: used.
 	 */
-	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+	if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
 		sync |= 4;
-	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+	if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
 		sync |= 8;
 
 	dev_dbg(hdmi->dev, "H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n",
-		htotal, hblank, hdelay, var->hsync_len,
-		vtotal, vblank, vdelay, var->vsync_len, sync);
+		htotal, hblank, hdelay, mode->hsync_len,
+		vtotal, vblank, vdelay, mode->vsync_len, sync);
 
 	hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
 
@@ -335,8 +336,8 @@
 	hdmi_write(hdmi, hdelay, HDMI_EXTERNAL_H_DELAY_7_0);
 	hdmi_write(hdmi, hdelay >> 8, HDMI_EXTERNAL_H_DELAY_9_8);
 
-	hdmi_write(hdmi, var->hsync_len, HDMI_EXTERNAL_H_DURATION_7_0);
-	hdmi_write(hdmi, var->hsync_len >> 8, HDMI_EXTERNAL_H_DURATION_9_8);
+	hdmi_write(hdmi, mode->hsync_len, HDMI_EXTERNAL_H_DURATION_7_0);
+	hdmi_write(hdmi, mode->hsync_len >> 8, HDMI_EXTERNAL_H_DURATION_9_8);
 
 	hdmi_write(hdmi, vtotal, HDMI_EXTERNAL_V_TOTAL_7_0);
 	hdmi_write(hdmi, vtotal >> 8, HDMI_EXTERNAL_V_TOTAL_9_8);
@@ -345,7 +346,7 @@
 
 	hdmi_write(hdmi, vdelay, HDMI_EXTERNAL_V_DELAY);
 
-	hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION);
+	hdmi_write(hdmi, mode->vsync_len, HDMI_EXTERNAL_V_DURATION);
 
 	/* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */
 	if (!hdmi->preprogrammed_vic)
@@ -472,7 +473,7 @@
  */
 static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
 {
-	if (hdmi->var.pixclock < 10000) {
+	if (hdmi->mode.pixclock < 10000) {
 		/* for 1080p8bit 148MHz */
 		hdmi_write(hdmi, 0x1d, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
 		hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
@@ -483,7 +484,7 @@
 		hdmi_write(hdmi, 0x0e, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
 		hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
 		hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
-	} else if (hdmi->var.pixclock < 30000) {
+	} else if (hdmi->mode.pixclock < 30000) {
 		/* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
 		/*
 		 * [1:0]	Speed_A
@@ -732,14 +733,12 @@
 static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
 			     unsigned long *parent_rate)
 {
-	struct fb_var_screeninfo tmpvar;
-	struct fb_var_screeninfo *var = &tmpvar;
+	struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc;
 	const struct fb_videomode *mode, *found = NULL;
-	struct fb_info *info = hdmi->info;
-	struct fb_modelist *modelist = NULL;
 	unsigned int f_width = 0, f_height = 0, f_refresh = 0;
 	unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
 	bool scanning = false, preferred_bad = false;
+	bool use_edid_mode = false;
 	u8 edid[128];
 	char *forced;
 	int i;
@@ -854,12 +853,9 @@
 		}
 
 		/* Check if supported: sufficient fb memory, supported clock-rate */
-		fb_videomode_to_var(var, mode);
-
-		var->bits_per_pixel = info->var.bits_per_pixel;
-
-		if (info && info->fbops->fb_check_var &&
-		    info->fbops->fb_check_var(var, info)) {
+		if (ch && ch->notify &&
+		    ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_MODE, mode,
+			       NULL)) {
 			scanning = true;
 			preferred_bad = true;
 			continue;
@@ -867,28 +863,19 @@
 
 		found = mode;
 		found_rate_error = rate_error;
+		use_edid_mode = true;
 	}
 
-	hdmi->var.width = hdmi->monspec.max_x * 10;
-	hdmi->var.height = hdmi->monspec.max_y * 10;
-
 	/*
-	 * TODO 1: if no ->info is present, postpone running the config until
-	 * after ->info first gets registered.
+	 * TODO 1: if no default mode is present, postpone running the config
+	 * until after the LCDC channel is initialized.
 	 * TODO 2: consider registering the HDMI platform device from the LCDC
-	 * driver, and passing ->info with HDMI platform data.
+	 * driver.
 	 */
-	if (info && !found) {
-		modelist = info->modelist.next &&
-			!list_empty(&info->modelist) ?
-			list_entry(info->modelist.next,
-				   struct fb_modelist, list) :
-			NULL;
-
-		if (modelist) {
-			found = &modelist->mode;
-			found_rate_error = sh_hdmi_rate_error(hdmi, found, hdmi_rate, parent_rate);
-		}
+	if (!found && hdmi->entity.def_mode.xres != 0) {
+		found = &hdmi->entity.def_mode;
+		found_rate_error = sh_hdmi_rate_error(hdmi, found, hdmi_rate,
+						      parent_rate);
 	}
 
 	/* No cookie today */
@@ -912,12 +899,13 @@
 	else
 		hdmi->preprogrammed_vic = 0;
 
-	dev_dbg(hdmi->dev, "Using %s %s mode %ux%u@%uHz (%luHz), clock error %luHz\n",
-		modelist ? "default" : "EDID", hdmi->preprogrammed_vic ? "VIC" : "external",
-		found->xres, found->yres, found->refresh,
-		PICOS2KHZ(found->pixclock) * 1000, found_rate_error);
+	dev_dbg(hdmi->dev, "Using %s %s mode %ux%u@%uHz (%luHz), "
+		"clock error %luHz\n", use_edid_mode ? "EDID" : "default",
+		hdmi->preprogrammed_vic ? "VIC" : "external", found->xres,
+		found->yres, found->refresh, PICOS2KHZ(found->pixclock) * 1000,
+		found_rate_error);
 
-	fb_videomode_to_var(&hdmi->var, found);
+	hdmi->mode = *found;
 	sh_hdmi_external_video_param(hdmi);
 
 	return 0;
@@ -998,22 +986,12 @@
 	return IRQ_HANDLED;
 }
 
-/* locking:	called with info->lock held, or before register_framebuffer() */
-static void sh_hdmi_display_on(void *arg, struct fb_info *info)
+static int sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity)
 {
-	/*
-	 * info is guaranteed to be valid, when we are called, because our
-	 * FB_EVENT_FB_UNBIND notify is also called with info->lock held
-	 */
-	struct sh_hdmi *hdmi = arg;
-	struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
-	struct sh_mobile_lcdc_chan *ch = info->par;
+	struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
 
-	dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__,
-		pdata->lcd_dev, info->state);
-
-	/* No need to lock */
-	hdmi->info = info;
+	dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi,
+		hdmi->hp_state);
 
 	/*
 	 * hp_state can be set to
@@ -1021,56 +999,30 @@
 	 * HDMI_HOTPLUG_CONNECTED:	on monitor plug-in
 	 * HDMI_HOTPLUG_EDID_DONE:	on EDID read completion
 	 */
-	switch (hdmi->hp_state) {
-	case HDMI_HOTPLUG_EDID_DONE:
+	if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) {
 		/* PS mode d->e. All functions are active */
 		hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL);
 		dev_dbg(hdmi->dev, "HDMI running\n");
-		break;
-	case HDMI_HOTPLUG_DISCONNECTED:
-		info->state = FBINFO_STATE_SUSPENDED;
-	default:
-		hdmi->var = ch->display_var;
 	}
+
+	return hdmi->hp_state == HDMI_HOTPLUG_DISCONNECTED
+		? SH_MOBILE_LCDC_DISPLAY_DISCONNECTED
+		: SH_MOBILE_LCDC_DISPLAY_CONNECTED;
 }
 
-/* locking: called with info->lock held */
-static void sh_hdmi_display_off(void *arg)
+static void sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
 {
-	struct sh_hdmi *hdmi = arg;
-	struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
+	struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
 
-	dev_dbg(hdmi->dev, "%s(%p)\n", __func__, pdata->lcd_dev);
+	dev_dbg(hdmi->dev, "%s(%p)\n", __func__, hdmi);
 	/* PS mode e->a */
 	hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
 }
 
-static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
-{
-	struct fb_info *info = hdmi->info;
-	struct sh_mobile_lcdc_chan *ch = info->par;
-	struct fb_var_screeninfo *new_var = &hdmi->var, *old_var = &ch->display_var;
-	struct fb_videomode mode1, mode2;
-
-	fb_var_to_videomode(&mode1, old_var);
-	fb_var_to_videomode(&mode2, new_var);
-
-	dev_dbg(info->dev, "Old %ux%u, new %ux%u\n",
-		mode1.xres, mode1.yres, mode2.xres, mode2.yres);
-
-	if (fb_mode_is_equal(&mode1, &mode2)) {
-		/* It can be a different monitor with an equal video-mode */
-		old_var->width = new_var->width;
-		old_var->height = new_var->height;
-		return false;
-	}
-
-	dev_dbg(info->dev, "Switching %u -> %u lines\n",
-		mode1.yres, mode2.yres);
-	*old_var = *new_var;
-
-	return true;
-}
+static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = {
+	.display_on = sh_hdmi_display_on,
+	.display_off = sh_hdmi_display_off,
+};
 
 /**
  * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock
@@ -1111,20 +1063,11 @@
 static void sh_hdmi_edid_work_fn(struct work_struct *work)
 {
 	struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
-	struct fb_info *info;
-	struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
-	struct sh_mobile_lcdc_chan *ch;
+	struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc;
 	int ret;
 
-	dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__,
-		pdata->lcd_dev, hdmi->hp_state);
-
-	if (!pdata->lcd_dev)
-		return;
-
-	mutex_lock(&hdmi->mutex);
-
-	info = hdmi->info;
+	dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__, hdmi,
+		hdmi->hp_state);
 
 	if (hdmi->hp_state == HDMI_HOTPLUG_CONNECTED) {
 		unsigned long parent_rate = 0, hdmi_rate;
@@ -1145,103 +1088,32 @@
 		/* Switched to another (d) power-save mode */
 		msleep(10);
 
-		if (!info)
-			goto out;
-
-		ch = info->par;
-
-		if (lock_fb_info(info)) {
-			console_lock();
-
-			/* HDMI plug in */
-			if (!sh_hdmi_must_reconfigure(hdmi) &&
-			    info->state == FBINFO_STATE_RUNNING) {
-				/*
-				 * First activation with the default monitor - just turn
-				 * on, if we run a resume here, the logo disappears
-				 */
-				info->var.width = hdmi->var.width;
-				info->var.height = hdmi->var.height;
-				sh_hdmi_display_on(hdmi, info);
-			} else {
-				/* New monitor or have to wake up */
-				fb_set_suspend(info, 0);
-			}
-
-			console_unlock();
-			unlock_fb_info(info);
-		}
+		if (ch && ch->notify)
+			ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT,
+				   &hdmi->mode, &hdmi->monspec);
 	} else {
-		ret = 0;
-		if (!info)
-			goto out;
-
 		hdmi->monspec.modedb_len = 0;
 		fb_destroy_modedb(hdmi->monspec.modedb);
 		hdmi->monspec.modedb = NULL;
 
-		if (lock_fb_info(info)) {
-			console_lock();
+		if (ch && ch->notify)
+			ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT,
+				   NULL, NULL);
 
-			/* HDMI disconnect */
-			fb_set_suspend(info, 1);
-
-			console_unlock();
-			unlock_fb_info(info);
-		}
+		ret = 0;
 	}
 
 out:
 	if (ret < 0 && ret != -EAGAIN)
 		hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
-	mutex_unlock(&hdmi->mutex);
 
-	dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, pdata->lcd_dev);
-}
-
-static int sh_hdmi_notify(struct notifier_block *nb,
-			  unsigned long action, void *data)
-{
-	struct fb_event *event = data;
-	struct fb_info *info = event->info;
-	struct sh_mobile_lcdc_chan *ch = info->par;
-	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
-	struct sh_hdmi *hdmi = board_cfg->board_data;
-
-	if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)
-		return NOTIFY_DONE;
-
-	switch(action) {
-	case FB_EVENT_FB_REGISTERED:
-		/* Unneeded, activation taken care by sh_hdmi_display_on() */
-		break;
-	case FB_EVENT_FB_UNREGISTERED:
-		/*
-		 * We are called from unregister_framebuffer() with the
-		 * info->lock held. This is bad for us, because we can race with
-		 * the scheduled work, which has to call fb_set_suspend(), which
-		 * takes info->lock internally, so, sh_hdmi_edid_work_fn()
-		 * cannot take and hold info->lock for the whole function
-		 * duration. Using an additional lock creates a classical AB-BA
-		 * lock up. Therefore, we have to release the info->lock
-		 * temporarily, synchronise with the work queue and re-acquire
-		 * the info->lock.
-		 */
-		unlock_fb_info(info);
-		mutex_lock(&hdmi->mutex);
-		hdmi->info = NULL;
-		mutex_unlock(&hdmi->mutex);
-		lock_fb_info(info);
-		return NOTIFY_OK;
-	}
-	return NOTIFY_DONE;
+	dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, hdmi);
 }
 
 static int __init sh_hdmi_probe(struct platform_device *pdev)
 {
 	struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	struct sh_mobile_lcdc_board_cfg	*board_cfg;
 	int irq = platform_get_irq(pdev, 0), ret;
 	struct sh_hdmi *hdmi;
 	long rate;
@@ -1255,9 +1127,9 @@
 		return -ENOMEM;
 	}
 
-	mutex_init(&hdmi->mutex);
-
 	hdmi->dev = &pdev->dev;
+	hdmi->entity.owner = THIS_MODULE;
+	hdmi->entity.ops = &sh_hdmi_ops;
 
 	hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
 	if (IS_ERR(hdmi->hdmi_clk)) {
@@ -1297,14 +1169,7 @@
 		goto emap;
 	}
 
-	platform_set_drvdata(pdev, hdmi);
-
-	/* Set up LCDC callbacks */
-	board_cfg = &pdata->lcd_chan->board_cfg;
-	board_cfg->owner = THIS_MODULE;
-	board_cfg->board_data = hdmi;
-	board_cfg->display_on = sh_hdmi_display_on;
-	board_cfg->display_off = sh_hdmi_display_off;
+	platform_set_drvdata(pdev, &hdmi->entity);
 
 	INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn);
 
@@ -1329,9 +1194,6 @@
 		goto ecodec;
 	}
 
-	hdmi->notifier.notifier_call = sh_hdmi_notify;
-	fb_register_client(&hdmi->notifier);
-
 	return 0;
 
 ecodec:
@@ -1347,7 +1209,6 @@
 erate:
 	clk_put(hdmi->hdmi_clk);
 egetclk:
-	mutex_destroy(&hdmi->mutex);
 	kfree(hdmi);
 
 	return ret;
@@ -1355,21 +1216,12 @@
 
 static int __exit sh_hdmi_remove(struct platform_device *pdev)
 {
-	struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
-	struct sh_hdmi *hdmi = platform_get_drvdata(pdev);
+	struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev));
 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	struct sh_mobile_lcdc_board_cfg	*board_cfg = &pdata->lcd_chan->board_cfg;
 	int irq = platform_get_irq(pdev, 0);
 
 	snd_soc_unregister_codec(&pdev->dev);
 
-	fb_unregister_client(&hdmi->notifier);
-
-	board_cfg->display_on = NULL;
-	board_cfg->display_off = NULL;
-	board_cfg->board_data = NULL;
-	board_cfg->owner = NULL;
-
 	/* No new work will be scheduled, wait for running ISR */
 	free_irq(irq, hdmi);
 	/* Wait for already scheduled work */
@@ -1380,7 +1232,6 @@
 	clk_put(hdmi->hdmi_clk);
 	iounmap(hdmi->base);
 	release_mem_region(res->start, resource_size(res));
-	mutex_destroy(&hdmi->mutex);
 	kfree(hdmi);
 
 	return 0;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index aac5b36..7a0b301 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -8,26 +8,27 @@
  * for more details.
  */
 
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
+#include <linux/atomic.h>
+#include <linux/backlight.h>
 #include <linux/clk.h>
-#include <linux/pm_runtime.h>
-#include <linux/platform_device.h>
+#include <linux/console.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-#include <linux/console.h>
-#include <linux/backlight.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
+
 #include <video/sh_mobile_lcdc.h>
 #include <video/sh_mobile_meram.h>
-#include <linux/atomic.h>
 
 #include "sh_mobile_lcdcfb.h"
 
@@ -37,6 +38,24 @@
 #define MAX_XRES 1920
 #define MAX_YRES 1080
 
+struct sh_mobile_lcdc_priv {
+	void __iomem *base;
+	int irq;
+	atomic_t hw_usecnt;
+	struct device *dev;
+	struct clk *dot_clk;
+	unsigned long lddckr;
+	struct sh_mobile_lcdc_chan ch[2];
+	struct notifier_block notifier;
+	int started;
+	int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
+	struct sh_mobile_meram_info *meram_dev;
+};
+
+/* -----------------------------------------------------------------------------
+ * Registers access
+ */
+
 static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
 	[LDDCKPAT1R] = 0x400,
 	[LDDCKPAT2R] = 0x404,
@@ -75,38 +94,6 @@
 	[LDPMR] = 0x63c,
 };
 
-static const struct fb_videomode default_720p = {
-	.name = "HDMI 720p",
-	.xres = 1280,
-	.yres = 720,
-
-	.left_margin = 220,
-	.right_margin = 110,
-	.hsync_len = 40,
-
-	.upper_margin = 20,
-	.lower_margin = 5,
-	.vsync_len = 5,
-
-	.pixclock = 13468,
-	.refresh = 60,
-	.sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
-};
-
-struct sh_mobile_lcdc_priv {
-	void __iomem *base;
-	int irq;
-	atomic_t hw_usecnt;
-	struct device *dev;
-	struct clk *dot_clk;
-	unsigned long lddckr;
-	struct sh_mobile_lcdc_chan ch[2];
-	struct notifier_block notifier;
-	int started;
-	int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
-	struct sh_mobile_meram_info *meram_dev;
-};
-
 static bool banked(int reg_nr)
 {
 	switch (reg_nr) {
@@ -127,6 +114,11 @@
 	return false;
 }
 
+static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
+{
+	return chan->cfg->chan == LCDC_CHAN_SUBLCD;
+}
+
 static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
 			    int reg_nr, unsigned long data)
 {
@@ -169,11 +161,72 @@
 		cpu_relax();
 }
 
-static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
+/* -----------------------------------------------------------------------------
+ * Clock management
+ */
+
+static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 {
-	return chan->cfg.chan == LCDC_CHAN_SUBLCD;
+	if (atomic_inc_and_test(&priv->hw_usecnt)) {
+		if (priv->dot_clk)
+			clk_enable(priv->dot_clk);
+		pm_runtime_get_sync(priv->dev);
+		if (priv->meram_dev && priv->meram_dev->pdev)
+			pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
+	}
 }
 
+static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
+{
+	if (atomic_sub_return(1, &priv->hw_usecnt) == -1) {
+		if (priv->meram_dev && priv->meram_dev->pdev)
+			pm_runtime_put_sync(&priv->meram_dev->pdev->dev);
+		pm_runtime_put(priv->dev);
+		if (priv->dot_clk)
+			clk_disable(priv->dot_clk);
+	}
+}
+
+static int sh_mobile_lcdc_setup_clocks(struct sh_mobile_lcdc_priv *priv,
+				       int clock_source)
+{
+	struct clk *clk;
+	char *str;
+
+	switch (clock_source) {
+	case LCDC_CLK_BUS:
+		str = "bus_clk";
+		priv->lddckr = LDDCKR_ICKSEL_BUS;
+		break;
+	case LCDC_CLK_PERIPHERAL:
+		str = "peripheral_clk";
+		priv->lddckr = LDDCKR_ICKSEL_MIPI;
+		break;
+	case LCDC_CLK_EXTERNAL:
+		str = NULL;
+		priv->lddckr = LDDCKR_ICKSEL_HDMI;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (str == NULL)
+		return 0;
+
+	clk = clk_get(priv->dev, str);
+	if (IS_ERR(clk)) {
+		dev_err(priv->dev, "cannot get dot clock %s\n", str);
+		return PTR_ERR(clk);
+	}
+
+	priv->dot_clk = clk;
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Display, panel and deferred I/O
+ */
+
 static void lcdc_sys_write_index(void *handle, unsigned long data)
 {
 	struct sh_mobile_lcdc_chan *ch = handle;
@@ -216,74 +269,11 @@
 	lcdc_sys_read_data,
 };
 
-static int sh_mobile_format_fourcc(const struct fb_var_screeninfo *var)
-{
-	if (var->grayscale > 1)
-		return var->grayscale;
-
-	switch (var->bits_per_pixel) {
-	case 16:
-		return V4L2_PIX_FMT_RGB565;
-	case 24:
-		return V4L2_PIX_FMT_BGR24;
-	case 32:
-		return V4L2_PIX_FMT_BGR32;
-	default:
-		return 0;
-	}
-}
-
-static int sh_mobile_format_is_fourcc(const struct fb_var_screeninfo *var)
-{
-	return var->grayscale > 1;
-}
-
-static bool sh_mobile_format_is_yuv(const struct fb_var_screeninfo *var)
-{
-	if (var->grayscale <= 1)
-		return false;
-
-	switch (var->grayscale) {
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV21:
-	case V4L2_PIX_FMT_NV16:
-	case V4L2_PIX_FMT_NV61:
-	case V4L2_PIX_FMT_NV24:
-	case V4L2_PIX_FMT_NV42:
-		return true;
-
-	default:
-		return false;
-	}
-}
-
-static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
-{
-	if (atomic_inc_and_test(&priv->hw_usecnt)) {
-		if (priv->dot_clk)
-			clk_enable(priv->dot_clk);
-		pm_runtime_get_sync(priv->dev);
-		if (priv->meram_dev && priv->meram_dev->pdev)
-			pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
-	}
-}
-
-static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
-{
-	if (atomic_sub_return(1, &priv->hw_usecnt) == -1) {
-		if (priv->meram_dev && priv->meram_dev->pdev)
-			pm_runtime_put_sync(&priv->meram_dev->pdev->dev);
-		pm_runtime_put(priv->dev);
-		if (priv->dot_clk)
-			clk_disable(priv->dot_clk);
-	}
-}
-
 static int sh_mobile_lcdc_sginit(struct fb_info *info,
 				  struct list_head *pagelist)
 {
 	struct sh_mobile_lcdc_chan *ch = info->par;
-	unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT;
+	unsigned int nr_pages_max = ch->fb_size >> PAGE_SHIFT;
 	struct page *page;
 	int nr_pages = 0;
 
@@ -299,7 +289,7 @@
 				       struct list_head *pagelist)
 {
 	struct sh_mobile_lcdc_chan *ch = info->par;
-	struct sh_mobile_lcdc_board_cfg	*bcfg = &ch->cfg.board_cfg;
+	const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg;
 
 	/* enable clocks before accessing hardware */
 	sh_mobile_lcdc_clk_on(ch->lcdc);
@@ -323,16 +313,15 @@
 		unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
 
 		/* trigger panel update */
-		dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
-		if (bcfg->start_transfer)
-			bcfg->start_transfer(bcfg->board_data, ch,
-					     &sh_mobile_lcdc_sys_bus_ops);
+		dma_map_sg(ch->lcdc->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+		if (panel->start_transfer)
+			panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
 		lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
-		dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+		dma_unmap_sg(ch->lcdc->dev, ch->sglist, nr_pages,
+			     DMA_TO_DEVICE);
 	} else {
-		if (bcfg->start_transfer)
-			bcfg->start_transfer(bcfg->board_data, ch,
-					     &sh_mobile_lcdc_sys_bus_ops);
+		if (panel->start_transfer)
+			panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
 		lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
 	}
 }
@@ -345,6 +334,217 @@
 		schedule_delayed_work(&info->deferred_work, fbdefio->delay);
 }
 
+static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
+{
+	const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg;
+
+	if (ch->tx_dev) {
+		int ret;
+
+		ret = ch->tx_dev->ops->display_on(ch->tx_dev);
+		if (ret < 0)
+			return;
+
+		if (ret == SH_MOBILE_LCDC_DISPLAY_DISCONNECTED)
+			ch->info->state = FBINFO_STATE_SUSPENDED;
+	}
+
+	/* HDMI must be enabled before LCDC configuration */
+	if (panel->display_on)
+		panel->display_on();
+}
+
+static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
+{
+	const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg;
+
+	if (panel->display_off)
+		panel->display_off();
+
+	if (ch->tx_dev)
+		ch->tx_dev->ops->display_off(ch->tx_dev);
+}
+
+static bool
+sh_mobile_lcdc_must_reconfigure(struct sh_mobile_lcdc_chan *ch,
+				const struct fb_videomode *new_mode)
+{
+	dev_dbg(ch->info->dev, "Old %ux%u, new %ux%u\n",
+		ch->display.mode.xres, ch->display.mode.yres,
+		new_mode->xres, new_mode->yres);
+
+	/* It can be a different monitor with an equal video-mode */
+	if (fb_mode_is_equal(&ch->display.mode, new_mode))
+		return false;
+
+	dev_dbg(ch->info->dev, "Switching %u -> %u lines\n",
+		ch->display.mode.yres, new_mode->yres);
+	ch->display.mode = *new_mode;
+
+	return true;
+}
+
+static int sh_mobile_check_var(struct fb_var_screeninfo *var,
+			       struct fb_info *info);
+
+static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
+					 enum sh_mobile_lcdc_entity_event event,
+					 const struct fb_videomode *mode,
+					 const struct fb_monspecs *monspec)
+{
+	struct fb_info *info = ch->info;
+	struct fb_var_screeninfo var;
+	int ret = 0;
+
+	switch (event) {
+	case SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT:
+		/* HDMI plug in */
+		if (lock_fb_info(info)) {
+			console_lock();
+
+			ch->display.width = monspec->max_x * 10;
+			ch->display.height = monspec->max_y * 10;
+
+			if (!sh_mobile_lcdc_must_reconfigure(ch, mode) &&
+			    info->state == FBINFO_STATE_RUNNING) {
+				/* First activation with the default monitor.
+				 * Just turn on, if we run a resume here, the
+				 * logo disappears.
+				 */
+				info->var.width = monspec->max_x * 10;
+				info->var.height = monspec->max_y * 10;
+				sh_mobile_lcdc_display_on(ch);
+			} else {
+				/* New monitor or have to wake up */
+				fb_set_suspend(info, 0);
+			}
+
+			console_unlock();
+			unlock_fb_info(info);
+		}
+		break;
+
+	case SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT:
+		/* HDMI disconnect */
+		if (lock_fb_info(info)) {
+			console_lock();
+			fb_set_suspend(info, 1);
+			console_unlock();
+			unlock_fb_info(info);
+		}
+		break;
+
+	case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE:
+		/* Validate a proposed new mode */
+		fb_videomode_to_var(&var, mode);
+		var.bits_per_pixel = info->var.bits_per_pixel;
+		var.grayscale = info->var.grayscale;
+		ret = sh_mobile_check_var(&var, info);
+		break;
+	}
+
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * Format helpers
+ */
+
+struct sh_mobile_lcdc_format_info {
+	u32 fourcc;
+	unsigned int bpp;
+	bool yuv;
+	u32 lddfr;
+};
+
+static const struct sh_mobile_lcdc_format_info sh_mobile_format_infos[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_RGB565,
+		.bpp = 16,
+		.yuv = false,
+		.lddfr = LDDFR_PKF_RGB16,
+	}, {
+		.fourcc = V4L2_PIX_FMT_BGR24,
+		.bpp = 24,
+		.yuv = false,
+		.lddfr = LDDFR_PKF_RGB24,
+	}, {
+		.fourcc = V4L2_PIX_FMT_BGR32,
+		.bpp = 32,
+		.yuv = false,
+		.lddfr = LDDFR_PKF_ARGB32,
+	}, {
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.bpp = 12,
+		.yuv = true,
+		.lddfr = LDDFR_CC | LDDFR_YF_420,
+	}, {
+		.fourcc = V4L2_PIX_FMT_NV21,
+		.bpp = 12,
+		.yuv = true,
+		.lddfr = LDDFR_CC | LDDFR_YF_420,
+	}, {
+		.fourcc = V4L2_PIX_FMT_NV16,
+		.bpp = 16,
+		.yuv = true,
+		.lddfr = LDDFR_CC | LDDFR_YF_422,
+	}, {
+		.fourcc = V4L2_PIX_FMT_NV61,
+		.bpp = 16,
+		.yuv = true,
+		.lddfr = LDDFR_CC | LDDFR_YF_422,
+	}, {
+		.fourcc = V4L2_PIX_FMT_NV24,
+		.bpp = 24,
+		.yuv = true,
+		.lddfr = LDDFR_CC | LDDFR_YF_444,
+	}, {
+		.fourcc = V4L2_PIX_FMT_NV42,
+		.bpp = 24,
+		.yuv = true,
+		.lddfr = LDDFR_CC | LDDFR_YF_444,
+	},
+};
+
+static const struct sh_mobile_lcdc_format_info *
+sh_mobile_format_info(u32 fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(sh_mobile_format_infos); ++i) {
+		if (sh_mobile_format_infos[i].fourcc == fourcc)
+			return &sh_mobile_format_infos[i];
+	}
+
+	return NULL;
+}
+
+static int sh_mobile_format_fourcc(const struct fb_var_screeninfo *var)
+{
+	if (var->grayscale > 1)
+		return var->grayscale;
+
+	switch (var->bits_per_pixel) {
+	case 16:
+		return V4L2_PIX_FMT_RGB565;
+	case 24:
+		return V4L2_PIX_FMT_BGR24;
+	case 32:
+		return V4L2_PIX_FMT_BGR32;
+	default:
+		return 0;
+	}
+}
+
+static int sh_mobile_format_is_fourcc(const struct fb_var_screeninfo *var)
+{
+	return var->grayscale > 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Start, stop and IRQ
+ */
+
 static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
 {
 	struct sh_mobile_lcdc_priv *priv = data;
@@ -385,6 +585,26 @@
 	return IRQ_HANDLED;
 }
 
+static int sh_mobile_wait_for_vsync(struct sh_mobile_lcdc_chan *ch)
+{
+	unsigned long ldintr;
+	int ret;
+
+	/* Enable VSync End interrupt and be careful not to acknowledge any
+	 * pending interrupt.
+	 */
+	ldintr = lcdc_read(ch->lcdc, _LDINTR);
+	ldintr |= LDINTR_VEE | LDINTR_STATUS_MASK;
+	lcdc_write(ch->lcdc, _LDINTR, ldintr);
+
+	ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion,
+							msecs_to_jiffies(100));
+	if (!ret)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
 static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
 				      int start)
 {
@@ -416,53 +636,52 @@
 
 static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
 {
-	struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var;
+	const struct fb_var_screeninfo *var = &ch->info->var;
+	const struct fb_videomode *mode = &ch->display.mode;
 	unsigned long h_total, hsync_pos, display_h_total;
 	u32 tmp;
 
 	tmp = ch->ldmt1r_value;
 	tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : LDMT1R_VPOL;
 	tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : LDMT1R_HPOL;
-	tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? LDMT1R_DWPOL : 0;
-	tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? LDMT1R_DIPOL : 0;
-	tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? LDMT1R_DAPOL : 0;
-	tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? LDMT1R_HSCNT : 0;
-	tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? LDMT1R_DWCNT : 0;
+	tmp |= (ch->cfg->flags & LCDC_FLAGS_DWPOL) ? LDMT1R_DWPOL : 0;
+	tmp |= (ch->cfg->flags & LCDC_FLAGS_DIPOL) ? LDMT1R_DIPOL : 0;
+	tmp |= (ch->cfg->flags & LCDC_FLAGS_DAPOL) ? LDMT1R_DAPOL : 0;
+	tmp |= (ch->cfg->flags & LCDC_FLAGS_HSCNT) ? LDMT1R_HSCNT : 0;
+	tmp |= (ch->cfg->flags & LCDC_FLAGS_DWCNT) ? LDMT1R_DWCNT : 0;
 	lcdc_write_chan(ch, LDMT1R, tmp);
 
 	/* setup SYS bus */
-	lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r);
-	lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
+	lcdc_write_chan(ch, LDMT2R, ch->cfg->sys_bus_cfg.ldmt2r);
+	lcdc_write_chan(ch, LDMT3R, ch->cfg->sys_bus_cfg.ldmt3r);
 
 	/* horizontal configuration */
-	h_total = display_var->xres + display_var->hsync_len +
-		display_var->left_margin + display_var->right_margin;
+	h_total = mode->xres + mode->hsync_len + mode->left_margin
+		+ mode->right_margin;
 	tmp = h_total / 8; /* HTCN */
-	tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */
+	tmp |= (min(mode->xres, ch->xres) / 8) << 16; /* HDCN */
 	lcdc_write_chan(ch, LDHCNR, tmp);
 
-	hsync_pos = display_var->xres + display_var->right_margin;
+	hsync_pos = mode->xres + mode->right_margin;
 	tmp = hsync_pos / 8; /* HSYNP */
-	tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */
+	tmp |= (mode->hsync_len / 8) << 16; /* HSYNW */
 	lcdc_write_chan(ch, LDHSYNR, tmp);
 
 	/* vertical configuration */
-	tmp = display_var->yres + display_var->vsync_len +
-		display_var->upper_margin + display_var->lower_margin; /* VTLN */
-	tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */
+	tmp = mode->yres + mode->vsync_len + mode->upper_margin
+	    + mode->lower_margin; /* VTLN */
+	tmp |= min(mode->yres, ch->yres) << 16; /* VDLN */
 	lcdc_write_chan(ch, LDVLNR, tmp);
 
-	tmp = display_var->yres + display_var->lower_margin; /* VSYNP */
-	tmp |= display_var->vsync_len << 16; /* VSYNW */
+	tmp = mode->yres + mode->lower_margin; /* VSYNP */
+	tmp |= mode->vsync_len << 16; /* VSYNW */
 	lcdc_write_chan(ch, LDVSYNR, tmp);
 
 	/* Adjust horizontal synchronisation for HDMI */
-	display_h_total = display_var->xres + display_var->hsync_len +
-		display_var->left_margin + display_var->right_margin;
-	tmp = ((display_var->xres & 7) << 24) |
-		((display_h_total & 7) << 16) |
-		((display_var->hsync_len & 7) << 8) |
-		(hsync_pos & 7);
+	display_h_total = mode->xres + mode->hsync_len + mode->left_margin
+			+ mode->right_margin;
+	tmp = ((mode->xres & 7) << 24) | ((display_h_total & 7) << 16)
+	    | ((mode->hsync_len & 7) << 8) | (hsync_pos & 7);
 	lcdc_write_chan(ch, LDHAJR, tmp);
 }
 
@@ -498,7 +717,7 @@
 		/* Power supply */
 		lcdc_write_chan(ch, LDPMR, 0);
 
-		m = ch->cfg.clock_divider;
+		m = ch->cfg->clock_divider;
 		if (!m)
 			continue;
 
@@ -525,32 +744,10 @@
 
 		sh_mobile_lcdc_geometry(ch);
 
-		switch (sh_mobile_format_fourcc(&ch->info->var)) {
-		case V4L2_PIX_FMT_RGB565:
-			tmp = LDDFR_PKF_RGB16;
-			break;
-		case V4L2_PIX_FMT_BGR24:
-			tmp = LDDFR_PKF_RGB24;
-			break;
-		case V4L2_PIX_FMT_BGR32:
-			tmp = LDDFR_PKF_ARGB32;
-			break;
-		case V4L2_PIX_FMT_NV12:
-		case V4L2_PIX_FMT_NV21:
-			tmp = LDDFR_CC | LDDFR_YF_420;
-			break;
-		case V4L2_PIX_FMT_NV16:
-		case V4L2_PIX_FMT_NV61:
-			tmp = LDDFR_CC | LDDFR_YF_422;
-			break;
-		case V4L2_PIX_FMT_NV24:
-		case V4L2_PIX_FMT_NV42:
-			tmp = LDDFR_CC | LDDFR_YF_444;
-			break;
-		}
+		tmp = ch->format->lddfr;
 
-		if (sh_mobile_format_is_yuv(&ch->info->var)) {
-			switch (ch->info->var.colorspace) {
+		if (ch->format->yuv) {
+			switch (ch->colorspace) {
 			case V4L2_COLORSPACE_REC709:
 				tmp |= LDDFR_CF1;
 				break;
@@ -563,7 +760,7 @@
 		lcdc_write_chan(ch, LDDFR, tmp);
 		lcdc_write_chan(ch, LDMLSR, ch->pitch);
 		lcdc_write_chan(ch, LDSA1R, ch->base_addr_y);
-		if (sh_mobile_format_is_yuv(&ch->info->var))
+		if (ch->format->yuv)
 			lcdc_write_chan(ch, LDSA2R, ch->base_addr_c);
 
 		/* When using deferred I/O mode, configure the LCDC for one-shot
@@ -571,7 +768,7 @@
 		 * continuous read mode.
 		 */
 		if (ch->ldmt1r_value & LDMT1R_IFM &&
-		    ch->cfg.sys_bus_cfg.deferred_io_msec) {
+		    ch->cfg->sys_bus_cfg.deferred_io_msec) {
 			lcdc_write_chan(ch, LDSM1R, LDSM1R_OS);
 			lcdc_write(priv, _LDINTR, LDINTR_FE);
 		} else {
@@ -580,7 +777,7 @@
 	}
 
 	/* Word and long word swap. */
-	switch (sh_mobile_format_fourcc(&priv->ch[0].info->var)) {
+	switch (priv->ch[0].format->fourcc) {
 	case V4L2_PIX_FMT_RGB565:
 	case V4L2_PIX_FMT_NV21:
 	case V4L2_PIX_FMT_NV61:
@@ -609,7 +806,6 @@
 static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 {
 	struct sh_mobile_meram_info *mdev = priv->meram_dev;
-	struct sh_mobile_lcdc_board_cfg	*board_cfg;
 	struct sh_mobile_lcdc_chan *ch;
 	unsigned long tmp;
 	int ret;
@@ -626,15 +822,15 @@
 	lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0);
 
 	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
-		ch = &priv->ch[k];
+		const struct sh_mobile_lcdc_panel_cfg *panel;
 
+		ch = &priv->ch[k];
 		if (!ch->enabled)
 			continue;
 
-		board_cfg = &ch->cfg.board_cfg;
-		if (board_cfg->setup_sys) {
-			ret = board_cfg->setup_sys(board_cfg->board_data, ch,
-						   &sh_mobile_lcdc_sys_bus_ops);
+		panel = &ch->cfg->panel_cfg;
+		if (panel->setup_sys) {
+			ret = panel->setup_sys(ch, &sh_mobile_lcdc_sys_bus_ops);
 			if (ret)
 				return ret;
 		}
@@ -642,33 +838,30 @@
 
 	/* Compute frame buffer base address and pitch for each channel. */
 	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
-		struct sh_mobile_meram_cfg *cfg;
 		int pixelformat;
+		void *meram;
 
 		ch = &priv->ch[k];
 		if (!ch->enabled)
 			continue;
 
-		ch->base_addr_y = ch->info->fix.smem_start;
-		ch->base_addr_c = ch->base_addr_y
-				+ ch->info->var.xres
-				* ch->info->var.yres_virtual;
-		ch->pitch = ch->info->fix.line_length;
+		ch->base_addr_y = ch->dma_handle;
+		ch->base_addr_c = ch->base_addr_y + ch->xres * ch->yres_virtual;
 
 		/* Enable MERAM if possible. */
-		cfg = ch->cfg.meram_cfg;
-		if (mdev == NULL || mdev->ops == NULL || cfg == NULL)
+		if (mdev == NULL || mdev->ops == NULL ||
+		    ch->cfg->meram_cfg == NULL)
 			continue;
 
 		/* we need to de-init configured ICBs before we can
 		 * re-initialize them.
 		 */
-		if (ch->meram_enabled) {
-			mdev->ops->meram_unregister(mdev, cfg);
-			ch->meram_enabled = 0;
+		if (ch->meram) {
+			mdev->ops->meram_unregister(mdev, ch->meram);
+			ch->meram = NULL;
 		}
 
-		switch (sh_mobile_format_fourcc(&ch->info->var)) {
+		switch (ch->format->fourcc) {
 		case V4L2_PIX_FMT_NV12:
 		case V4L2_PIX_FMT_NV21:
 		case V4L2_PIX_FMT_NV16:
@@ -687,13 +880,15 @@
 			break;
 		}
 
-		ret = mdev->ops->meram_register(mdev, cfg, ch->pitch,
-					ch->info->var.yres, pixelformat,
-					ch->base_addr_y, ch->base_addr_c,
-					&ch->base_addr_y, &ch->base_addr_c,
+		meram = mdev->ops->meram_register(mdev, ch->cfg->meram_cfg,
+					ch->pitch, ch->yres, pixelformat,
 					&ch->pitch);
-		if (!ret)
-			ch->meram_enabled = 1;
+		if (!IS_ERR(meram)) {
+			mdev->ops->meram_update(mdev, meram,
+					ch->base_addr_y, ch->base_addr_c,
+					&ch->base_addr_y, &ch->base_addr_c);
+			ch->meram = meram;
+		}
 	}
 
 	/* Start the LCDC. */
@@ -707,7 +902,7 @@
 		if (!ch->enabled)
 			continue;
 
-		tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
+		tmp = ch->cfg->sys_bus_cfg.deferred_io_msec;
 		if (ch->ldmt1r_value & LDMT1R_IFM && tmp) {
 			ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
 			ch->defio.delay = msecs_to_jiffies(tmp);
@@ -715,11 +910,7 @@
 			fb_deferred_io_init(ch->info);
 		}
 
-		board_cfg = &ch->cfg.board_cfg;
-		if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
-			board_cfg->display_on(board_cfg->board_data, ch->info);
-			module_put(board_cfg->owner);
-		}
+		sh_mobile_lcdc_display_on(ch);
 
 		if (ch->bl) {
 			ch->bl->props.power = FB_BLANK_UNBLANK;
@@ -733,7 +924,6 @@
 static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
 {
 	struct sh_mobile_lcdc_chan *ch;
-	struct sh_mobile_lcdc_board_cfg	*board_cfg;
 	int k;
 
 	/* clean up deferred io and ask board code to disable panel */
@@ -760,20 +950,14 @@
 			backlight_update_status(ch->bl);
 		}
 
-		board_cfg = &ch->cfg.board_cfg;
-		if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
-			board_cfg->display_off(board_cfg->board_data);
-			module_put(board_cfg->owner);
-		}
+		sh_mobile_lcdc_display_off(ch);
 
 		/* disable the meram */
-		if (ch->meram_enabled) {
-			struct sh_mobile_meram_cfg *cfg;
+		if (ch->meram) {
 			struct sh_mobile_meram_info *mdev;
-			cfg = ch->cfg.meram_cfg;
 			mdev = priv->meram_dev;
-			mdev->ops->meram_unregister(mdev, cfg);
-			ch->meram_enabled = 0;
+			mdev->ops->meram_unregister(mdev, ch->meram);
+			ch->meram = 0;
 		}
 
 	}
@@ -790,86 +974,9 @@
 			sh_mobile_lcdc_clk_off(priv);
 }
 
-static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
-{
-	int interface_type = ch->cfg.interface_type;
-
-	switch (interface_type) {
-	case RGB8:
-	case RGB9:
-	case RGB12A:
-	case RGB12B:
-	case RGB16:
-	case RGB18:
-	case RGB24:
-	case SYS8A:
-	case SYS8B:
-	case SYS8C:
-	case SYS8D:
-	case SYS9:
-	case SYS12:
-	case SYS16A:
-	case SYS16B:
-	case SYS16C:
-	case SYS18:
-	case SYS24:
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	/* SUBLCD only supports SYS interface */
-	if (lcdc_chan_is_sublcd(ch)) {
-		if (!(interface_type & LDMT1R_IFM))
-			return -EINVAL;
-
-		interface_type &= ~LDMT1R_IFM;
-	}
-
-	ch->ldmt1r_value = interface_type;
-	return 0;
-}
-
-static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
-				       int clock_source,
-				       struct sh_mobile_lcdc_priv *priv)
-{
-	char *str;
-
-	switch (clock_source) {
-	case LCDC_CLK_BUS:
-		str = "bus_clk";
-		priv->lddckr = LDDCKR_ICKSEL_BUS;
-		break;
-	case LCDC_CLK_PERIPHERAL:
-		str = "peripheral_clk";
-		priv->lddckr = LDDCKR_ICKSEL_MIPI;
-		break;
-	case LCDC_CLK_EXTERNAL:
-		str = NULL;
-		priv->lddckr = LDDCKR_ICKSEL_HDMI;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (str) {
-		priv->dot_clk = clk_get(&pdev->dev, str);
-		if (IS_ERR(priv->dot_clk)) {
-			dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
-			return PTR_ERR(priv->dot_clk);
-		}
-	}
-
-	/* Runtime PM support involves two step for this driver:
-	 * 1) Enable Runtime PM
-	 * 2) Force Runtime PM Resume since hardware is accessed from probe()
-	 */
-	priv->dev = &pdev->dev;
-	pm_runtime_enable(priv->dev);
-	pm_runtime_resume(priv->dev);
-	return 0;
-}
+/* -----------------------------------------------------------------------------
+ * Frame buffer operations
+ */
 
 static int sh_mobile_lcdc_setcolreg(u_int regno,
 				    u_int red, u_int green, u_int blue,
@@ -936,14 +1043,12 @@
 	unsigned long new_pan_offset;
 	unsigned long base_addr_y, base_addr_c;
 	unsigned long c_offset;
-	bool yuv = sh_mobile_format_is_yuv(&info->var);
 
-	if (!yuv)
-		new_pan_offset = var->yoffset * info->fix.line_length
-			       + var->xoffset * (info->var.bits_per_pixel / 8);
+	if (!ch->format->yuv)
+		new_pan_offset = var->yoffset * ch->pitch
+			       + var->xoffset * (ch->format->bpp / 8);
 	else
-		new_pan_offset = var->yoffset * info->fix.line_length
-			       + var->xoffset;
+		new_pan_offset = var->yoffset * ch->pitch + var->xoffset;
 
 	if (new_pan_offset == ch->pan_offset)
 		return 0;	/* No change, do nothing */
@@ -952,39 +1057,33 @@
 
 	/* Set the source address for the next refresh */
 	base_addr_y = ch->dma_handle + new_pan_offset;
-	if (yuv) {
+	if (ch->format->yuv) {
 		/* Set y offset */
-		c_offset = var->yoffset * info->fix.line_length
-			 * (info->var.bits_per_pixel - 8) / 8;
-		base_addr_c = ch->dma_handle
-			    + info->var.xres * info->var.yres_virtual
+		c_offset = var->yoffset * ch->pitch
+			 * (ch->format->bpp - 8) / 8;
+		base_addr_c = ch->dma_handle + ch->xres * ch->yres_virtual
 			    + c_offset;
 		/* Set x offset */
-		if (sh_mobile_format_fourcc(&info->var) == V4L2_PIX_FMT_NV24)
+		if (ch->format->fourcc == V4L2_PIX_FMT_NV24)
 			base_addr_c += 2 * var->xoffset;
 		else
 			base_addr_c += var->xoffset;
 	}
 
-	if (ch->meram_enabled) {
-		struct sh_mobile_meram_cfg *cfg;
+	if (ch->meram) {
 		struct sh_mobile_meram_info *mdev;
-		int ret;
 
-		cfg = ch->cfg.meram_cfg;
 		mdev = priv->meram_dev;
-		ret = mdev->ops->meram_update(mdev, cfg,
+		mdev->ops->meram_update(mdev, ch->meram,
 					base_addr_y, base_addr_c,
 					&base_addr_y, &base_addr_c);
-		if (ret)
-			return ret;
 	}
 
 	ch->base_addr_y = base_addr_y;
 	ch->base_addr_c = base_addr_c;
 
 	lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
-	if (yuv)
+	if (ch->format->yuv)
 		lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
 
 	if (lcdc_chan_is_sublcd(ch))
@@ -999,27 +1098,6 @@
 	return 0;
 }
 
-static int sh_mobile_wait_for_vsync(struct fb_info *info)
-{
-	struct sh_mobile_lcdc_chan *ch = info->par;
-	unsigned long ldintr;
-	int ret;
-
-	/* Enable VSync End interrupt and be careful not to acknowledge any
-	 * pending interrupt.
-	 */
-	ldintr = lcdc_read(ch->lcdc, _LDINTR);
-	ldintr |= LDINTR_VEE | LDINTR_STATUS_MASK;
-	lcdc_write(ch->lcdc, _LDINTR, ldintr);
-
-	ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion,
-							msecs_to_jiffies(100));
-	if (!ret)
-		return -ETIMEDOUT;
-
-	return 0;
-}
-
 static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
 		       unsigned long arg)
 {
@@ -1027,7 +1105,7 @@
 
 	switch (cmd) {
 	case FBIO_WAITFORVSYNC:
-		retval = sh_mobile_wait_for_vsync(info);
+		retval = sh_mobile_wait_for_vsync(info->par);
 		break;
 
 	default:
@@ -1040,7 +1118,8 @@
 static void sh_mobile_fb_reconfig(struct fb_info *info)
 {
 	struct sh_mobile_lcdc_chan *ch = info->par;
-	struct fb_videomode mode1, mode2;
+	struct fb_var_screeninfo var;
+	struct fb_videomode mode;
 	struct fb_event event;
 	int evnt = FB_EVENT_MODE_CHANGE_ALL;
 
@@ -1048,14 +1127,19 @@
 		/* More framebuffer users are active */
 		return;
 
-	fb_var_to_videomode(&mode1, &ch->display_var);
-	fb_var_to_videomode(&mode2, &info->var);
+	fb_var_to_videomode(&mode, &info->var);
 
-	if (fb_mode_is_equal(&mode1, &mode2))
+	if (fb_mode_is_equal(&ch->display.mode, &mode))
 		return;
 
 	/* Display has been re-plugged, framebuffer is free now, reconfigure */
-	if (fb_set_var(info, &ch->display_var) < 0)
+	var = info->var;
+	fb_videomode_to_var(&var, &ch->display.mode);
+	var.width = ch->display.width;
+	var.height = ch->display.height;
+	var.activate = FB_ACTIVATE_NOW;
+
+	if (fb_set_var(info, &var) < 0)
 		/* Couldn't reconfigure, hopefully, can continue as before */
 		return;
 
@@ -1065,7 +1149,7 @@
 	 * user event, we have to call the chain ourselves.
 	 */
 	event.info = info;
-	event.data = &mode1;
+	event.data = &ch->display.mode;
 	fb_notifier_call_chain(evnt, &event);
 }
 
@@ -1124,8 +1208,8 @@
 	 * distance between two modes is defined as the size of the
 	 * non-overlapping parts of the two rectangles.
 	 */
-	for (i = 0; i < ch->cfg.num_cfg; ++i) {
-		const struct fb_videomode *mode = &ch->cfg.lcd_cfg[i];
+	for (i = 0; i < ch->cfg->num_modes; ++i) {
+		const struct fb_videomode *mode = &ch->cfg->lcd_modes[i];
 		unsigned int dist;
 
 		/* We can only round up. */
@@ -1144,7 +1228,7 @@
 	}
 
 	/* If no available mode can be used, return an error. */
-	if (ch->cfg.num_cfg != 0) {
+	if (ch->cfg->num_modes != 0) {
 		if (best_dist == (unsigned int)-1)
 			return -EINVAL;
 
@@ -1161,32 +1245,17 @@
 		var->yres_virtual = var->yres;
 
 	if (sh_mobile_format_is_fourcc(var)) {
-		switch (var->grayscale) {
-		case V4L2_PIX_FMT_NV12:
-		case V4L2_PIX_FMT_NV21:
-			var->bits_per_pixel = 12;
-			break;
-		case V4L2_PIX_FMT_RGB565:
-		case V4L2_PIX_FMT_NV16:
-		case V4L2_PIX_FMT_NV61:
-			var->bits_per_pixel = 16;
-			break;
-		case V4L2_PIX_FMT_BGR24:
-		case V4L2_PIX_FMT_NV24:
-		case V4L2_PIX_FMT_NV42:
-			var->bits_per_pixel = 24;
-			break;
-		case V4L2_PIX_FMT_BGR32:
-			var->bits_per_pixel = 32;
-			break;
-		default:
+		const struct sh_mobile_lcdc_format_info *format;
+
+		format = sh_mobile_format_info(var->grayscale);
+		if (format == NULL)
 			return -EINVAL;
-		}
+		var->bits_per_pixel = format->bpp;
 
 		/* Default to RGB and JPEG color-spaces for RGB and YUV formats
 		 * respectively.
 		 */
-		if (!sh_mobile_format_is_yuv(var))
+		if (!format->yuv)
 			var->colorspace = V4L2_COLORSPACE_SRGB;
 		else if (var->colorspace != V4L2_COLORSPACE_REC709)
 			var->colorspace = V4L2_COLORSPACE_JPEG;
@@ -1246,22 +1315,28 @@
 static int sh_mobile_set_par(struct fb_info *info)
 {
 	struct sh_mobile_lcdc_chan *ch = info->par;
-	u32 line_length = info->fix.line_length;
 	int ret;
 
 	sh_mobile_lcdc_stop(ch->lcdc);
 
-	if (sh_mobile_format_is_yuv(&info->var))
-		info->fix.line_length = info->var.xres;
+	ch->format = sh_mobile_format_info(sh_mobile_format_fourcc(&info->var));
+	ch->colorspace = info->var.colorspace;
+
+	ch->xres = info->var.xres;
+	ch->xres_virtual = info->var.xres_virtual;
+	ch->yres = info->var.yres;
+	ch->yres_virtual = info->var.yres_virtual;
+
+	if (ch->format->yuv)
+		ch->pitch = info->var.xres;
 	else
-		info->fix.line_length = info->var.xres
-				      * info->var.bits_per_pixel / 8;
+		ch->pitch = info->var.xres * ch->format->bpp / 8;
 
 	ret = sh_mobile_lcdc_start(ch->lcdc);
-	if (ret < 0) {
+	if (ret < 0)
 		dev_err(info->dev, "%s: unable to restart LCDC\n", __func__);
-		info->fix.line_length = line_length;
-	}
+
+	info->fix.line_length = ch->pitch;
 
 	if (sh_mobile_format_is_fourcc(&info->var)) {
 		info->fix.type = FB_TYPE_FOURCC;
@@ -1290,8 +1365,8 @@
 	/* blank the screen? */
 	if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) {
 		struct fb_fillrect rect = {
-			.width = info->var.xres,
-			.height = info->var.yres,
+			.width = ch->xres,
+			.height = ch->yres,
 		};
 		sh_mobile_lcdc_fillrect(info, &rect);
 	}
@@ -1307,8 +1382,8 @@
 		 * mode will reenable the clocks and update the screen in time,
 		 * so it does not need this. */
 		if (!info->fbdefio) {
-			sh_mobile_wait_for_vsync(info);
-			sh_mobile_wait_for_vsync(info);
+			sh_mobile_wait_for_vsync(ch);
+			sh_mobile_wait_for_vsync(ch);
 		}
 		sh_mobile_lcdc_clk_off(p);
 	}
@@ -1334,25 +1409,161 @@
 	.fb_set_par	= sh_mobile_set_par,
 };
 
+static void
+sh_mobile_lcdc_channel_fb_unregister(struct sh_mobile_lcdc_chan *ch)
+{
+	if (ch->info && ch->info->dev)
+		unregister_framebuffer(ch->info);
+}
+
+static int __devinit
+sh_mobile_lcdc_channel_fb_register(struct sh_mobile_lcdc_chan *ch)
+{
+	struct fb_info *info = ch->info;
+	int ret;
+
+	if (info->fbdefio) {
+		ch->sglist = vmalloc(sizeof(struct scatterlist) *
+				     ch->fb_size >> PAGE_SHIFT);
+		if (!ch->sglist) {
+			dev_err(ch->lcdc->dev, "cannot allocate sglist\n");
+			return -ENOMEM;
+		}
+	}
+
+	info->bl_dev = ch->bl;
+
+	ret = register_framebuffer(info);
+	if (ret < 0)
+		return ret;
+
+	dev_info(ch->lcdc->dev, "registered %s/%s as %dx%d %dbpp.\n",
+		 dev_name(ch->lcdc->dev), (ch->cfg->chan == LCDC_CHAN_MAINLCD) ?
+		 "mainlcd" : "sublcd", info->var.xres, info->var.yres,
+		 info->var.bits_per_pixel);
+
+	/* deferred io mode: disable clock to save power */
+	if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED)
+		sh_mobile_lcdc_clk_off(ch->lcdc);
+
+	return ret;
+}
+
+static void
+sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch)
+{
+	struct fb_info *info = ch->info;
+
+	if (!info || !info->device)
+		return;
+
+	if (ch->sglist)
+		vfree(ch->sglist);
+
+	fb_dealloc_cmap(&info->cmap);
+	framebuffer_release(info);
+}
+
+static int __devinit
+sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
+			       const struct fb_videomode *mode,
+			       unsigned int num_modes)
+{
+	struct sh_mobile_lcdc_priv *priv = ch->lcdc;
+	struct fb_var_screeninfo *var;
+	struct fb_info *info;
+	int ret;
+
+	/* Allocate and initialize the frame buffer device. Create the modes
+	 * list and allocate the color map.
+	 */
+	info = framebuffer_alloc(0, priv->dev);
+	if (info == NULL) {
+		dev_err(priv->dev, "unable to allocate fb_info\n");
+		return -ENOMEM;
+	}
+
+	ch->info = info;
+
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &sh_mobile_lcdc_ops;
+	info->device = priv->dev;
+	info->screen_base = ch->fb_mem;
+	info->pseudo_palette = &ch->pseudo_palette;
+	info->par = ch;
+
+	fb_videomode_to_modelist(mode, num_modes, &info->modelist);
+
+	ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
+	if (ret < 0) {
+		dev_err(priv->dev, "unable to allocate cmap\n");
+		return ret;
+	}
+
+	/* Initialize fixed screen information. Restrict pan to 2 lines steps
+	 * for NV12 and NV21.
+	 */
+	info->fix = sh_mobile_lcdc_fix;
+	info->fix.smem_start = ch->dma_handle;
+	info->fix.smem_len = ch->fb_size;
+	info->fix.line_length = ch->pitch;
+
+	if (ch->format->yuv)
+		info->fix.visual = FB_VISUAL_FOURCC;
+	else
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	if (ch->format->fourcc == V4L2_PIX_FMT_NV12 ||
+	    ch->format->fourcc == V4L2_PIX_FMT_NV21)
+		info->fix.ypanstep = 2;
+
+	/* Initialize variable screen information using the first mode as
+	 * default. The default Y virtual resolution is twice the panel size to
+	 * allow for double-buffering.
+	 */
+	var = &info->var;
+	fb_videomode_to_var(var, mode);
+	var->width = ch->cfg->panel_cfg.width;
+	var->height = ch->cfg->panel_cfg.height;
+	var->yres_virtual = var->yres * 2;
+	var->activate = FB_ACTIVATE_NOW;
+
+	/* Use the legacy API by default for RGB formats, and the FOURCC API
+	 * for YUV formats.
+	 */
+	if (!ch->format->yuv)
+		var->bits_per_pixel = ch->format->bpp;
+	else
+		var->grayscale = ch->format->fourcc;
+
+	ret = sh_mobile_check_var(var, info);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Backlight
+ */
+
 static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
 {
 	struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
-	struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
 	int brightness = bdev->props.brightness;
 
 	if (bdev->props.power != FB_BLANK_UNBLANK ||
 	    bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
 		brightness = 0;
 
-	return cfg->set_brightness(cfg->board_data, brightness);
+	return ch->cfg->bl_info.set_brightness(brightness);
 }
 
 static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
 {
 	struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
-	struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
 
-	return cfg->get_brightness(cfg->board_data);
+	return ch->cfg->bl_info.get_brightness();
 }
 
 static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
@@ -1373,7 +1584,7 @@
 {
 	struct backlight_device *bl;
 
-	bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch,
+	bl = backlight_device_register(ch->cfg->bl_info.name, parent, ch,
 				       &sh_mobile_lcdc_bl_ops, NULL);
 	if (IS_ERR(bl)) {
 		dev_err(parent, "unable to register backlight device: %ld\n",
@@ -1381,7 +1592,7 @@
 		return NULL;
 	}
 
-	bl->props.max_brightness = ch->cfg.bl_info.max_brightness;
+	bl->props.max_brightness = ch->cfg->bl_info.max_brightness;
 	bl->props.brightness = bl->props.max_brightness;
 	backlight_update_status(bl);
 
@@ -1393,6 +1604,10 @@
 	backlight_device_unregister(bdev);
 }
 
+/* -----------------------------------------------------------------------------
+ * Power management
+ */
+
 static int sh_mobile_lcdc_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -1436,6 +1651,10 @@
 	.runtime_resume = sh_mobile_lcdc_runtime_resume,
 };
 
+/* -----------------------------------------------------------------------------
+ * Framebuffer notifier
+ */
+
 /* locking: called with info->lock held */
 static int sh_mobile_lcdc_notify(struct notifier_block *nb,
 				 unsigned long action, void *data)
@@ -1443,7 +1662,6 @@
 	struct fb_event *event = data;
 	struct fb_info *info = event->info;
 	struct sh_mobile_lcdc_chan *ch = info->par;
-	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
 
 	if (&ch->lcdc->notifier != nb)
 		return NOTIFY_DONE;
@@ -1453,10 +1671,7 @@
 
 	switch(action) {
 	case FB_EVENT_SUSPEND:
-		if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
-			board_cfg->display_off(board_cfg->board_data);
-			module_put(board_cfg->owner);
-		}
+		sh_mobile_lcdc_display_off(ch);
 		sh_mobile_lcdc_stop(ch->lcdc);
 		break;
 	case FB_EVENT_RESUME:
@@ -1464,47 +1679,60 @@
 		sh_mobile_fb_reconfig(info);
 		mutex_unlock(&ch->open_lock);
 
-		/* HDMI must be enabled before LCDC configuration */
-		if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
-			board_cfg->display_on(board_cfg->board_data, info);
-			module_put(board_cfg->owner);
-		}
-
+		sh_mobile_lcdc_display_on(ch);
 		sh_mobile_lcdc_start(ch->lcdc);
 	}
 
 	return NOTIFY_OK;
 }
 
+/* -----------------------------------------------------------------------------
+ * Probe/remove and driver init/exit
+ */
+
+static const struct fb_videomode default_720p __devinitconst = {
+	.name = "HDMI 720p",
+	.xres = 1280,
+	.yres = 720,
+
+	.left_margin = 220,
+	.right_margin = 110,
+	.hsync_len = 40,
+
+	.upper_margin = 20,
+	.lower_margin = 5,
+	.vsync_len = 5,
+
+	.pixclock = 13468,
+	.refresh = 60,
+	.sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+};
+
 static int sh_mobile_lcdc_remove(struct platform_device *pdev)
 {
 	struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
-	struct fb_info *info;
 	int i;
 
 	fb_unregister_client(&priv->notifier);
 
 	for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
-		if (priv->ch[i].info && priv->ch[i].info->dev)
-			unregister_framebuffer(priv->ch[i].info);
+		sh_mobile_lcdc_channel_fb_unregister(&priv->ch[i]);
 
 	sh_mobile_lcdc_stop(priv);
 
 	for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
-		info = priv->ch[i].info;
+		struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
 
-		if (!info || !info->device)
-			continue;
+		if (ch->tx_dev) {
+			ch->tx_dev->lcdc = NULL;
+			module_put(ch->cfg->tx_dev->dev.driver->owner);
+		}
 
-		if (priv->ch[i].sglist)
-			vfree(priv->ch[i].sglist);
+		sh_mobile_lcdc_channel_fb_cleanup(ch);
 
-		if (info->screen_base)
-			dma_free_coherent(&pdev->dev, info->fix.smem_len,
-					  info->screen_base,
-					  priv->ch[i].dma_handle);
-		fb_dealloc_cmap(&info->cmap);
-		framebuffer_release(info);
+		if (ch->fb_mem)
+			dma_free_coherent(&pdev->dev, ch->fb_size,
+					  ch->fb_mem, ch->dma_handle);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
@@ -1512,11 +1740,10 @@
 			sh_mobile_lcdc_bl_remove(priv->ch[i].bl);
 	}
 
-	if (priv->dot_clk)
+	if (priv->dot_clk) {
+		pm_runtime_disable(&pdev->dev);
 		clk_put(priv->dot_clk);
-
-	if (priv->dev)
-		pm_runtime_disable(priv->dev);
+	}
 
 	if (priv->base)
 		iounmap(priv->base);
@@ -1527,34 +1754,67 @@
 	return 0;
 }
 
-static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
-						 struct device *dev)
+static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
 {
-	struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
-	const struct fb_videomode *max_mode;
-	const struct fb_videomode *mode;
-	struct fb_var_screeninfo *var;
-	struct fb_info *info;
-	unsigned int max_size;
-	int num_cfg;
-	void *buf;
-	int ret;
-	int i;
+	int interface_type = ch->cfg->interface_type;
 
-	mutex_init(&ch->open_lock);
-
-	/* Allocate the frame buffer device. */
-	ch->info = framebuffer_alloc(0, dev);
-	if (!ch->info) {
-		dev_err(dev, "unable to allocate fb_info\n");
-		return -ENOMEM;
+	switch (interface_type) {
+	case RGB8:
+	case RGB9:
+	case RGB12A:
+	case RGB12B:
+	case RGB16:
+	case RGB18:
+	case RGB24:
+	case SYS8A:
+	case SYS8B:
+	case SYS8C:
+	case SYS8D:
+	case SYS9:
+	case SYS12:
+	case SYS16A:
+	case SYS16B:
+	case SYS16C:
+	case SYS18:
+	case SYS24:
+		break;
+	default:
+		return -EINVAL;
 	}
 
-	info = ch->info;
-	info->fbops = &sh_mobile_lcdc_ops;
-	info->par = ch;
-	info->pseudo_palette = &ch->pseudo_palette;
-	info->flags = FBINFO_FLAG_DEFAULT;
+	/* SUBLCD only supports SYS interface */
+	if (lcdc_chan_is_sublcd(ch)) {
+		if (!(interface_type & LDMT1R_IFM))
+			return -EINVAL;
+
+		interface_type &= ~LDMT1R_IFM;
+	}
+
+	ch->ldmt1r_value = interface_type;
+	return 0;
+}
+
+static int __devinit
+sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
+			    struct sh_mobile_lcdc_chan *ch)
+{
+	const struct sh_mobile_lcdc_format_info *format;
+	const struct sh_mobile_lcdc_chan_cfg *cfg = ch->cfg;
+	const struct fb_videomode *max_mode;
+	const struct fb_videomode *mode;
+	unsigned int num_modes;
+	unsigned int max_size;
+	unsigned int i;
+
+	mutex_init(&ch->open_lock);
+	ch->notify = sh_mobile_lcdc_display_notify;
+
+	/* Validate the format. */
+	format = sh_mobile_format_info(cfg->fourcc);
+	if (format == NULL) {
+		dev_err(priv->dev, "Invalid FOURCC %08x.\n", cfg->fourcc);
+		return -EINVAL;
+	}
 
 	/* Iterate through the modes to validate them and find the highest
 	 * resolution.
@@ -1562,14 +1822,14 @@
 	max_mode = NULL;
 	max_size = 0;
 
-	for (i = 0, mode = cfg->lcd_cfg; i < cfg->num_cfg; i++, mode++) {
+	for (i = 0, mode = cfg->lcd_modes; i < cfg->num_modes; i++, mode++) {
 		unsigned int size = mode->yres * mode->xres;
 
 		/* NV12/NV21 buffers must have even number of lines */
 		if ((cfg->fourcc == V4L2_PIX_FMT_NV12 ||
 		     cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) {
-			dev_err(dev, "yres must be multiple of 2 for YCbCr420 "
-				"mode.\n");
+			dev_err(priv->dev, "yres must be multiple of 2 for "
+				"YCbCr420 mode.\n");
 			return -EINVAL;
 		}
 
@@ -1582,93 +1842,59 @@
 	if (!max_size)
 		max_size = MAX_XRES * MAX_YRES;
 	else
-		dev_dbg(dev, "Found largest videomode %ux%u\n",
+		dev_dbg(priv->dev, "Found largest videomode %ux%u\n",
 			max_mode->xres, max_mode->yres);
 
-	/* Create the mode list. */
-	if (cfg->lcd_cfg == NULL) {
+	if (cfg->lcd_modes == NULL) {
 		mode = &default_720p;
-		num_cfg = 1;
+		num_modes = 1;
 	} else {
-		mode = cfg->lcd_cfg;
-		num_cfg = cfg->num_cfg;
+		mode = cfg->lcd_modes;
+		num_modes = cfg->num_modes;
 	}
 
-	fb_videomode_to_modelist(mode, num_cfg, &info->modelist);
+	/* Use the first mode as default. */
+	ch->format = format;
+	ch->xres = mode->xres;
+	ch->xres_virtual = mode->xres;
+	ch->yres = mode->yres;
+	ch->yres_virtual = mode->yres * 2;
 
-	/* Initialize variable screen information using the first mode as
-	 * default. The default Y virtual resolution is twice the panel size to
-	 * allow for double-buffering.
-	 */
-	var = &info->var;
-	fb_videomode_to_var(var, mode);
-	var->width = cfg->lcd_size_cfg.width;
-	var->height = cfg->lcd_size_cfg.height;
-	var->yres_virtual = var->yres * 2;
-	var->activate = FB_ACTIVATE_NOW;
-
-	switch (cfg->fourcc) {
-	case V4L2_PIX_FMT_RGB565:
-		var->bits_per_pixel = 16;
-		break;
-	case V4L2_PIX_FMT_BGR24:
-		var->bits_per_pixel = 24;
-		break;
-	case V4L2_PIX_FMT_BGR32:
-		var->bits_per_pixel = 32;
-		break;
-	default:
-		var->grayscale = cfg->fourcc;
-		break;
+	if (!format->yuv) {
+		ch->colorspace = V4L2_COLORSPACE_SRGB;
+		ch->pitch = ch->xres * format->bpp / 8;
+	} else {
+		ch->colorspace = V4L2_COLORSPACE_REC709;
+		ch->pitch = ch->xres;
 	}
 
-	/* Make sure the memory size check won't fail. smem_len is initialized
-	 * later based on var.
-	 */
-	info->fix.smem_len = UINT_MAX;
-	ret = sh_mobile_check_var(var, info);
-	if (ret)
-		return ret;
+	ch->display.width = cfg->panel_cfg.width;
+	ch->display.height = cfg->panel_cfg.height;
+	ch->display.mode = *mode;
 
-	max_size = max_size * var->bits_per_pixel / 8 * 2;
-
-	/* Allocate frame buffer memory and color map. */
-	buf = dma_alloc_coherent(dev, max_size, &ch->dma_handle, GFP_KERNEL);
-	if (!buf) {
-		dev_err(dev, "unable to allocate buffer\n");
+	/* Allocate frame buffer memory. */
+	ch->fb_size = max_size * format->bpp / 8 * 2;
+	ch->fb_mem = dma_alloc_coherent(priv->dev, ch->fb_size, &ch->dma_handle,
+					GFP_KERNEL);
+	if (ch->fb_mem == NULL) {
+		dev_err(priv->dev, "unable to allocate buffer\n");
 		return -ENOMEM;
 	}
 
-	ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
-	if (ret < 0) {
-		dev_err(dev, "unable to allocate cmap\n");
-		dma_free_coherent(dev, max_size, buf, ch->dma_handle);
-		return ret;
+	/* Initialize the transmitter device if present. */
+	if (cfg->tx_dev) {
+		if (!cfg->tx_dev->dev.driver ||
+		    !try_module_get(cfg->tx_dev->dev.driver->owner)) {
+			dev_warn(priv->dev,
+				 "unable to get transmitter device\n");
+			return -EINVAL;
+		}
+		ch->tx_dev = platform_get_drvdata(cfg->tx_dev);
+		ch->tx_dev->lcdc = ch;
+		ch->tx_dev->def_mode = *mode;
 	}
 
-	/* Initialize fixed screen information. Restrict pan to 2 lines steps
-	 * for NV12 and NV21.
-	 */
-	info->fix = sh_mobile_lcdc_fix;
-	info->fix.smem_start = ch->dma_handle;
-	info->fix.smem_len = max_size;
-	if (cfg->fourcc == V4L2_PIX_FMT_NV12 ||
-	    cfg->fourcc == V4L2_PIX_FMT_NV21)
-		info->fix.ypanstep = 2;
-
-	if (sh_mobile_format_is_yuv(var)) {
-		info->fix.line_length = var->xres;
-		info->fix.visual = FB_VISUAL_FOURCC;
-	} else {
-		info->fix.line_length = var->xres * var->bits_per_pixel / 8;
-		info->fix.visual = FB_VISUAL_TRUECOLOR;
-	}
-
-	info->screen_base = buf;
-	info->device = dev;
-	ch->display_var = *var;
-
-	return 0;
+	return sh_mobile_lcdc_channel_fb_init(ch, mode, num_modes);
 }
 
 static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
@@ -1698,6 +1924,8 @@
 		return -ENOMEM;
 	}
 
+	priv->dev = &pdev->dev;
+	priv->meram_dev = pdata->meram_dev;
 	platform_set_drvdata(pdev, priv);
 
 	error = request_irq(i, sh_mobile_lcdc_irq, 0,
@@ -1714,7 +1942,7 @@
 		struct sh_mobile_lcdc_chan *ch = priv->ch + num_channels;
 
 		ch->lcdc = priv;
-		memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
+		ch->cfg = &pdata->ch[i];
 
 		error = sh_mobile_lcdc_check_interface(ch);
 		if (error) {
@@ -1726,7 +1954,7 @@
 		ch->pan_offset = 0;
 
 		/* probe the backlight is there is one defined */
-		if (ch->cfg.bl_info.max_brightness)
+		if (ch->cfg->bl_info.max_brightness)
 			ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch);
 
 		switch (pdata->ch[i].chan) {
@@ -1757,18 +1985,19 @@
 	if (!priv->base)
 		goto err1;
 
-	error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
+	error = sh_mobile_lcdc_setup_clocks(priv, pdata->clock_source);
 	if (error) {
 		dev_err(&pdev->dev, "unable to setup clocks\n");
 		goto err1;
 	}
 
-	priv->meram_dev = pdata->meram_dev;
+	/* Enable runtime PM. */
+	pm_runtime_enable(&pdev->dev);
 
 	for (i = 0; i < num_channels; i++) {
 		struct sh_mobile_lcdc_chan *ch = priv->ch + i;
 
-		error = sh_mobile_lcdc_channel_init(ch, &pdev->dev);
+		error = sh_mobile_lcdc_channel_init(priv, ch);
 		if (error)
 			goto err1;
 	}
@@ -1781,31 +2010,10 @@
 
 	for (i = 0; i < num_channels; i++) {
 		struct sh_mobile_lcdc_chan *ch = priv->ch + i;
-		struct fb_info *info = ch->info;
 
-		if (info->fbdefio) {
-			ch->sglist = vmalloc(sizeof(struct scatterlist) *
-					info->fix.smem_len >> PAGE_SHIFT);
-			if (!ch->sglist) {
-				dev_err(&pdev->dev, "cannot allocate sglist\n");
-				goto err1;
-			}
-		}
-
-		info->bl_dev = ch->bl;
-
-		error = register_framebuffer(info);
-		if (error < 0)
+		error = sh_mobile_lcdc_channel_fb_register(ch);
+		if (error)
 			goto err1;
-
-		dev_info(info->dev, "registered %s/%s as %dx%d %dbpp.\n",
-			 pdev->name, (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
-			 "mainlcd" : "sublcd", info->var.xres, info->var.yres,
-			 info->var.bits_per_pixel);
-
-		/* deferred io mode: disable clock to save power */
-		if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED)
-			sh_mobile_lcdc_clk_off(priv);
 	}
 
 	/* Failure ignored */
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index a58a0f3..da1c26e 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -14,9 +14,35 @@
 
 #define PALETTE_NR 16
 
-struct sh_mobile_lcdc_priv;
-struct fb_info;
 struct backlight_device;
+struct fb_info;
+struct module;
+struct sh_mobile_lcdc_chan;
+struct sh_mobile_lcdc_entity;
+struct sh_mobile_lcdc_format_info;
+struct sh_mobile_lcdc_priv;
+
+#define SH_MOBILE_LCDC_DISPLAY_DISCONNECTED	0
+#define SH_MOBILE_LCDC_DISPLAY_CONNECTED	1
+
+struct sh_mobile_lcdc_entity_ops {
+	/* Display */
+	int (*display_on)(struct sh_mobile_lcdc_entity *entity);
+	void (*display_off)(struct sh_mobile_lcdc_entity *entity);
+};
+
+enum sh_mobile_lcdc_entity_event {
+	SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT,
+	SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT,
+	SH_MOBILE_LCDC_EVENT_DISPLAY_MODE,
+};
+
+struct sh_mobile_lcdc_entity {
+	struct module *owner;
+	const struct sh_mobile_lcdc_entity_ops *ops;
+	struct sh_mobile_lcdc_chan *lcdc;
+	struct fb_videomode def_mode;
+};
 
 /*
  * struct sh_mobile_lcdc_chan - LCDC display channel
@@ -27,29 +53,57 @@
  */
 struct sh_mobile_lcdc_chan {
 	struct sh_mobile_lcdc_priv *lcdc;
+	struct sh_mobile_lcdc_entity *tx_dev;
+	const struct sh_mobile_lcdc_chan_cfg *cfg;
+
 	unsigned long *reg_offs;
 	unsigned long ldmt1r_value;
 	unsigned long enabled; /* ME and SE in LDCNT2R */
-	struct sh_mobile_lcdc_chan_cfg cfg;
-	u32 pseudo_palette[PALETTE_NR];
-	struct fb_info *info;
-	struct backlight_device *bl;
+	void *meram;
+
+	struct mutex open_lock;		/* protects the use counter */
+	int use_count;
+
+	void *fb_mem;
+	unsigned long fb_size;
+
 	dma_addr_t dma_handle;
-	struct fb_deferred_io defio;
-	struct scatterlist *sglist;
-	unsigned long frame_end;
 	unsigned long pan_offset;
+
+	unsigned long frame_end;
 	wait_queue_head_t frame_end_wait;
 	struct completion vsync_completion;
-	struct fb_var_screeninfo display_var;
-	int use_count;
-	int blank_status;
-	struct mutex open_lock;		/* protects the use counter */
-	int meram_enabled;
+
+	const struct sh_mobile_lcdc_format_info *format;
+	u32 colorspace;
+	unsigned int xres;
+	unsigned int xres_virtual;
+	unsigned int yres;
+	unsigned int yres_virtual;
+	unsigned int pitch;
 
 	unsigned long base_addr_y;
 	unsigned long base_addr_c;
-	unsigned int pitch;
+
+	int (*notify)(struct sh_mobile_lcdc_chan *ch,
+		      enum sh_mobile_lcdc_entity_event event,
+		      const struct fb_videomode *mode,
+		      const struct fb_monspecs *monspec);
+
+	/* Backlight */
+	struct backlight_device *bl;
+
+	/* FB */
+	struct fb_info *info;
+	u32 pseudo_palette[PALETTE_NR];
+	struct {
+		unsigned int width;
+		unsigned int height;
+		struct fb_videomode mode;
+	} display;
+	struct fb_deferred_io defio;
+	struct scatterlist *sglist;
+	int blank_status;
 };
 
 #endif
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index f45d83e..82ba830 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -9,16 +9,22 @@
  * for more details.
  */
 
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/genalloc.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/device.h>
-#include <linux/pm_runtime.h>
-#include <linux/io.h>
-#include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
 #include <video/sh_mobile_meram.h>
 
-/* meram registers */
+/* -----------------------------------------------------------------------------
+ * MERAM registers
+ */
+
 #define MEVCR1			0x4
 #define MEVCR1_RST		(1 << 31)
 #define MEVCR1_WD		(1 << 30)
@@ -81,16 +87,14 @@
 	 ((yszm1) << MExxBSIZE_YSZM1_SHIFT) | \
 	 ((xszm1) << MExxBSIZE_XSZM1_SHIFT))
 
-#define SH_MOBILE_MERAM_ICB_NUM		32
-
-static unsigned long common_regs[] = {
+static const unsigned long common_regs[] = {
 	MEVCR1,
 	MEQSEL1,
 	MEQSEL2,
 };
-#define CMN_REGS_SIZE ARRAY_SIZE(common_regs)
+#define MERAM_REGS_SIZE ARRAY_SIZE(common_regs)
 
-static unsigned long icb_regs[] = {
+static const unsigned long icb_regs[] = {
 	MExxCTL,
 	MExxBSIZE,
 	MExxMNCF,
@@ -100,216 +104,269 @@
 };
 #define ICB_REGS_SIZE ARRAY_SIZE(icb_regs)
 
+/*
+ * sh_mobile_meram_icb - MERAM ICB information
+ * @regs: Registers cache
+ * @index: ICB index
+ * @offset: MERAM block offset
+ * @size: MERAM block size in KiB
+ * @cache_unit: Bytes to cache per ICB
+ * @pixelformat: Video pixel format of the data stored in the ICB
+ * @current_reg: Which of Start Address Register A (0) or B (1) is in use
+ */
+struct sh_mobile_meram_icb {
+	unsigned long regs[ICB_REGS_SIZE];
+	unsigned int index;
+	unsigned long offset;
+	unsigned int size;
+
+	unsigned int cache_unit;
+	unsigned int pixelformat;
+	unsigned int current_reg;
+};
+
+#define MERAM_ICB_NUM			32
+
+struct sh_mobile_meram_fb_plane {
+	struct sh_mobile_meram_icb *marker;
+	struct sh_mobile_meram_icb *cache;
+};
+
+struct sh_mobile_meram_fb_cache {
+	unsigned int nplanes;
+	struct sh_mobile_meram_fb_plane planes[2];
+};
+
+/*
+ * sh_mobile_meram_priv - MERAM device
+ * @base: Registers base address
+ * @meram: MERAM physical address
+ * @regs: Registers cache
+ * @lock: Protects used_icb and icbs
+ * @used_icb: Bitmask of used ICBs
+ * @icbs: ICBs
+ * @pool: Allocation pool to manage the MERAM
+ */
 struct sh_mobile_meram_priv {
-	void __iomem	*base;
-	struct mutex	lock;
-	unsigned long	used_icb;
-	int		used_meram_cache_regions;
-	unsigned long	used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
-	unsigned long	cmn_saved_regs[CMN_REGS_SIZE];
-	unsigned long	icb_saved_regs[ICB_REGS_SIZE * SH_MOBILE_MERAM_ICB_NUM];
+	void __iomem *base;
+	unsigned long meram;
+	unsigned long regs[MERAM_REGS_SIZE];
+
+	struct mutex lock;
+	unsigned long used_icb;
+	struct sh_mobile_meram_icb icbs[MERAM_ICB_NUM];
+
+	struct gen_pool *pool;
 };
 
 /* settings */
-#define MERAM_SEC_LINE 15
-#define MERAM_LINE_WIDTH 2048
+#define MERAM_GRANULARITY		1024
+#define MERAM_SEC_LINE			15
+#define MERAM_LINE_WIDTH		2048
 
-/*
- * MERAM/ICB access functions
+/* -----------------------------------------------------------------------------
+ * Registers access
  */
 
 #define MERAM_ICB_OFFSET(base, idx, off)	((base) + (off) + (idx) * 0x20)
 
-static inline void meram_write_icb(void __iomem *base, int idx, int off,
-	unsigned long val)
+static inline void meram_write_icb(void __iomem *base, unsigned int idx,
+				   unsigned int off, unsigned long val)
 {
 	iowrite32(val, MERAM_ICB_OFFSET(base, idx, off));
 }
 
-static inline unsigned long meram_read_icb(void __iomem *base, int idx, int off)
+static inline unsigned long meram_read_icb(void __iomem *base, unsigned int idx,
+					   unsigned int off)
 {
 	return ioread32(MERAM_ICB_OFFSET(base, idx, off));
 }
 
-static inline void meram_write_reg(void __iomem *base, int off,
-		unsigned long val)
+static inline void meram_write_reg(void __iomem *base, unsigned int off,
+				   unsigned long val)
 {
 	iowrite32(val, base + off);
 }
 
-static inline unsigned long meram_read_reg(void __iomem *base, int off)
+static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off)
 {
 	return ioread32(base + off);
 }
 
-/*
- * register ICB
+/* -----------------------------------------------------------------------------
+ * Allocation
  */
 
-#define MERAM_CACHE_START(p)	 ((p) >> 16)
-#define MERAM_CACHE_END(p)	 ((p) & 0xffff)
-#define MERAM_CACHE_SET(o, s)	 ((((o) & 0xffff) << 16) | \
-				  (((o) + (s) - 1) & 0xffff))
-
-/*
- * check if there's no overlaps in MERAM allocation.
- */
-
-static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv,
-				      struct sh_mobile_meram_icb *new)
+/* Allocate ICBs and MERAM for a plane. */
+static int __meram_alloc(struct sh_mobile_meram_priv *priv,
+			 struct sh_mobile_meram_fb_plane *plane,
+			 size_t size)
 {
-	int i;
-	int used_start, used_end, meram_start, meram_end;
+	unsigned long mem;
+	unsigned long idx;
 
-	/* valid ICB? */
-	if (new->marker_icb & ~0x1f || new->cache_icb & ~0x1f)
-		return 1;
+	idx = find_first_zero_bit(&priv->used_icb, 28);
+	if (idx == 28)
+		return -ENOMEM;
+	plane->cache = &priv->icbs[idx];
 
-	if (test_bit(new->marker_icb, &priv->used_icb) ||
-			test_bit(new->cache_icb,  &priv->used_icb))
-		return  1;
+	idx = find_next_zero_bit(&priv->used_icb, 32, 28);
+	if (idx == 32)
+		return -ENOMEM;
+	plane->marker = &priv->icbs[idx];
 
-	for (i = 0; i < priv->used_meram_cache_regions; i++) {
-		used_start = MERAM_CACHE_START(priv->used_meram_cache[i]);
-		used_end   = MERAM_CACHE_END(priv->used_meram_cache[i]);
-		meram_start = new->meram_offset;
-		meram_end   = new->meram_offset + new->meram_size;
+	mem = gen_pool_alloc(priv->pool, size * 1024);
+	if (mem == 0)
+		return -ENOMEM;
 
-		if ((meram_start >= used_start && meram_start < used_end) ||
-			(meram_end > used_start && meram_end < used_end))
-			return 1;
-	}
+	__set_bit(plane->marker->index, &priv->used_icb);
+	__set_bit(plane->cache->index, &priv->used_icb);
+
+	plane->marker->offset = mem - priv->meram;
+	plane->marker->size = size;
 
 	return 0;
 }
 
-/*
- * mark the specified ICB as used
- */
-
-static inline void meram_mark(struct sh_mobile_meram_priv *priv,
-			      struct sh_mobile_meram_icb *new)
+/* Free ICBs and MERAM for a plane. */
+static void __meram_free(struct sh_mobile_meram_priv *priv,
+			 struct sh_mobile_meram_fb_plane *plane)
 {
-	int n;
+	gen_pool_free(priv->pool, priv->meram + plane->marker->offset,
+		      plane->marker->size * 1024);
 
-	if (new->marker_icb < 0 || new->cache_icb < 0)
-		return;
-
-	__set_bit(new->marker_icb, &priv->used_icb);
-	__set_bit(new->cache_icb, &priv->used_icb);
-
-	n = priv->used_meram_cache_regions;
-
-	priv->used_meram_cache[n] = MERAM_CACHE_SET(new->meram_offset,
-						    new->meram_size);
-
-	priv->used_meram_cache_regions++;
+	__clear_bit(plane->marker->index, &priv->used_icb);
+	__clear_bit(plane->cache->index, &priv->used_icb);
 }
 
-/*
- * unmark the specified ICB as used
- */
-
-static inline void meram_unmark(struct sh_mobile_meram_priv *priv,
-				struct sh_mobile_meram_icb *icb)
-{
-	int i;
-	unsigned long pattern;
-
-	if (icb->marker_icb < 0 || icb->cache_icb < 0)
-		return;
-
-	__clear_bit(icb->marker_icb, &priv->used_icb);
-	__clear_bit(icb->cache_icb, &priv->used_icb);
-
-	pattern = MERAM_CACHE_SET(icb->meram_offset, icb->meram_size);
-	for (i = 0; i < priv->used_meram_cache_regions; i++) {
-		if (priv->used_meram_cache[i] == pattern) {
-			while (i < priv->used_meram_cache_regions - 1) {
-				priv->used_meram_cache[i] =
-					priv->used_meram_cache[i + 1] ;
-				i++;
-			}
-			priv->used_meram_cache[i] = 0;
-			priv->used_meram_cache_regions--;
-			break;
-		}
-	}
-}
-
-/*
- * is this a YCbCr(NV12, NV16 or NV24) colorspace
- */
-static inline int is_nvcolor(int cspace)
+/* Is this a YCbCr(NV12, NV16 or NV24) colorspace? */
+static int is_nvcolor(int cspace)
 {
 	if (cspace == SH_MOBILE_MERAM_PF_NV ||
-			cspace == SH_MOBILE_MERAM_PF_NV24)
+	    cspace == SH_MOBILE_MERAM_PF_NV24)
 		return 1;
 	return 0;
 }
 
-/*
- * set the next address to fetch
- */
-static inline void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
-				       struct sh_mobile_meram_cfg *cfg,
-				       unsigned long base_addr_y,
-				       unsigned long base_addr_c)
+/* Allocate memory for the ICBs and mark them as used. */
+static struct sh_mobile_meram_fb_cache *
+meram_alloc(struct sh_mobile_meram_priv *priv,
+	    const struct sh_mobile_meram_cfg *cfg,
+	    int pixelformat)
 {
+	struct sh_mobile_meram_fb_cache *cache;
+	unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
+	int ret;
+
+	if (cfg->icb[0].meram_size == 0)
+		return ERR_PTR(-EINVAL);
+
+	if (nplanes == 2 && cfg->icb[1].meram_size == 0)
+		return ERR_PTR(-EINVAL);
+
+	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
+	if (cache == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	cache->nplanes = nplanes;
+
+	ret = __meram_alloc(priv, &cache->planes[0], cfg->icb[0].meram_size);
+	if (ret < 0)
+		goto error;
+
+	cache->planes[0].marker->current_reg = 1;
+	cache->planes[0].marker->pixelformat = pixelformat;
+
+	if (cache->nplanes == 1)
+		return cache;
+
+	ret = __meram_alloc(priv, &cache->planes[1], cfg->icb[1].meram_size);
+	if (ret < 0) {
+		__meram_free(priv, &cache->planes[0]);
+		goto error;
+	}
+
+	return cache;
+
+error:
+	kfree(cache);
+	return ERR_PTR(-ENOMEM);
+}
+
+/* Unmark the specified ICB as used. */
+static void meram_free(struct sh_mobile_meram_priv *priv,
+		       struct sh_mobile_meram_fb_cache *cache)
+{
+	__meram_free(priv, &cache->planes[0]);
+	if (cache->nplanes == 2)
+		__meram_free(priv, &cache->planes[1]);
+
+	kfree(cache);
+}
+
+/* Set the next address to fetch. */
+static void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
+				struct sh_mobile_meram_fb_cache *cache,
+				unsigned long base_addr_y,
+				unsigned long base_addr_c)
+{
+	struct sh_mobile_meram_icb *icb = cache->planes[0].marker;
 	unsigned long target;
 
-	target = (cfg->current_reg) ? MExxSARA : MExxSARB;
-	cfg->current_reg ^= 1;
+	icb->current_reg ^= 1;
+	target = icb->current_reg ? MExxSARB : MExxSARA;
 
 	/* set the next address to fetch */
-	meram_write_icb(priv->base, cfg->icb[0].cache_icb,  target,
+	meram_write_icb(priv->base, cache->planes[0].cache->index, target,
 			base_addr_y);
-	meram_write_icb(priv->base, cfg->icb[0].marker_icb, target,
-			base_addr_y + cfg->icb[0].cache_unit);
+	meram_write_icb(priv->base, cache->planes[0].marker->index, target,
+			base_addr_y + cache->planes[0].marker->cache_unit);
 
-	if (is_nvcolor(cfg->pixelformat)) {
-		meram_write_icb(priv->base, cfg->icb[1].cache_icb,  target,
-				base_addr_c);
-		meram_write_icb(priv->base, cfg->icb[1].marker_icb, target,
-				base_addr_c + cfg->icb[1].cache_unit);
+	if (cache->nplanes == 2) {
+		meram_write_icb(priv->base, cache->planes[1].cache->index,
+				target, base_addr_c);
+		meram_write_icb(priv->base, cache->planes[1].marker->index,
+				target, base_addr_c +
+				cache->planes[1].marker->cache_unit);
 	}
 }
 
-/*
- * get the next ICB address
- */
-static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
-					   struct sh_mobile_meram_cfg *cfg,
-					   unsigned long *icb_addr_y,
-					   unsigned long *icb_addr_c)
+/* Get the next ICB address. */
+static void
+meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
+			struct sh_mobile_meram_fb_cache *cache,
+			unsigned long *icb_addr_y, unsigned long *icb_addr_c)
 {
+	struct sh_mobile_meram_icb *icb = cache->planes[0].marker;
 	unsigned long icb_offset;
 
 	if (pdata->addr_mode == SH_MOBILE_MERAM_MODE0)
-		icb_offset = 0x80000000 | (cfg->current_reg << 29);
+		icb_offset = 0x80000000 | (icb->current_reg << 29);
 	else
-		icb_offset = 0xc0000000 | (cfg->current_reg << 23);
+		icb_offset = 0xc0000000 | (icb->current_reg << 23);
 
-	*icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24);
-	if (is_nvcolor(cfg->pixelformat))
-		*icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24);
+	*icb_addr_y = icb_offset | (cache->planes[0].marker->index << 24);
+	if (cache->nplanes == 2)
+		*icb_addr_c = icb_offset
+			    | (cache->planes[1].marker->index << 24);
 }
 
 #define MERAM_CALC_BYTECOUNT(x, y) \
 	(((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1))
 
-/*
- * initialize MERAM
- */
-
+/* Initialize MERAM. */
 static int meram_init(struct sh_mobile_meram_priv *priv,
-		      struct sh_mobile_meram_icb *icb,
-		      int xres, int yres, int *out_pitch)
+		      struct sh_mobile_meram_fb_plane *plane,
+		      unsigned int xres, unsigned int yres,
+		      unsigned int *out_pitch)
 {
+	struct sh_mobile_meram_icb *marker = plane->marker;
 	unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres);
 	unsigned long bnm;
-	int lcdc_pitch, xpitch, line_cnt;
-	int save_lines;
+	unsigned int lcdc_pitch;
+	unsigned int xpitch;
+	unsigned int line_cnt;
+	unsigned int save_lines;
 
 	/* adjust pitch to 1024, 2048, 4096 or 8192 */
 	lcdc_pitch = (xres - 1) | 1023;
@@ -322,13 +379,13 @@
 		lcdc_pitch = xpitch = MERAM_LINE_WIDTH;
 		line_cnt = total_byte_count >> 11;
 		*out_pitch = xres;
-		save_lines = (icb->meram_size / 16 / MERAM_SEC_LINE);
+		save_lines = plane->marker->size / 16 / MERAM_SEC_LINE;
 		save_lines *= MERAM_SEC_LINE;
 	} else {
 		xpitch = xres;
 		line_cnt = yres;
 		*out_pitch = lcdc_pitch;
-		save_lines = icb->meram_size / (lcdc_pitch >> 10) / 2;
+		save_lines = plane->marker->size / (lcdc_pitch >> 10) / 2;
 		save_lines &= 0xff;
 	}
 	bnm = (save_lines - 1) << 16;
@@ -336,19 +393,20 @@
 	/* TODO: we better to check if we have enough MERAM buffer size */
 
 	/* set up ICB */
-	meram_write_icb(priv->base, icb->cache_icb,  MExxBSIZE,
+	meram_write_icb(priv->base, plane->cache->index,  MExxBSIZE,
 			MERAM_MExxBSIZE_VAL(0x0, line_cnt - 1, xpitch - 1));
-	meram_write_icb(priv->base, icb->marker_icb, MExxBSIZE,
+	meram_write_icb(priv->base, plane->marker->index, MExxBSIZE,
 			MERAM_MExxBSIZE_VAL(0xf, line_cnt - 1, xpitch - 1));
 
-	meram_write_icb(priv->base, icb->cache_icb,  MExxMNCF, bnm);
-	meram_write_icb(priv->base, icb->marker_icb, MExxMNCF, bnm);
+	meram_write_icb(priv->base, plane->cache->index,  MExxMNCF, bnm);
+	meram_write_icb(priv->base, plane->marker->index, MExxMNCF, bnm);
 
-	meram_write_icb(priv->base, icb->cache_icb,  MExxSBSIZE, xpitch);
-	meram_write_icb(priv->base, icb->marker_icb, MExxSBSIZE, xpitch);
+	meram_write_icb(priv->base, plane->cache->index,  MExxSBSIZE, xpitch);
+	meram_write_icb(priv->base, plane->marker->index, MExxSBSIZE, xpitch);
 
 	/* save a cache unit size */
-	icb->cache_unit = xres * save_lines;
+	plane->cache->cache_unit = xres * save_lines;
+	plane->marker->cache_unit = xres * save_lines;
 
 	/*
 	 * Set MERAM for framebuffer
@@ -356,13 +414,13 @@
 	 * we also chain the cache_icb and the marker_icb.
 	 * we also split the allocated MERAM buffer between two ICBs.
 	 */
-	meram_write_icb(priv->base, icb->cache_icb, MExxCTL,
-			MERAM_MExxCTL_VAL(icb->marker_icb, icb->meram_offset) |
-			MExxCTL_WD1 | MExxCTL_WD0 | MExxCTL_WS | MExxCTL_CM |
+	meram_write_icb(priv->base, plane->cache->index, MExxCTL,
+			MERAM_MExxCTL_VAL(plane->marker->index, marker->offset)
+			| MExxCTL_WD1 | MExxCTL_WD0 | MExxCTL_WS | MExxCTL_CM |
 			MExxCTL_MD_FB);
-	meram_write_icb(priv->base, icb->marker_icb, MExxCTL,
-			MERAM_MExxCTL_VAL(icb->cache_icb, icb->meram_offset +
-					  icb->meram_size / 2) |
+	meram_write_icb(priv->base, plane->marker->index, MExxCTL,
+			MERAM_MExxCTL_VAL(plane->cache->index, marker->offset +
+					  plane->marker->size / 2) |
 			MExxCTL_WD1 | MExxCTL_WD0 | MExxCTL_WS | MExxCTL_CM |
 			MExxCTL_MD_FB);
 
@@ -370,221 +428,106 @@
 }
 
 static void meram_deinit(struct sh_mobile_meram_priv *priv,
-			struct sh_mobile_meram_icb *icb)
+			 struct sh_mobile_meram_fb_plane *plane)
 {
 	/* disable ICB */
-	meram_write_icb(priv->base, icb->cache_icb,  MExxCTL,
+	meram_write_icb(priv->base, plane->cache->index,  MExxCTL,
 			MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF);
-	meram_write_icb(priv->base, icb->marker_icb, MExxCTL,
+	meram_write_icb(priv->base, plane->marker->index, MExxCTL,
 			MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF);
-	icb->cache_unit = 0;
+
+	plane->cache->cache_unit = 0;
+	plane->marker->cache_unit = 0;
 }
 
-/*
- * register the ICB
+/* -----------------------------------------------------------------------------
+ * Registration/unregistration
  */
 
-static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
-				    struct sh_mobile_meram_cfg *cfg,
-				    int xres, int yres, int pixelformat,
-				    unsigned long base_addr_y,
-				    unsigned long base_addr_c,
-				    unsigned long *icb_addr_y,
-				    unsigned long *icb_addr_c,
-				    int *pitch)
+static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
+				      const struct sh_mobile_meram_cfg *cfg,
+				      unsigned int xres, unsigned int yres,
+				      unsigned int pixelformat,
+				      unsigned int *pitch)
 {
-	struct platform_device *pdev;
-	struct sh_mobile_meram_priv *priv;
-	int n, out_pitch;
-	int error = 0;
-
-	if (!pdata || !pdata->priv || !pdata->pdev || !cfg)
-		return -EINVAL;
+	struct sh_mobile_meram_fb_cache *cache;
+	struct sh_mobile_meram_priv *priv = pdata->priv;
+	struct platform_device *pdev = pdata->pdev;
+	unsigned int out_pitch;
 
 	if (pixelformat != SH_MOBILE_MERAM_PF_NV &&
 	    pixelformat != SH_MOBILE_MERAM_PF_NV24 &&
 	    pixelformat != SH_MOBILE_MERAM_PF_RGB)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 
-	priv = pdata->priv;
-	pdev = pdata->pdev;
-
-	dev_dbg(&pdev->dev, "registering %dx%d (%s) (y=%08lx, c=%08lx)",
-		xres, yres, (!pixelformat) ? "yuv" : "rgb",
-		base_addr_y, base_addr_c);
+	dev_dbg(&pdev->dev, "registering %dx%d (%s)", xres, yres,
+		!pixelformat ? "yuv" : "rgb");
 
 	/* we can't handle wider than 8192px */
 	if (xres > 8192) {
 		dev_err(&pdev->dev, "width exceeding the limit (> 8192).");
-		return -EINVAL;
-	}
-
-	/* do we have at least one ICB config? */
-	if (cfg->icb[0].marker_icb < 0 || cfg->icb[0].cache_icb < 0) {
-		dev_err(&pdev->dev, "at least one ICB is required.");
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	mutex_lock(&priv->lock);
 
-	if (priv->used_meram_cache_regions + 2 > SH_MOBILE_MERAM_ICB_NUM) {
-		dev_err(&pdev->dev, "no more ICB available.");
-		error = -EINVAL;
+	/* We now register the ICBs and allocate the MERAM regions. */
+	cache = meram_alloc(priv, cfg, pixelformat);
+	if (IS_ERR(cache)) {
+		dev_err(&pdev->dev, "MERAM allocation failed (%ld).",
+			PTR_ERR(cache));
 		goto err;
 	}
 
-	/* make sure that there's no overlaps */
-	if (meram_check_overlap(priv, &cfg->icb[0])) {
-		dev_err(&pdev->dev, "conflicting config detected.");
-		error = -EINVAL;
-		goto err;
-	}
-	n = 1;
-
-	/* do the same if we have the second ICB set */
-	if (cfg->icb[1].marker_icb >= 0 && cfg->icb[1].cache_icb >= 0) {
-		if (meram_check_overlap(priv, &cfg->icb[1])) {
-			dev_err(&pdev->dev, "conflicting config detected.");
-			error = -EINVAL;
-			goto err;
-		}
-		n = 2;
-	}
-
-	if (is_nvcolor(pixelformat) && n != 2) {
-		dev_err(&pdev->dev, "requires two ICB sets for planar Y/C.");
-		error =  -EINVAL;
-		goto err;
-	}
-
-	/* we now register the ICB */
-	cfg->pixelformat = pixelformat;
-	meram_mark(priv, &cfg->icb[0]);
-	if (is_nvcolor(pixelformat))
-		meram_mark(priv, &cfg->icb[1]);
-
 	/* initialize MERAM */
-	meram_init(priv, &cfg->icb[0], xres, yres, &out_pitch);
+	meram_init(priv, &cache->planes[0], xres, yres, &out_pitch);
 	*pitch = out_pitch;
 	if (pixelformat == SH_MOBILE_MERAM_PF_NV)
-		meram_init(priv, &cfg->icb[1], xres, (yres + 1) / 2,
+		meram_init(priv, &cache->planes[1], xres, (yres + 1) / 2,
 			&out_pitch);
 	else if (pixelformat == SH_MOBILE_MERAM_PF_NV24)
-		meram_init(priv, &cfg->icb[1], 2 * xres, (yres + 1) / 2,
+		meram_init(priv, &cache->planes[1], 2 * xres, (yres + 1) / 2,
 			&out_pitch);
 
-	cfg->current_reg = 1;
-	meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c);
-	meram_get_next_icb_addr(pdata, cfg, icb_addr_y, icb_addr_c);
-
-	dev_dbg(&pdev->dev, "registered - can access via y=%08lx, c=%08lx",
-		*icb_addr_y, *icb_addr_c);
-
 err:
 	mutex_unlock(&priv->lock);
-	return error;
+	return cache;
 }
 
-static int sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata,
-				      struct sh_mobile_meram_cfg *cfg)
+static void
+sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata, void *data)
 {
-	struct sh_mobile_meram_priv *priv;
-
-	if (!pdata || !pdata->priv || !cfg)
-		return -EINVAL;
-
-	priv = pdata->priv;
+	struct sh_mobile_meram_fb_cache *cache = data;
+	struct sh_mobile_meram_priv *priv = pdata->priv;
 
 	mutex_lock(&priv->lock);
 
-	/* deinit & unmark */
-	if (is_nvcolor(cfg->pixelformat)) {
-		meram_deinit(priv, &cfg->icb[1]);
-		meram_unmark(priv, &cfg->icb[1]);
-	}
-	meram_deinit(priv, &cfg->icb[0]);
-	meram_unmark(priv, &cfg->icb[0]);
+	/* deinit & free */
+	meram_deinit(priv, &cache->planes[0]);
+	if (cache->nplanes == 2)
+		meram_deinit(priv, &cache->planes[1]);
+
+	meram_free(priv, cache);
 
 	mutex_unlock(&priv->lock);
-
-	return 0;
 }
 
-static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata,
-				  struct sh_mobile_meram_cfg *cfg,
-				  unsigned long base_addr_y,
-				  unsigned long base_addr_c,
-				  unsigned long *icb_addr_y,
-				  unsigned long *icb_addr_c)
+static void
+sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, void *data,
+		       unsigned long base_addr_y, unsigned long base_addr_c,
+		       unsigned long *icb_addr_y, unsigned long *icb_addr_c)
 {
-	struct sh_mobile_meram_priv *priv;
-
-	if (!pdata || !pdata->priv || !cfg)
-		return -EINVAL;
-
-	priv = pdata->priv;
+	struct sh_mobile_meram_fb_cache *cache = data;
+	struct sh_mobile_meram_priv *priv = pdata->priv;
 
 	mutex_lock(&priv->lock);
 
-	meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c);
-	meram_get_next_icb_addr(pdata, cfg, icb_addr_y, icb_addr_c);
+	meram_set_next_addr(priv, cache, base_addr_y, base_addr_c);
+	meram_get_next_icb_addr(pdata, cache, icb_addr_y, icb_addr_c);
 
 	mutex_unlock(&priv->lock);
-
-	return 0;
 }
 
-static int sh_mobile_meram_runtime_suspend(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
-	int k, j;
-
-	for (k = 0; k < CMN_REGS_SIZE; k++)
-		priv->cmn_saved_regs[k] = meram_read_reg(priv->base,
-			common_regs[k]);
-
-	for (j = 0; j < 32; j++) {
-		if (!test_bit(j, &priv->used_icb))
-			continue;
-		for (k = 0; k < ICB_REGS_SIZE; k++) {
-			priv->icb_saved_regs[j * ICB_REGS_SIZE + k] =
-				meram_read_icb(priv->base, j, icb_regs[k]);
-			/* Reset ICB on resume */
-			if (icb_regs[k] == MExxCTL)
-				priv->icb_saved_regs[j * ICB_REGS_SIZE + k] |=
-					MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF;
-		}
-	}
-	return 0;
-}
-
-static int sh_mobile_meram_runtime_resume(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
-	int k, j;
-
-	for (j = 0; j < 32; j++) {
-		if (!test_bit(j, &priv->used_icb))
-			continue;
-		for (k = 0; k < ICB_REGS_SIZE; k++) {
-			meram_write_icb(priv->base, j, icb_regs[k],
-			priv->icb_saved_regs[j * ICB_REGS_SIZE + k]);
-		}
-	}
-
-	for (k = 0; k < CMN_REGS_SIZE; k++)
-		meram_write_reg(priv->base, common_regs[k],
-			priv->cmn_saved_regs[k]);
-	return 0;
-}
-
-static const struct dev_pm_ops sh_mobile_meram_dev_pm_ops = {
-	.runtime_suspend = sh_mobile_meram_runtime_suspend,
-	.runtime_resume = sh_mobile_meram_runtime_resume,
-};
-
 static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
 	.module			= THIS_MODULE,
 	.meram_register		= sh_mobile_meram_register,
@@ -592,17 +535,68 @@
 	.meram_update		= sh_mobile_meram_update,
 };
 
-/*
- * initialize MERAM
+/* -----------------------------------------------------------------------------
+ * Power management
  */
 
-static int sh_mobile_meram_remove(struct platform_device *pdev);
+static int sh_mobile_meram_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
+	unsigned int i, j;
+
+	for (i = 0; i < MERAM_REGS_SIZE; i++)
+		priv->regs[i] = meram_read_reg(priv->base, common_regs[i]);
+
+	for (i = 0; i < 32; i++) {
+		if (!test_bit(i, &priv->used_icb))
+			continue;
+		for (j = 0; j < ICB_REGS_SIZE; j++) {
+			priv->icbs[i].regs[j] =
+				meram_read_icb(priv->base, i, icb_regs[j]);
+			/* Reset ICB on resume */
+			if (icb_regs[j] == MExxCTL)
+				priv->icbs[i].regs[j] |=
+					MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF;
+		}
+	}
+	return 0;
+}
+
+static int sh_mobile_meram_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
+	unsigned int i, j;
+
+	for (i = 0; i < 32; i++) {
+		if (!test_bit(i, &priv->used_icb))
+			continue;
+		for (j = 0; j < ICB_REGS_SIZE; j++)
+			meram_write_icb(priv->base, i, icb_regs[j],
+					priv->icbs[i].regs[j]);
+	}
+
+	for (i = 0; i < MERAM_REGS_SIZE; i++)
+		meram_write_reg(priv->base, common_regs[i], priv->regs[i]);
+	return 0;
+}
+
+static UNIVERSAL_DEV_PM_OPS(sh_mobile_meram_dev_pm_ops,
+			    sh_mobile_meram_suspend,
+			    sh_mobile_meram_resume, NULL);
+
+/* -----------------------------------------------------------------------------
+ * Probe/remove and driver init/exit
+ */
 
 static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
 {
 	struct sh_mobile_meram_priv *priv;
 	struct sh_mobile_meram_info *pdata = pdev->dev.platform_data;
-	struct resource *res;
+	struct resource *regs;
+	struct resource *meram;
+	unsigned int i;
 	int error;
 
 	if (!pdata) {
@@ -610,8 +604,9 @@
 		return -EINVAL;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	meram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (regs == NULL || meram == NULL) {
 		dev_err(&pdev->dev, "cannot get platform resources\n");
 		return -ENOENT;
 	}
@@ -622,32 +617,74 @@
 		return -ENOMEM;
 	}
 
-	platform_set_drvdata(pdev, priv);
-
-	/* initialize private data */
+	/* Initialize private data. */
 	mutex_init(&priv->lock);
-	priv->base = ioremap_nocache(res->start, resource_size(res));
-	if (!priv->base) {
-		dev_err(&pdev->dev, "ioremap failed\n");
-		error = -EFAULT;
-		goto err;
-	}
+	priv->used_icb = pdata->reserved_icbs;
+
+	for (i = 0; i < MERAM_ICB_NUM; ++i)
+		priv->icbs[i].index = i;
+
 	pdata->ops = &sh_mobile_meram_ops;
 	pdata->priv = priv;
 	pdata->pdev = pdev;
 
+	/* Request memory regions and remap the registers. */
+	if (!request_mem_region(regs->start, resource_size(regs), pdev->name)) {
+		dev_err(&pdev->dev, "MERAM registers region already claimed\n");
+		error = -EBUSY;
+		goto err_req_regs;
+	}
+
+	if (!request_mem_region(meram->start, resource_size(meram),
+				pdev->name)) {
+		dev_err(&pdev->dev, "MERAM memory region already claimed\n");
+		error = -EBUSY;
+		goto err_req_meram;
+	}
+
+	priv->base = ioremap_nocache(regs->start, resource_size(regs));
+	if (!priv->base) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		error = -EFAULT;
+		goto err_ioremap;
+	}
+
+	priv->meram = meram->start;
+
+	/* Create and initialize the MERAM memory pool. */
+	priv->pool = gen_pool_create(ilog2(MERAM_GRANULARITY), -1);
+	if (priv->pool == NULL) {
+		error = -ENOMEM;
+		goto err_genpool;
+	}
+
+	error = gen_pool_add(priv->pool, meram->start, resource_size(meram),
+			     -1);
+	if (error < 0)
+		goto err_genpool;
+
 	/* initialize ICB addressing mode */
 	if (pdata->addr_mode == SH_MOBILE_MERAM_MODE1)
 		meram_write_reg(priv->base, MEVCR1, MEVCR1_AMD1);
 
+	platform_set_drvdata(pdev, priv);
 	pm_runtime_enable(&pdev->dev);
 
 	dev_info(&pdev->dev, "sh_mobile_meram initialized.");
 
 	return 0;
 
-err:
-	sh_mobile_meram_remove(pdev);
+err_genpool:
+	if (priv->pool)
+		gen_pool_destroy(priv->pool);
+	iounmap(priv->base);
+err_ioremap:
+	release_mem_region(meram->start, resource_size(meram));
+err_req_meram:
+	release_mem_region(regs->start, resource_size(regs));
+err_req_regs:
+	mutex_destroy(&priv->lock);
+	kfree(priv);
 
 	return error;
 }
@@ -656,11 +693,16 @@
 static int sh_mobile_meram_remove(struct platform_device *pdev)
 {
 	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
+	struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct resource *meram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 
 	pm_runtime_disable(&pdev->dev);
 
-	if (priv->base)
-		iounmap(priv->base);
+	gen_pool_destroy(priv->pool);
+
+	iounmap(priv->base);
+	release_mem_region(meram->start, resource_size(meram));
+	release_mem_region(regs->start, resource_size(regs));
 
 	mutex_destroy(&priv->lock);
 
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index a197731..157df78 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -72,6 +72,7 @@
 static bool console = 1; /* Allow fbcon to open framebuffer */
 static bool fb_defio = 1;  /* Detect mmap writes using page faults */
 static bool shadow = 1; /* Optionally disable shadow framebuffer */
+static int pixel_limit; /* Optionally force a pixel resolution limit */
 
 /* dlfb keeps a list of urbs for efficient bulk transfers */
 static void dlfb_urb_completion(struct urb *urb);
@@ -918,10 +919,6 @@
 {
 	struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
 
-	/* this function will wait for all in-flight urbs to complete */
-	if (dev->urbs.count > 0)
-		dlfb_free_urb_list(dev);
-
 	if (dev->backing_buffer)
 		vfree(dev->backing_buffer);
 
@@ -940,35 +937,42 @@
 	up(&unode->dev->urbs.limit_sem);
 }
 
-static void dlfb_free_framebuffer_work(struct work_struct *work)
+static void dlfb_free_framebuffer(struct dlfb_data *dev)
 {
-	struct dlfb_data *dev = container_of(work, struct dlfb_data,
-					     free_framebuffer_work.work);
 	struct fb_info *info = dev->info;
-	int node = info->node;
 
-	unregister_framebuffer(info);
+	if (info) {
+		int node = info->node;
 
-	if (info->cmap.len != 0)
-		fb_dealloc_cmap(&info->cmap);
-	if (info->monspecs.modedb)
-		fb_destroy_modedb(info->monspecs.modedb);
-	if (info->screen_base)
-		vfree(info->screen_base);
+		unregister_framebuffer(info);
 
-	fb_destroy_modelist(&info->modelist);
+		if (info->cmap.len != 0)
+			fb_dealloc_cmap(&info->cmap);
+		if (info->monspecs.modedb)
+			fb_destroy_modedb(info->monspecs.modedb);
+		if (info->screen_base)
+			vfree(info->screen_base);
 
-	dev->info = 0;
+		fb_destroy_modelist(&info->modelist);
 
-	/* Assume info structure is freed after this point */
-	framebuffer_release(info);
+		dev->info = NULL;
 
-	pr_warn("fb_info for /dev/fb%d has been freed\n", node);
+		/* Assume info structure is freed after this point */
+		framebuffer_release(info);
+
+		pr_warn("fb_info for /dev/fb%d has been freed\n", node);
+	}
 
 	/* ref taken in probe() as part of registering framebfufer */
 	kref_put(&dev->kref, dlfb_free);
 }
 
+static void dlfb_free_framebuffer_work(struct work_struct *work)
+{
+	struct dlfb_data *dev = container_of(work, struct dlfb_data,
+					     free_framebuffer_work.work);
+	dlfb_free_framebuffer(dev);
+}
 /*
  * Assumes caller is holding info->lock mutex (for open and release at least)
  */
@@ -1012,7 +1016,8 @@
 		return 0;
 	}
 
-	pr_info("%dx%d valid mode\n", mode->xres, mode->yres);
+	pr_info("%dx%d @ %d Hz valid mode\n", mode->xres, mode->yres,
+		mode->refresh);
 
 	return 1;
 }
@@ -1427,19 +1432,22 @@
 	struct device *fbdev = container_of(kobj, struct device, kobj);
 	struct fb_info *fb_info = dev_get_drvdata(fbdev);
 	struct dlfb_data *dev = fb_info->par;
+	int ret;
 
 	/* We only support write of entire EDID at once, no offset*/
 	if ((src_size != EDID_LENGTH) || (src_off != 0))
-		return 0;
+		return -EINVAL;
 
-	dlfb_setup_modes(dev, fb_info, src, src_size);
+	ret = dlfb_setup_modes(dev, fb_info, src, src_size);
+	if (ret)
+		return ret;
 
-	if (dev->edid && (memcmp(src, dev->edid, src_size) == 0)) {
-		pr_info("sysfs written EDID is new default\n");
-		dlfb_ops_set_par(fb_info);
-		return src_size;
-	} else
-		return 0;
+	if (!dev->edid || memcmp(src, dev->edid, src_size))
+		return -EINVAL;
+
+	pr_info("sysfs written EDID is new default\n");
+	dlfb_ops_set_par(fb_info);
+	return src_size;
 }
 
 static ssize_t metrics_reset_store(struct device *fbdev,
@@ -1537,7 +1545,7 @@
 			u8 length;
 			u16 key;
 
-			key = *((u16 *) desc);
+			key = le16_to_cpu(*((u16 *) desc));
 			desc += sizeof(u16);
 			length = *desc;
 			desc++;
@@ -1570,14 +1578,15 @@
 	kfree(buf);
 	return true;
 }
+
+static void dlfb_init_framebuffer_work(struct work_struct *work);
+
 static int dlfb_usb_probe(struct usb_interface *interface,
 			const struct usb_device_id *id)
 {
 	struct usb_device *usbdev;
 	struct dlfb_data *dev = 0;
-	struct fb_info *info = 0;
 	int retval = -ENOMEM;
-	int i;
 
 	/* usb initialization */
 
@@ -1589,9 +1598,7 @@
 		goto error;
 	}
 
-	/* we need to wait for both usb and fbdev to spin down on disconnect */
 	kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
-	kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
 
 	dev->udev = usbdev;
 	dev->gdev = &usbdev->dev; /* our generic struct device * */
@@ -1613,16 +1620,53 @@
 		goto error;
 	}
 
+	if (pixel_limit) {
+		pr_warn("DL chip limit of %d overriden"
+			" by module param to %d\n",
+			dev->sku_pixel_limit, pixel_limit);
+		dev->sku_pixel_limit = pixel_limit;
+	}
+
+
 	if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
 		retval = -ENOMEM;
 		pr_err("dlfb_alloc_urb_list failed\n");
 		goto error;
 	}
 
+	kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
+
 	/* We don't register a new USB class. Our client interface is fbdev */
 
+	/* Workitem keep things fast & simple during USB enumeration */
+	INIT_DELAYED_WORK(&dev->init_framebuffer_work,
+			  dlfb_init_framebuffer_work);
+	schedule_delayed_work(&dev->init_framebuffer_work, 0);
+
+	return 0;
+
+error:
+	if (dev) {
+
+		kref_put(&dev->kref, dlfb_free); /* ref for framebuffer */
+		kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
+
+		/* dev has been deallocated. Do not dereference */
+	}
+
+	return retval;
+}
+
+static void dlfb_init_framebuffer_work(struct work_struct *work)
+{
+	struct dlfb_data *dev = container_of(work, struct dlfb_data,
+					     init_framebuffer_work.work);
+	struct fb_info *info;
+	int retval;
+	int i;
+
 	/* allocates framebuffer driver structure, not framebuffer memory */
-	info = framebuffer_alloc(0, &interface->dev);
+	info = framebuffer_alloc(0, dev->gdev);
 	if (!info) {
 		retval = -ENOMEM;
 		pr_err("framebuffer_alloc failed\n");
@@ -1668,15 +1712,13 @@
 	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) {
 		retval = device_create_file(info->dev, &fb_device_attrs[i]);
 		if (retval) {
-			pr_err("device_create_file failed %d\n", retval);
-			goto err_del_attrs;
+			pr_warn("device_create_file failed %d\n", retval);
 		}
 	}
 
 	retval = device_create_bin_file(info->dev, &edid_attr);
 	if (retval) {
-		pr_err("device_create_bin_file failed %d\n", retval);
-		goto err_del_attrs;
+		pr_warn("device_create_bin_file failed %d\n", retval);
 	}
 
 	pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
@@ -1684,38 +1726,10 @@
 			info->var.xres, info->var.yres,
 			((dev->backing_buffer) ?
 			info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
-	return 0;
-
-err_del_attrs:
-	for (i -= 1; i >= 0; i--)
-		device_remove_file(info->dev, &fb_device_attrs[i]);
+	return;
 
 error:
-	if (dev) {
-
-		if (info) {
-			if (info->cmap.len != 0)
-				fb_dealloc_cmap(&info->cmap);
-			if (info->monspecs.modedb)
-				fb_destroy_modedb(info->monspecs.modedb);
-			if (info->screen_base)
-				vfree(info->screen_base);
-
-			fb_destroy_modelist(&info->modelist);
-
-			framebuffer_release(info);
-		}
-
-		if (dev->backing_buffer)
-			vfree(dev->backing_buffer);
-
-		kref_put(&dev->kref, dlfb_free); /* ref for framebuffer */
-		kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
-
-		/* dev has been deallocated. Do not dereference */
-	}
-
-	return retval;
+	dlfb_free_framebuffer(dev);
 }
 
 static void dlfb_usb_disconnect(struct usb_interface *interface)
@@ -1735,12 +1749,24 @@
 	/* When non-active we'll update virtual framebuffer, but no new urbs */
 	atomic_set(&dev->usb_active, 0);
 
-	/* remove udlfb's sysfs interfaces */
-	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
-		device_remove_file(info->dev, &fb_device_attrs[i]);
-	device_remove_bin_file(info->dev, &edid_attr);
+	/* this function will wait for all in-flight urbs to complete */
+	dlfb_free_urb_list(dev);
+
+	if (info) {
+
+		/* remove udlfb's sysfs interfaces */
+		for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
+			device_remove_file(info->dev, &fb_device_attrs[i]);
+		device_remove_bin_file(info->dev, &edid_attr);
+
+		/* it's safe to uncomment next line if your kernel
+		   doesn't yet have this function exported */
+		unlink_framebuffer(info);
+	}
 
 	usb_set_intfdata(interface, NULL);
+	dev->udev = NULL;
+	dev->gdev = NULL;
 
 	/* if clients still have us open, will be freed on last close */
 	if (dev->fb_count == 0)
@@ -1806,12 +1832,12 @@
 	int ret;
 	unsigned long flags;
 
-	pr_notice("Waiting for completes and freeing all render urbs\n");
+	pr_notice("Freeing all render urbs\n");
 
 	/* keep waiting and freeing, until we've got 'em all */
 	while (count--) {
 
-		/* Getting interrupted means a leak, but ok at shutdown*/
+		/* Getting interrupted means a leak, but ok at disconnect */
 		ret = down_interruptible(&dev->urbs.limit_sem);
 		if (ret)
 			break;
@@ -1833,6 +1859,7 @@
 		kfree(node);
 	}
 
+	dev->urbs.count = 0;
 }
 
 static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
@@ -1948,6 +1975,9 @@
 module_param(shadow, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
 MODULE_PARM_DESC(shadow, "Shadow vid mem. Disable to save mem but lose perf");
 
+module_param(pixel_limit, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
+MODULE_PARM_DESC(pixel_limit, "Force limit on max mode (in x*y pixels)");
+
 MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, "
 	      "Jaya Kumar <jayakumar.lkml@gmail.com>, "
 	      "Bernie Thompson <bernie@plugable.com>");
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index e7f69ef..1f882ed 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -23,6 +23,7 @@
 #include <video/uvesafb.h>
 #ifdef CONFIG_X86
 #include <video/vga.h>
+#include <linux/pci.h>
 #endif
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
@@ -362,7 +363,7 @@
 
 	state = kmalloc(par->vbe_state_size, GFP_KERNEL);
 	if (!state)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	task = uvesafb_prep();
 	if (!task) {
@@ -815,8 +816,15 @@
 	par->pmi_setpal = pmi_setpal;
 	par->ypan = ypan;
 
-	if (par->pmi_setpal || par->ypan)
-		uvesafb_vbe_getpmi(task, par);
+	if (par->pmi_setpal || par->ypan) {
+		if (pcibios_enabled) {
+			uvesafb_vbe_getpmi(task, par);
+		} else {
+			par->pmi_setpal = par->ypan = 0;
+			printk(KERN_WARNING "uvesafb: PCI BIOS area is NX."
+				"Can't use protected mode interface\n");
+		}
+	}
 #else
 	/* The protected mode interface is not available on non-x86. */
 	par->pmi_setpal = par->ypan = 0;
@@ -1172,9 +1180,17 @@
 {
 	struct uvesafb_par *par = info->par;
 	int cnt = atomic_read(&par->ref_count);
+	u8 *buf = NULL;
 
-	if (!cnt && par->vbe_state_size)
-		par->vbe_state_orig = uvesafb_vbe_state_save(par);
+	if (!cnt && par->vbe_state_size) {
+		buf =  uvesafb_vbe_state_save(par);
+		if (IS_ERR(buf)) {
+			printk(KERN_WARNING "uvesafb: save hardware state"
+				"failed, error code is %ld!\n", PTR_ERR(buf));
+		} else {
+			par->vbe_state_orig = buf;
+		}
+	}
 
 	atomic_inc(&par->ref_count);
 	return 0;
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 1372ef4..898590d 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -1797,7 +1797,11 @@
 		break;
 	}
 
+	/* magic required on VX900 for correct modesetting on IGA1 */
+	via_write_reg_mask(VIACR, 0x45, 0x00, 0x01);
+
 	/* probably this should go to the scaling code one day */
+	via_write_reg_mask(VIACR, 0xFD, 0, 0x80); /* VX900 hw scale on IGA2 */
 	viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
 
 	/* Fill VPIT Parameters */
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 95aeedf..958e512 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -367,29 +367,45 @@
 #ifdef CONFIG_PM
 static int virtballoon_freeze(struct virtio_device *vdev)
 {
+	struct virtio_balloon *vb = vdev->priv;
+
 	/*
 	 * The kthread is already frozen by the PM core before this
 	 * function is called.
 	 */
 
+	while (vb->num_pages)
+		leak_balloon(vb, vb->num_pages);
+	update_balloon_size(vb);
+
 	/* Ensure we don't get any more requests from the host */
 	vdev->config->reset(vdev);
 	vdev->config->del_vqs(vdev);
 	return 0;
 }
 
+static int restore_common(struct virtio_device *vdev)
+{
+	struct virtio_balloon *vb = vdev->priv;
+	int ret;
+
+	ret = init_vqs(vdev->priv);
+	if (ret)
+		return ret;
+
+	fill_balloon(vb, towards_target(vb));
+	update_balloon_size(vb);
+	return 0;
+}
+
 static int virtballoon_thaw(struct virtio_device *vdev)
 {
-	return init_vqs(vdev->priv);
+	return restore_common(vdev);
 }
 
 static int virtballoon_restore(struct virtio_device *vdev)
 {
 	struct virtio_balloon *vb = vdev->priv;
-	struct page *page, *page2;
-
-	/* We're starting from a clean slate */
-	vb->num_pages = 0;
 
 	/*
 	 * If a request wasn't complete at the time of freezing, this
@@ -397,12 +413,7 @@
 	 */
 	vb->need_stats_update = 0;
 
-	/* We don't have these pages in the balloon anymore! */
-	list_for_each_entry_safe(page, page2, &vb->pages, lru) {
-		list_del(&page->lru);
-		totalram_pages++;
-	}
-	return init_vqs(vdev->priv);
+	return restore_common(vdev);
 }
 #endif
 
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 877b107..df9e8f0 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1098,7 +1098,7 @@
 	  For Freescale Book-E processors, this is a number between 0 and 63.
 	  For other Book-E processors, this is a number between 0 and 3.
 
-	  The value can be overidden by the wdt_period command-line parameter.
+	  The value can be overridden by the wdt_period command-line parameter.
 
 # PPC64 Architecture
 
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index 337265b..7c0fdfc 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -198,9 +198,13 @@
 		booke_wdt_period = tmp;
 #endif
 		booke_wdt_set();
-		return 0;
+		/* Fall */
 	case WDIOC_GETTIMEOUT:
+#ifdef	CONFIG_FSL_BOOKE
+		return put_user(period_to_sec(booke_wdt_period), p);
+#else
 		return put_user(booke_wdt_period, p);
+#endif
 	default:
 		return -ENOTTY;
 	}
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 8464ea1..3c166d3 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -231,7 +231,7 @@
 
 	cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
 
-	set_memory_x((unsigned long)bios32_entrypoint, (2 * PAGE_SIZE));
+	set_memory_x((unsigned long)bios32_map, 2);
 	asminline_call(&cmn_regs, bios32_entrypoint);
 
 	if (cmn_regs.u1.ral != 0) {
@@ -250,7 +250,8 @@
 			cru_rom_addr =
 				ioremap(cru_physical_address, cru_length);
 			if (cru_rom_addr) {
-				set_memory_x((unsigned long)cru_rom_addr, cru_length);
+				set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
+					(cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT);
 				retval = 0;
 			}
 		}
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 8e210aa..dfae030 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -264,7 +264,7 @@
 	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (wdt_mem == NULL) {
 		printk(KERN_INFO MODULE_NAME
-			"failed to get memory region resouce\n");
+			"failed to get memory region resource\n");
 		return -ENOENT;
 	}
 
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 4bc3744..404172f 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -312,18 +312,26 @@
 	dev = &pdev->dev;
 	wdt_dev = &pdev->dev;
 
-	/* get the memory region for the watchdog timer */
-
 	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (wdt_mem == NULL) {
 		dev_err(dev, "no memory resource specified\n");
 		return -ENOENT;
 	}
 
+	wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (wdt_irq == NULL) {
+		dev_err(dev, "no irq resource specified\n");
+		ret = -ENOENT;
+		goto err;
+	}
+
+	/* get the memory region for the watchdog timer */
+
 	size = resource_size(wdt_mem);
 	if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
 		dev_err(dev, "failed to get memory region\n");
-		return -EBUSY;
+		ret = -EBUSY;
+		goto err;
 	}
 
 	wdt_base = ioremap(wdt_mem->start, size);
@@ -335,29 +343,17 @@
 
 	DBG("probe: mapped wdt_base=%p\n", wdt_base);
 
-	wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (wdt_irq == NULL) {
-		dev_err(dev, "no irq resource specified\n");
-		ret = -ENOENT;
-		goto err_map;
-	}
-
-	ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
-	if (ret != 0) {
-		dev_err(dev, "failed to install irq (%d)\n", ret);
-		goto err_map;
-	}
-
 	wdt_clock = clk_get(&pdev->dev, "watchdog");
 	if (IS_ERR(wdt_clock)) {
 		dev_err(dev, "failed to find watchdog clock source\n");
 		ret = PTR_ERR(wdt_clock);
-		goto err_irq;
+		goto err_map;
 	}
 
 	clk_enable(wdt_clock);
 
-	if (s3c2410wdt_cpufreq_register() < 0) {
+	ret = s3c2410wdt_cpufreq_register();
+	if (ret < 0) {
 		printk(KERN_ERR PFX "failed to register cpufreq\n");
 		goto err_clk;
 	}
@@ -378,12 +374,18 @@
 							"cannot start\n");
 	}
 
+	ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
+	if (ret != 0) {
+		dev_err(dev, "failed to install irq (%d)\n", ret);
+		goto err_cpufreq;
+	}
+
 	watchdog_set_nowayout(&s3c2410_wdd, nowayout);
 
 	ret = watchdog_register_device(&s3c2410_wdd);
 	if (ret) {
 		dev_err(dev, "cannot register watchdog (%d)\n", ret);
-		goto err_cpufreq;
+		goto err_irq;
 	}
 
 	if (tmr_atboot && started == 0) {
@@ -408,23 +410,26 @@
 
 	return 0;
 
+ err_irq:
+	free_irq(wdt_irq->start, pdev);
+
  err_cpufreq:
 	s3c2410wdt_cpufreq_deregister();
 
  err_clk:
 	clk_disable(wdt_clock);
 	clk_put(wdt_clock);
-
- err_irq:
-	free_irq(wdt_irq->start, pdev);
+	wdt_clock = NULL;
 
  err_map:
 	iounmap(wdt_base);
 
  err_req:
 	release_mem_region(wdt_mem->start, size);
-	wdt_mem = NULL;
 
+ err:
+	wdt_irq = NULL;
+	wdt_mem = NULL;
 	return ret;
 }
 
@@ -432,18 +437,18 @@
 {
 	watchdog_unregister_device(&s3c2410_wdd);
 
+	free_irq(wdt_irq->start, dev);
+
 	s3c2410wdt_cpufreq_deregister();
 
 	clk_disable(wdt_clock);
 	clk_put(wdt_clock);
 	wdt_clock = NULL;
 
-	free_irq(wdt_irq->start, dev);
-	wdt_irq = NULL;
-
 	iounmap(wdt_base);
 
 	release_mem_region(wdt_mem->start, resource_size(wdt_mem));
+	wdt_irq = NULL;
 	wdt_mem = NULL;
 	return 0;
 }
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index 14e2d99..4dcfced 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -30,7 +30,8 @@
 	sprintf(dir, "cpu/%u", cpu);
 	err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
 	if (err != 1) {
-		printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
+		if (!xen_initial_domain())
+			printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
 		return err;
 	}
 
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 7944a17..19834d1 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -884,7 +884,7 @@
 	int err;
 
 	err =
-	    sscanf(buf, " %04x:%02x:%02x.%1x-%08x:%1x:%08x", domain, bus, slot,
+	    sscanf(buf, " %04x:%02x:%02x.%d-%08x:%1x:%08x", domain, bus, slot,
 		   func, reg, size, mask);
 	if (err == 7)
 		return 0;
@@ -904,7 +904,7 @@
 	pci_dev_id->bus = bus;
 	pci_dev_id->devfn = PCI_DEVFN(slot, func);
 
-	pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%01x\n",
+	pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n",
 		 domain, bus, slot, func);
 
 	spin_lock_irqsave(&device_ids_lock, flags);
@@ -934,7 +934,7 @@
 
 			err = 0;
 
-			pr_debug(DRV_NAME ": removed %04x:%02x:%02x.%01x from "
+			pr_debug(DRV_NAME ": removed %04x:%02x:%02x.%d from "
 				 "seize list\n", domain, bus, slot, func);
 		}
 	}
@@ -1029,7 +1029,7 @@
 			break;
 
 		count += scnprintf(buf + count, PAGE_SIZE - count,
-				   "%04x:%02x:%02x.%01x\n",
+				   "%04x:%02x:%02x.%d\n",
 				   pci_dev_id->domain, pci_dev_id->bus,
 				   PCI_SLOT(pci_dev_id->devfn),
 				   PCI_FUNC(pci_dev_id->devfn));
diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c
index d5dcf8d..64b11f9 100644
--- a/drivers/xen/xen-pciback/xenbus.c
+++ b/drivers/xen/xen-pciback/xenbus.c
@@ -206,6 +206,7 @@
 		goto out;
 	}
 
+	/* Note: The PV protocol uses %02x, don't change it */
 	err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
 			    "%04x:%02x:%02x.%02x", domain, bus,
 			    PCI_SLOT(devfn), PCI_FUNC(devfn));
@@ -229,7 +230,7 @@
 		err = -EINVAL;
 		xenbus_dev_fatal(pdev->xdev, err,
 				 "Couldn't locate PCI device "
-				 "(%04x:%02x:%02x.%01x)! "
+				 "(%04x:%02x:%02x.%d)! "
 				 "perhaps already in-use?",
 				 domain, bus, slot, func);
 		goto out;
@@ -274,7 +275,7 @@
 	if (!dev) {
 		err = -EINVAL;
 		dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device "
-			"(%04x:%02x:%02x.%01x)! not owned by this domain\n",
+			"(%04x:%02x:%02x.%d)! not owned by this domain\n",
 			domain, bus, slot, func);
 		goto out;
 	}
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index 527dc2a..89f7625 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -369,6 +369,10 @@
 		goto out;
 	}
 	token++;
+	if (memchr(token, 0, u->u.msg.len - (token - path)) == NULL) {
+		rc = -EILSEQ;
+		goto out;
+	}
 
 	if (msg_type == XS_WATCH) {
 		watch = alloc_watch_adapter(path, token);
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index d8d8e7b..eb1cc92 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -110,6 +110,7 @@
 	int sub_version;
 	int min_proto;
 	int max_proto;
+	int compat_daemon;
 	unsigned long exp_timeout;
 	unsigned int type;
 	int reghost_enabled;
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 76741d8..85f1fcd 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -385,6 +385,7 @@
 		sbi->pipefd = pipefd;
 		sbi->pipe = pipe;
 		sbi->catatonic = 0;
+		sbi->compat_daemon = is_compat_task();
 	}
 out:
 	mutex_unlock(&sbi->wq_mutex);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 450f529..1feb68e 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -124,6 +124,7 @@
 	/* Negative dentry - try next */
 	if (!simple_positive(q)) {
 		spin_unlock(&p->d_lock);
+		lock_set_subclass(&q->d_lock.dep_map, 0, _RET_IP_);
 		p = q;
 		goto again;
 	}
@@ -186,6 +187,7 @@
 	/* Negative dentry - try next */
 	if (!simple_positive(ret)) {
 		spin_unlock(&p->d_lock);
+		lock_set_subclass(&ret->d_lock.dep_map, 0, _RET_IP_);
 		p = ret;
 		goto again;
 	}
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index e16980b..06858d9 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -19,6 +19,7 @@
 #include <linux/parser.h>
 #include <linux/bitops.h>
 #include <linux/magic.h>
+#include <linux/compat.h>
 #include "autofs_i.h"
 #include <linux/module.h>
 
@@ -224,6 +225,7 @@
 	set_autofs_type_indirect(&sbi->type);
 	sbi->min_proto = 0;
 	sbi->max_proto = 0;
+	sbi->compat_daemon = is_compat_task();
 	mutex_init(&sbi->wq_mutex);
 	mutex_init(&sbi->pipe_mutex);
 	spin_lock_init(&sbi->fs_lock);
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index da8876d..9c098db 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -91,7 +91,24 @@
 
 	return (bytes > 0);
 }
-	
+
+/*
+ * The autofs_v5 packet was misdesigned.
+ *
+ * The packets are identical on x86-32 and x86-64, but have different
+ * alignment. Which means that 'sizeof()' will give different results.
+ * Fix it up for the case of running 32-bit user mode on a 64-bit kernel.
+ */
+static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi)
+{
+	size_t pktsz = sizeof(struct autofs_v5_packet);
+#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
+	if (sbi->compat_daemon > 0)
+		pktsz -= 4;
+#endif
+	return pktsz;
+}
+
 static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
 				 struct autofs_wait_queue *wq,
 				 int type)
@@ -155,8 +172,7 @@
 	{
 		struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet;
 
-		pktsz = sizeof(*packet);
-
+		pktsz = autofs_v5_packet_size(sbi);
 		packet->wait_queue_token = wq->wait_queue_token;
 		packet->len = wq->name.len;
 		memcpy(packet->name, wq->name.name, wq->name.len);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index bcb884e..07d096c 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1421,7 +1421,7 @@
 	for (i = 1; i < view->n; ++i) {
 		const struct user_regset *regset = &view->regsets[i];
 		do_thread_regset_writeback(t->task, regset);
-		if (regset->core_note_type &&
+		if (regset->core_note_type && regset->get &&
 		    (!regset->active || regset->active(t->task, regset))) {
 			int ret;
 			size_t size = regset->n * regset->size;
diff --git a/fs/bio.c b/fs/bio.c
index b1fe82c..b980ecd 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -505,13 +505,9 @@
 int bio_get_nr_vecs(struct block_device *bdev)
 {
 	struct request_queue *q = bdev_get_queue(bdev);
-	int nr_pages;
-
-	nr_pages = ((queue_max_sectors(q) << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	if (nr_pages > queue_max_segments(q))
-		nr_pages = queue_max_segments(q);
-
-	return nr_pages;
+	return min_t(unsigned,
+		     queue_max_segments(q),
+		     queue_max_sectors(q) / (PAGE_SIZE >> 9) + 1);
 }
 EXPORT_SYMBOL(bio_get_nr_vecs);
 
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 633c701..98f6bf10 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -892,6 +892,8 @@
 		if (eb != eb_in)
 			free_extent_buffer(eb);
 		ret = inode_ref_info(parent, 0, fs_root, path, &found_key);
+		if (ret > 0)
+			ret = -ENOENT;
 		if (ret)
 			break;
 		next_inum = found_key.offset;
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index b669a7d..d986824 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -644,7 +644,7 @@
 static int btrfsic_process_superblock(struct btrfsic_state *state,
 				      struct btrfs_fs_devices *fs_devices)
 {
-	int ret;
+	int ret = 0;
 	struct btrfs_super_block *selected_super;
 	struct list_head *dev_head = &fs_devices->devices;
 	struct btrfs_device *device;
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 14f1c5a..d02c27c 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -588,6 +588,8 @@
 				   page_offset(bio->bi_io_vec->bv_page),
 				   PAGE_CACHE_SIZE);
 	read_unlock(&em_tree->lock);
+	if (!em)
+		return -EIO;
 
 	compressed_len = em->block_len;
 	cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 27ebe61..80b6486 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -886,7 +886,7 @@
 	u64 reserved;
 	struct btrfs_space_info *space_info;
 	spinlock_t lock;
-	unsigned int full:1;
+	unsigned int full;
 };
 
 /*
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 811d9f9..534266f 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2260,6 +2260,12 @@
 		goto fail_sb_buffer;
 	}
 
+	if (sectorsize < PAGE_SIZE) {
+		printk(KERN_WARNING "btrfs: Incompatible sector size "
+		       "found on %s\n", sb->s_id);
+		goto fail_sb_buffer;
+	}
+
 	mutex_lock(&fs_info->chunk_mutex);
 	ret = btrfs_read_sys_array(tree_root);
 	mutex_unlock(&fs_info->chunk_mutex);
@@ -2301,6 +2307,12 @@
 
 	btrfs_close_extra_devices(fs_devices);
 
+	if (!fs_devices->latest_bdev) {
+		printk(KERN_CRIT "btrfs: failed to read devices on %s\n",
+		       sb->s_id);
+		goto fail_tree_roots;
+	}
+
 retry_root_backup:
 	blocksize = btrfs_level_size(tree_root,
 				     btrfs_super_root_level(disk_super));
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 283af7a..37e0a80 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3312,7 +3312,8 @@
 	}
 	data_sinfo->bytes_may_use += bytes;
 	trace_btrfs_space_reservation(root->fs_info, "space_info",
-				      (u64)data_sinfo, bytes, 1);
+				      (u64)(unsigned long)data_sinfo,
+				      bytes, 1);
 	spin_unlock(&data_sinfo->lock);
 
 	return 0;
@@ -3333,7 +3334,8 @@
 	spin_lock(&data_sinfo->lock);
 	data_sinfo->bytes_may_use -= bytes;
 	trace_btrfs_space_reservation(root->fs_info, "space_info",
-				      (u64)data_sinfo, bytes, 0);
+				      (u64)(unsigned long)data_sinfo,
+				      bytes, 0);
 	spin_unlock(&data_sinfo->lock);
 }
 
@@ -3611,12 +3613,15 @@
 	if (space_info != delayed_rsv->space_info)
 		return -ENOSPC;
 
+	spin_lock(&space_info->lock);
 	spin_lock(&delayed_rsv->lock);
-	if (delayed_rsv->size < bytes) {
+	if (space_info->bytes_pinned + delayed_rsv->size < bytes) {
 		spin_unlock(&delayed_rsv->lock);
+		spin_unlock(&space_info->lock);
 		return -ENOSPC;
 	}
 	spin_unlock(&delayed_rsv->lock);
+	spin_unlock(&space_info->lock);
 
 commit:
 	trans = btrfs_join_transaction(root);
@@ -3695,9 +3700,9 @@
 		if (used + orig_bytes <= space_info->total_bytes) {
 			space_info->bytes_may_use += orig_bytes;
 			trace_btrfs_space_reservation(root->fs_info,
-						      "space_info",
-						      (u64)space_info,
-						      orig_bytes, 1);
+					      "space_info",
+					      (u64)(unsigned long)space_info,
+					      orig_bytes, 1);
 			ret = 0;
 		} else {
 			/*
@@ -3766,9 +3771,9 @@
 		if (used + num_bytes < space_info->total_bytes + avail) {
 			space_info->bytes_may_use += orig_bytes;
 			trace_btrfs_space_reservation(root->fs_info,
-						      "space_info",
-						      (u64)space_info,
-						      orig_bytes, 1);
+					      "space_info",
+					      (u64)(unsigned long)space_info,
+					      orig_bytes, 1);
 			ret = 0;
 		} else {
 			wait_ordered = true;
@@ -3913,8 +3918,8 @@
 			spin_lock(&space_info->lock);
 			space_info->bytes_may_use -= num_bytes;
 			trace_btrfs_space_reservation(fs_info, "space_info",
-						      (u64)space_info,
-						      num_bytes, 0);
+					      (u64)(unsigned long)space_info,
+					      num_bytes, 0);
 			space_info->reservation_progress++;
 			spin_unlock(&space_info->lock);
 		}
@@ -4105,7 +4110,7 @@
 	num_bytes += div64_u64(data_used + meta_used, 50);
 
 	if (num_bytes * 3 > meta_used)
-		num_bytes = div64_u64(meta_used, 3);
+		num_bytes = div64_u64(meta_used, 3) * 2;
 
 	return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10);
 }
@@ -4132,14 +4137,14 @@
 		block_rsv->reserved += num_bytes;
 		sinfo->bytes_may_use += num_bytes;
 		trace_btrfs_space_reservation(fs_info, "space_info",
-					      (u64)sinfo, num_bytes, 1);
+				      (u64)(unsigned long)sinfo, num_bytes, 1);
 	}
 
 	if (block_rsv->reserved >= block_rsv->size) {
 		num_bytes = block_rsv->reserved - block_rsv->size;
 		sinfo->bytes_may_use -= num_bytes;
 		trace_btrfs_space_reservation(fs_info, "space_info",
-					      (u64)sinfo, num_bytes, 0);
+				      (u64)(unsigned long)sinfo, num_bytes, 0);
 		sinfo->reservation_progress++;
 		block_rsv->reserved = block_rsv->size;
 		block_rsv->full = 1;
@@ -4192,7 +4197,8 @@
 	if (!trans->bytes_reserved)
 		return;
 
-	trace_btrfs_space_reservation(root->fs_info, "transaction", (u64)trans,
+	trace_btrfs_space_reservation(root->fs_info, "transaction",
+				      (u64)(unsigned long)trans,
 				      trans->bytes_reserved, 0);
 	btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
 	trans->bytes_reserved = 0;
@@ -4710,9 +4716,9 @@
 			space_info->bytes_reserved += num_bytes;
 			if (reserve == RESERVE_ALLOC) {
 				trace_btrfs_space_reservation(cache->fs_info,
-							      "space_info",
-							      (u64)space_info,
-							      num_bytes, 0);
+					      "space_info",
+					      (u64)(unsigned long)space_info,
+					      num_bytes, 0);
 				space_info->bytes_may_use -= num_bytes;
 			}
 		}
@@ -7886,9 +7892,16 @@
 	u64 start;
 	u64 end;
 	u64 trimmed = 0;
+	u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
 	int ret = 0;
 
-	cache = btrfs_lookup_block_group(fs_info, range->start);
+	/*
+	 * try to trim all FS space, our block group may start from non-zero.
+	 */
+	if (range->len == total_bytes)
+		cache = btrfs_lookup_first_block_group(fs_info, range->start);
+	else
+		cache = btrfs_lookup_block_group(fs_info, range->start);
 
 	while (cache) {
 		if (cache->key.objectid >= (range->start + range->len)) {
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index fcf77e1..a55fbe6 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -513,6 +513,15 @@
 	WARN_ON(state->end < start);
 	last_end = state->end;
 
+	if (state->end < end && !need_resched())
+		next_node = rb_next(&state->rb_node);
+	else
+		next_node = NULL;
+
+	/* the state doesn't have the wanted bits, go ahead */
+	if (!(state->state & bits))
+		goto next;
+
 	/*
 	 *     | ---- desired range ---- |
 	 *  | state | or
@@ -565,20 +574,15 @@
 		goto out;
 	}
 
-	if (state->end < end && prealloc && !need_resched())
-		next_node = rb_next(&state->rb_node);
-	else
-		next_node = NULL;
-
 	set |= clear_state_bit(tree, state, &bits, wake);
+next:
 	if (last_end == (u64)-1)
 		goto out;
 	start = last_end + 1;
 	if (start <= end && next_node) {
 		state = rb_entry(next_node, struct extent_state,
 				 rb_node);
-		if (state->start == start)
-			goto hit_next;
+		goto hit_next;
 	}
 	goto search_again;
 
@@ -961,8 +965,6 @@
 
 		set_state_bits(tree, state, &bits);
 		clear_state_bit(tree, state, &clear_bits, 0);
-
-		merge_state(tree, state);
 		if (last_end == (u64)-1)
 			goto out;
 
@@ -1007,7 +1009,6 @@
 		if (state->end <= end) {
 			set_state_bits(tree, state, &bits);
 			clear_state_bit(tree, state, &clear_bits, 0);
-			merge_state(tree, state);
 			if (last_end == (u64)-1)
 				goto out;
 			start = last_end + 1;
@@ -1068,8 +1069,6 @@
 
 		set_state_bits(tree, prealloc, &bits);
 		clear_state_bit(tree, prealloc, &clear_bits, 0);
-
-		merge_state(tree, prealloc);
 		prealloc = NULL;
 		goto out;
 	}
@@ -2154,13 +2153,46 @@
 		 "this_mirror=%d, num_copies=%d, in_validation=%d\n", read_mode,
 		 failrec->this_mirror, num_copies, failrec->in_validation);
 
-	tree->ops->submit_bio_hook(inode, read_mode, bio, failrec->this_mirror,
-					failrec->bio_flags, 0);
-	return 0;
+	ret = tree->ops->submit_bio_hook(inode, read_mode, bio,
+					 failrec->this_mirror,
+					 failrec->bio_flags, 0);
+	return ret;
 }
 
 /* lots and lots of room for performance fixes in the end_bio funcs */
 
+int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
+{
+	int uptodate = (err == 0);
+	struct extent_io_tree *tree;
+	int ret;
+
+	tree = &BTRFS_I(page->mapping->host)->io_tree;
+
+	if (tree->ops && tree->ops->writepage_end_io_hook) {
+		ret = tree->ops->writepage_end_io_hook(page, start,
+					       end, NULL, uptodate);
+		if (ret)
+			uptodate = 0;
+	}
+
+	if (!uptodate && tree->ops &&
+	    tree->ops->writepage_io_failed_hook) {
+		ret = tree->ops->writepage_io_failed_hook(NULL, page,
+						 start, end, NULL);
+		/* Writeback already completed */
+		if (ret == 0)
+			return 1;
+	}
+
+	if (!uptodate) {
+		clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS);
+		ClearPageUptodate(page);
+		SetPageError(page);
+	}
+	return 0;
+}
+
 /*
  * after a writepage IO is done, we need to:
  * clear the uptodate bits on error
@@ -2172,13 +2204,11 @@
  */
 static void end_bio_extent_writepage(struct bio *bio, int err)
 {
-	int uptodate = err == 0;
 	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
 	struct extent_io_tree *tree;
 	u64 start;
 	u64 end;
 	int whole_page;
-	int ret;
 
 	do {
 		struct page *page = bvec->bv_page;
@@ -2195,28 +2225,9 @@
 
 		if (--bvec >= bio->bi_io_vec)
 			prefetchw(&bvec->bv_page->flags);
-		if (tree->ops && tree->ops->writepage_end_io_hook) {
-			ret = tree->ops->writepage_end_io_hook(page, start,
-						       end, NULL, uptodate);
-			if (ret)
-				uptodate = 0;
-		}
 
-		if (!uptodate && tree->ops &&
-		    tree->ops->writepage_io_failed_hook) {
-			ret = tree->ops->writepage_io_failed_hook(bio, page,
-							 start, end, NULL);
-			if (ret == 0) {
-				uptodate = (err == 0);
-				continue;
-			}
-		}
-
-		if (!uptodate) {
-			clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS);
-			ClearPageUptodate(page);
-			SetPageError(page);
-		}
+		if (end_extent_writepage(page, err, start, end))
+			continue;
 
 		if (whole_page)
 			end_page_writeback(page);
@@ -2779,9 +2790,12 @@
 				delalloc_start = delalloc_end + 1;
 				continue;
 			}
-			tree->ops->fill_delalloc(inode, page, delalloc_start,
-						 delalloc_end, &page_started,
-						 &nr_written);
+			ret = tree->ops->fill_delalloc(inode, page,
+						       delalloc_start,
+						       delalloc_end,
+						       &page_started,
+						       &nr_written);
+			BUG_ON(ret);
 			/*
 			 * delalloc_end is already one less than the total
 			 * length, so we don't subtract one from
@@ -2818,8 +2832,12 @@
 	if (tree->ops && tree->ops->writepage_start_hook) {
 		ret = tree->ops->writepage_start_hook(page, start,
 						      page_end);
-		if (ret == -EAGAIN) {
-			redirty_page_for_writepage(wbc, page);
+		if (ret) {
+			/* Fixup worker will requeue */
+			if (ret == -EBUSY)
+				wbc->pages_skipped++;
+			else
+				redirty_page_for_writepage(wbc, page);
 			update_nr_written(page, wbc, nr_written);
 			unlock_page(page);
 			ret = 0;
@@ -3289,7 +3307,7 @@
 			len = end - start + 1;
 			write_lock(&map->lock);
 			em = lookup_extent_mapping(map, start, len);
-			if (IS_ERR_OR_NULL(em)) {
+			if (!em) {
 				write_unlock(&map->lock);
 				break;
 			}
@@ -3853,10 +3871,9 @@
 	num_pages = num_extent_pages(eb->start, eb->len);
 	clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 
-	if (eb_straddles_pages(eb)) {
-		clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
-				      cached_state, GFP_NOFS);
-	}
+	clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
+			      cached_state, GFP_NOFS);
+
 	for (i = 0; i < num_pages; i++) {
 		page = extent_buffer_page(eb, i);
 		if (page)
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index bc6a042cb..cecc351 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -319,4 +319,5 @@
 int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start,
 			u64 length, u64 logical, struct page *page,
 			int mirror_num);
+int end_extent_writepage(struct page *page, int err, u64 start, u64 end);
 #endif
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 33a7890..1195f09 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -26,8 +26,8 @@
 	unsigned long flags;
 	struct block_device *bdev;
 	atomic_t refs;
-	unsigned int in_tree:1;
-	unsigned int compress_type:4;
+	unsigned int in_tree;
+	unsigned int compress_type;
 };
 
 struct extent_map_tree {
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 859ba2d..e8d06b6 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1605,6 +1605,14 @@
 		return -EOPNOTSUPP;
 
 	/*
+	 * Make sure we have enough space before we do the
+	 * allocation.
+	 */
+	ret = btrfs_check_data_free_space(inode, len);
+	if (ret)
+		return ret;
+
+	/*
 	 * wait for ordered IO before we have any locks.  We'll loop again
 	 * below with the locks held.
 	 */
@@ -1667,27 +1675,12 @@
 		if (em->block_start == EXTENT_MAP_HOLE ||
 		    (cur_offset >= inode->i_size &&
 		     !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
-
-			/*
-			 * Make sure we have enough space before we do the
-			 * allocation.
-			 */
-			ret = btrfs_check_data_free_space(inode, last_byte -
-							  cur_offset);
-			if (ret) {
-				free_extent_map(em);
-				break;
-			}
-
 			ret = btrfs_prealloc_file_range(inode, mode, cur_offset,
 							last_byte - cur_offset,
 							1 << inode->i_blkbits,
 							offset + len,
 							&alloc_hint);
 
-			/* Let go of our reservation. */
-			btrfs_free_reserved_data_space(inode, last_byte -
-						       cur_offset);
 			if (ret < 0) {
 				free_extent_map(em);
 				break;
@@ -1715,6 +1708,8 @@
 			     &cached_state, GFP_NOFS);
 out:
 	mutex_unlock(&inode->i_mutex);
+	/* Let go of our reservation. */
+	btrfs_free_reserved_data_space(inode, len);
 	return ret;
 }
 
@@ -1761,7 +1756,7 @@
 						     start - root->sectorsize,
 						     root->sectorsize, 0);
 		if (IS_ERR(em)) {
-			ret = -ENXIO;
+			ret = PTR_ERR(em);
 			goto out;
 		}
 		last_end = em->start + em->len;
@@ -1773,7 +1768,7 @@
 	while (1) {
 		em = btrfs_get_extent_fiemap(inode, NULL, 0, start, len, 0);
 		if (IS_ERR(em)) {
-			ret = -ENXIO;
+			ret = PTR_ERR(em);
 			break;
 		}
 
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index c2f2059..710ea38 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -777,6 +777,7 @@
 	spin_lock(&block_group->lock);
 	if (block_group->disk_cache_state != BTRFS_DC_WRITTEN) {
 		spin_unlock(&block_group->lock);
+		btrfs_free_path(path);
 		goto out;
 	}
 	spin_unlock(&block_group->lock);
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index 213ffa8..ee15d88 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -438,7 +438,8 @@
 					  trans->bytes_reserved);
 	if (ret)
 		goto out;
-	trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
+	trace_btrfs_space_reservation(root->fs_info, "ino_cache",
+				      (u64)(unsigned long)trans,
 				      trans->bytes_reserved, 1);
 again:
 	inode = lookup_free_ino_inode(root, path);
@@ -500,7 +501,8 @@
 out_put:
 	iput(inode);
 out_release:
-	trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
+	trace_btrfs_space_reservation(root->fs_info, "ino_cache",
+				      (u64)(unsigned long)trans,
 				      trans->bytes_reserved, 0);
 	btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
 out:
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 32214fe..892b347 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1555,6 +1555,7 @@
 	struct inode *inode;
 	u64 page_start;
 	u64 page_end;
+	int ret;
 
 	fixup = container_of(work, struct btrfs_writepage_fixup, work);
 	page = fixup->page;
@@ -1582,12 +1583,21 @@
 				     page_end, &cached_state, GFP_NOFS);
 		unlock_page(page);
 		btrfs_start_ordered_extent(inode, ordered, 1);
+		btrfs_put_ordered_extent(ordered);
 		goto again;
 	}
 
-	BUG();
+	ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
+	if (ret) {
+		mapping_set_error(page->mapping, ret);
+		end_extent_writepage(page, ret, page_start, page_end);
+		ClearPageChecked(page);
+		goto out;
+	 }
+
 	btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state);
 	ClearPageChecked(page);
+	set_page_dirty(page);
 out:
 	unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
 			     &cached_state, GFP_NOFS);
@@ -1630,7 +1640,7 @@
 	fixup->work.func = btrfs_writepage_fixup_worker;
 	fixup->page = page;
 	btrfs_queue_worker(&root->fs_info->fixup_workers, &fixup->work);
-	return -EAGAIN;
+	return -EBUSY;
 }
 
 static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
@@ -4575,7 +4585,8 @@
 		ret = btrfs_insert_dir_item(trans, root, name, name_len,
 					    parent_inode, &key,
 					    btrfs_inode_type(inode), index);
-		BUG_ON(ret);
+		if (ret)
+			goto fail_dir_item;
 
 		btrfs_i_size_write(parent_inode, parent_inode->i_size +
 				   name_len * 2);
@@ -4583,6 +4594,23 @@
 		ret = btrfs_update_inode(trans, root, parent_inode);
 	}
 	return ret;
+
+fail_dir_item:
+	if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) {
+		u64 local_index;
+		int err;
+		err = btrfs_del_root_ref(trans, root->fs_info->tree_root,
+				 key.objectid, root->root_key.objectid,
+				 parent_ino, &local_index, name, name_len);
+
+	} else if (add_backref) {
+		u64 local_index;
+		int err;
+
+		err = btrfs_del_inode_ref(trans, root, name, name_len,
+					  ino, parent_ino, &local_index);
+	}
+	return ret;
 }
 
 static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
@@ -6696,8 +6724,10 @@
 	int err;
 	u64 index = 0;
 
-	inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid,
-				new_dirid, S_IFDIR | 0700, &index);
+	inode = btrfs_new_inode(trans, new_root, NULL, "..", 2,
+				new_dirid, new_dirid,
+				S_IFDIR | (~current_umask() & S_IRWXUGO),
+				&index);
 	if (IS_ERR(inode))
 		return PTR_ERR(inode);
 	inode->i_op = &btrfs_dir_inode_operations;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 03bb62a..d8b5471 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -861,6 +861,7 @@
 	int i_done;
 	struct btrfs_ordered_extent *ordered;
 	struct extent_state *cached_state = NULL;
+	struct extent_io_tree *tree;
 	gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
 
 	if (isize == 0)
@@ -871,18 +872,34 @@
 					   num_pages << PAGE_CACHE_SHIFT);
 	if (ret)
 		return ret;
-again:
-	ret = 0;
 	i_done = 0;
+	tree = &BTRFS_I(inode)->io_tree;
 
 	/* step one, lock all the pages */
 	for (i = 0; i < num_pages; i++) {
 		struct page *page;
+again:
 		page = find_or_create_page(inode->i_mapping,
-					    start_index + i, mask);
+					   start_index + i, mask);
 		if (!page)
 			break;
 
+		page_start = page_offset(page);
+		page_end = page_start + PAGE_CACHE_SIZE - 1;
+		while (1) {
+			lock_extent(tree, page_start, page_end, GFP_NOFS);
+			ordered = btrfs_lookup_ordered_extent(inode,
+							      page_start);
+			unlock_extent(tree, page_start, page_end, GFP_NOFS);
+			if (!ordered)
+				break;
+
+			unlock_page(page);
+			btrfs_start_ordered_extent(inode, ordered, 1);
+			btrfs_put_ordered_extent(ordered);
+			lock_page(page);
+		}
+
 		if (!PageUptodate(page)) {
 			btrfs_readpage(NULL, page);
 			lock_page(page);
@@ -893,15 +910,22 @@
 				break;
 			}
 		}
+
 		isize = i_size_read(inode);
 		file_end = (isize - 1) >> PAGE_CACHE_SHIFT;
-		if (!isize || page->index > file_end ||
-		    page->mapping != inode->i_mapping) {
+		if (!isize || page->index > file_end) {
 			/* whoops, we blew past eof, skip this page */
 			unlock_page(page);
 			page_cache_release(page);
 			break;
 		}
+
+		if (page->mapping != inode->i_mapping) {
+			unlock_page(page);
+			page_cache_release(page);
+			goto again;
+		}
+
 		pages[i] = page;
 		i_done++;
 	}
@@ -924,25 +948,6 @@
 	lock_extent_bits(&BTRFS_I(inode)->io_tree,
 			 page_start, page_end - 1, 0, &cached_state,
 			 GFP_NOFS);
-	ordered = btrfs_lookup_first_ordered_extent(inode, page_end - 1);
-	if (ordered &&
-	    ordered->file_offset + ordered->len > page_start &&
-	    ordered->file_offset < page_end) {
-		btrfs_put_ordered_extent(ordered);
-		unlock_extent_cached(&BTRFS_I(inode)->io_tree,
-				     page_start, page_end - 1,
-				     &cached_state, GFP_NOFS);
-		for (i = 0; i < i_done; i++) {
-			unlock_page(pages[i]);
-			page_cache_release(pages[i]);
-		}
-		btrfs_wait_ordered_range(inode, page_start,
-					 page_end - page_start);
-		goto again;
-	}
-	if (ordered)
-		btrfs_put_ordered_extent(ordered);
-
 	clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start,
 			  page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
 			  EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
@@ -1327,6 +1332,12 @@
 		goto out;
 	}
 
+	if (name[0] == '.' &&
+	   (namelen == 1 || (name[1] == '.' && namelen == 2))) {
+		ret = -EEXIST;
+		goto out;
+	}
+
 	if (subvol) {
 		ret = btrfs_mksubvol(&file->f_path, name, namelen,
 				     NULL, transid, readonly);
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 9770cc5..abc0fbf 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1367,7 +1367,8 @@
 }
 
 static noinline_for_stack int scrub_chunk(struct scrub_dev *sdev,
-	u64 chunk_tree, u64 chunk_objectid, u64 chunk_offset, u64 length)
+	u64 chunk_tree, u64 chunk_objectid, u64 chunk_offset, u64 length,
+	u64 dev_offset)
 {
 	struct btrfs_mapping_tree *map_tree =
 		&sdev->dev->dev_root->fs_info->mapping_tree;
@@ -1391,7 +1392,8 @@
 		goto out;
 
 	for (i = 0; i < map->num_stripes; ++i) {
-		if (map->stripes[i].dev == sdev->dev) {
+		if (map->stripes[i].dev == sdev->dev &&
+		    map->stripes[i].physical == dev_offset) {
 			ret = scrub_stripe(sdev, map, i, chunk_offset, length);
 			if (ret)
 				goto out;
@@ -1487,7 +1489,7 @@
 			break;
 		}
 		ret = scrub_chunk(sdev, chunk_tree, chunk_objectid,
-				  chunk_offset, length);
+				  chunk_offset, length, found_key.offset);
 		btrfs_put_block_group(cache);
 		if (ret)
 			break;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 287a672..04b77e3 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -327,7 +327,8 @@
 
 	if (num_bytes) {
 		trace_btrfs_space_reservation(root->fs_info, "transaction",
-					      (u64)h, num_bytes, 1);
+					      (u64)(unsigned long)h,
+					      num_bytes, 1);
 		h->block_rsv = &root->fs_info->trans_block_rsv;
 		h->bytes_reserved = num_bytes;
 	}
@@ -915,7 +916,11 @@
 				dentry->d_name.name, dentry->d_name.len,
 				parent_inode, &key,
 				BTRFS_FT_DIR, index);
-	BUG_ON(ret);
+	if (ret) {
+		pending->error = -EEXIST;
+		dput(parent);
+		goto fail;
+	}
 
 	btrfs_i_size_write(parent_inode, parent_inode->i_size +
 					 dentry->d_name.len * 2);
@@ -993,12 +998,9 @@
 {
 	struct btrfs_pending_snapshot *pending;
 	struct list_head *head = &trans->transaction->pending_snapshots;
-	int ret;
 
-	list_for_each_entry(pending, head, list) {
-		ret = create_pending_snapshot(trans, fs_info, pending);
-		BUG_ON(ret);
-	}
+	list_for_each_entry(pending, head, list)
+		create_pending_snapshot(trans, fs_info, pending);
 	return 0;
 }
 
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 0b4e2af..ef41f28 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -459,12 +459,23 @@
 {
 	struct btrfs_device *device, *next;
 
+	struct block_device *latest_bdev = NULL;
+	u64 latest_devid = 0;
+	u64 latest_transid = 0;
+
 	mutex_lock(&uuid_mutex);
 again:
 	/* This is the initialized path, it is safe to release the devices. */
 	list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) {
-		if (device->in_fs_metadata)
+		if (device->in_fs_metadata) {
+			if (!latest_transid ||
+			    device->generation > latest_transid) {
+				latest_devid = device->devid;
+				latest_transid = device->generation;
+				latest_bdev = device->bdev;
+			}
 			continue;
+		}
 
 		if (device->bdev) {
 			blkdev_put(device->bdev, device->mode);
@@ -487,6 +498,10 @@
 		goto again;
 	}
 
+	fs_devices->latest_bdev = latest_bdev;
+	fs_devices->latest_devid = latest_devid;
+	fs_devices->latest_trans = latest_transid;
+
 	mutex_unlock(&uuid_mutex);
 	return 0;
 }
@@ -1953,7 +1968,7 @@
 	em = lookup_extent_mapping(em_tree, chunk_offset, 1);
 	read_unlock(&em_tree->lock);
 
-	BUG_ON(em->start > chunk_offset ||
+	BUG_ON(!em || em->start > chunk_offset ||
 	       em->start + em->len < chunk_offset);
 	map = (struct map_lookup *)em->bdev;
 
@@ -4356,6 +4371,20 @@
 		return -ENOMEM;
 	btrfs_set_buffer_uptodate(sb);
 	btrfs_set_buffer_lockdep_class(root->root_key.objectid, sb, 0);
+	/*
+	 * The sb extent buffer is artifical and just used to read the system array.
+	 * btrfs_set_buffer_uptodate() call does not properly mark all it's
+	 * pages up-to-date when the page is larger: extent does not cover the
+	 * whole page and consequently check_page_uptodate does not find all
+	 * the page's extents up-to-date (the hole beyond sb),
+	 * write_extent_buffer then triggers a WARN_ON.
+	 *
+	 * Regular short extents go through mark_extent_buffer_dirty/writeback cycle,
+	 * but sb spans only this function. Add an explicit SetPageUptodate call
+	 * to silence the warning eg. on PowerPC 64.
+	 */
+	if (PAGE_CACHE_SIZE > BTRFS_SUPER_INFO_SIZE)
+		SetPageUptodate(sb->first_page);
 
 	write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE);
 	array_size = btrfs_super_sys_array_size(super_copy);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9c28865..602f77c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -773,10 +773,11 @@
 		cifs_dump_mem("Bad SMB: ", buf,
 			min_t(unsigned int, server->total_read, 48));
 
-	if (mid)
-		handle_mid(mid, server, smb_buffer, length);
+	if (!mid)
+		return length;
 
-	return length;
+	handle_mid(mid, server, smb_buffer, length);
+	return 0;
 }
 
 static int
@@ -2125,7 +2126,7 @@
 	down_read(&key->sem);
 	upayload = key->payload.data;
 	if (IS_ERR_OR_NULL(upayload)) {
-		rc = PTR_ERR(key);
+		rc = upayload ? PTR_ERR(upayload) : -EINVAL;
 		goto out_key_put;
 	}
 
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index df8fecb..63a196b 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -492,7 +492,7 @@
 {
 	int xid;
 	int rc = 0; /* to get around spurious gcc warning, set to zero here */
-	__u32 oplock = 0;
+	__u32 oplock = enable_oplocks ? REQ_OPLOCK : 0;
 	__u16 fileHandle = 0;
 	bool posix_open = false;
 	struct cifs_sb_info *cifs_sb;
diff --git a/fs/compat.c b/fs/compat.c
index fa9d721..07880ba 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -131,41 +131,35 @@
 
 static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
 {
-	compat_ino_t ino = stat->ino;
-	typeof(ubuf->st_uid) uid = 0;
-	typeof(ubuf->st_gid) gid = 0;
-	int err;
+	struct compat_stat tmp;
 
-	SET_UID(uid, stat->uid);
-	SET_GID(gid, stat->gid);
-
-	if ((u64) stat->size > MAX_NON_LFS ||
-	    !old_valid_dev(stat->dev) ||
-	    !old_valid_dev(stat->rdev))
-		return -EOVERFLOW;
-	if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+	if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
 		return -EOVERFLOW;
 
-	if (clear_user(ubuf, sizeof(*ubuf)))
-		return -EFAULT;
-
-	err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
-	err |= __put_user(ino, &ubuf->st_ino);
-	err |= __put_user(stat->mode, &ubuf->st_mode);
-	err |= __put_user(stat->nlink, &ubuf->st_nlink);
-	err |= __put_user(uid, &ubuf->st_uid);
-	err |= __put_user(gid, &ubuf->st_gid);
-	err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
-	err |= __put_user(stat->size, &ubuf->st_size);
-	err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
-	err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
-	err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
-	err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
-	err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
-	err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
-	err |= __put_user(stat->blksize, &ubuf->st_blksize);
-	err |= __put_user(stat->blocks, &ubuf->st_blocks);
-	return err;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.st_dev = old_encode_dev(stat->dev);
+	tmp.st_ino = stat->ino;
+	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+		return -EOVERFLOW;
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	if (tmp.st_nlink != stat->nlink)
+		return -EOVERFLOW;
+	SET_UID(tmp.st_uid, stat->uid);
+	SET_GID(tmp.st_gid, stat->gid);
+	tmp.st_rdev = old_encode_dev(stat->rdev);
+	if ((u64) stat->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+	tmp.st_size = stat->size;
+	tmp.st_atime = stat->atime.tv_sec;
+	tmp.st_atime_nsec = stat->atime.tv_nsec;
+	tmp.st_mtime = stat->mtime.tv_sec;
+	tmp.st_mtime_nsec = stat->mtime.tv_nsec;
+	tmp.st_ctime = stat->ctime.tv_sec;
+	tmp.st_ctime_nsec = stat->ctime.tv_nsec;
+	tmp.st_blocks = stat->blocks;
+	tmp.st_blksize = stat->blksize;
+	return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
 asmlinkage long compat_sys_newstat(const char __user * filename,
diff --git a/fs/dcache.c b/fs/dcache.c
index 16a53cc..138be96 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -104,7 +104,7 @@
 
 static struct hlist_bl_head *dentry_hashtable __read_mostly;
 
-static inline struct hlist_bl_head *d_hash(struct dentry *parent,
+static inline struct hlist_bl_head *d_hash(const struct dentry *parent,
 					unsigned long hash)
 {
 	hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES;
@@ -1717,8 +1717,9 @@
  * child is looked up. Thus, an interlocking stepping of sequence lock checks
  * is formed, giving integrity down the path walk.
  */
-struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
-				unsigned *seq, struct inode **inode)
+struct dentry *__d_lookup_rcu(const struct dentry *parent,
+				const struct qstr *name,
+				unsigned *seqp, struct inode **inode)
 {
 	unsigned int len = name->len;
 	unsigned int hash = name->hash;
@@ -1748,6 +1749,7 @@
 	 * See Documentation/filesystems/path-lookup.txt for more details.
 	 */
 	hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
+		unsigned seq;
 		struct inode *i;
 		const char *tname;
 		int tlen;
@@ -1756,7 +1758,7 @@
 			continue;
 
 seqretry:
-		*seq = read_seqcount_begin(&dentry->d_seq);
+		seq = read_seqcount_begin(&dentry->d_seq);
 		if (dentry->d_parent != parent)
 			continue;
 		if (d_unhashed(dentry))
@@ -1771,7 +1773,7 @@
 		 * edge of memory when walking. If we could load this
 		 * atomically some other way, we could drop this check.
 		 */
-		if (read_seqcount_retry(&dentry->d_seq, *seq))
+		if (read_seqcount_retry(&dentry->d_seq, seq))
 			goto seqretry;
 		if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
 			if (parent->d_op->d_compare(parent, *inode,
@@ -1788,6 +1790,7 @@
 		 * order to do anything useful with the returned dentry
 		 * anyway.
 		 */
+		*seqp = seq;
 		*inode = i;
 		return dentry;
 	}
@@ -2968,7 +2971,7 @@
 
 static void __init dcache_init_early(void)
 {
-	int loop;
+	unsigned int loop;
 
 	/* If hashes are distributed across NUMA nodes, defer
 	 * hash allocation until vmalloc space is available.
@@ -2986,13 +2989,13 @@
 					&d_hash_mask,
 					0);
 
-	for (loop = 0; loop < (1 << d_hash_shift); loop++)
+	for (loop = 0; loop < (1U << d_hash_shift); loop++)
 		INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
 }
 
 static void __init dcache_init(void)
 {
-	int loop;
+	unsigned int loop;
 
 	/* 
 	 * A constructor could be added for stable state like the lists,
@@ -3016,7 +3019,7 @@
 					&d_hash_mask,
 					0);
 
-	for (loop = 0; loop < (1 << d_hash_shift); loop++)
+	for (loop = 0; loop < (1U << d_hash_shift); loop++)
 		INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
 }
 
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 4a588db..f4aadd1 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -173,7 +173,7 @@
 	if (atomic_read(&inode->i_dio_count))
 		__inode_dio_wait(inode);
 }
-EXPORT_SYMBOL_GPL(inode_dio_wait);
+EXPORT_SYMBOL(inode_dio_wait);
 
 /*
  * inode_dio_done - signal finish of a direct I/O requests
@@ -187,7 +187,7 @@
 	if (atomic_dec_and_test(&inode->i_dio_count))
 		wake_up_bit(&inode->i_state, __I_DIO_WAKEUP);
 }
-EXPORT_SYMBOL_GPL(inode_dio_done);
+EXPORT_SYMBOL(inode_dio_done);
 
 /*
  * How many pages are in the queue?
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 63ab245..ea99312 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -1990,6 +1990,17 @@
 	return;
 }
 
+static size_t ecryptfs_max_decoded_size(size_t encoded_size)
+{
+	/* Not exact; conservatively long. Every block of 4
+	 * encoded characters decodes into a block of 3
+	 * decoded characters. This segment of code provides
+	 * the caller with the maximum amount of allocated
+	 * space that @dst will need to point to in a
+	 * subsequent call. */
+	return ((encoded_size + 1) * 3) / 4;
+}
+
 /**
  * ecryptfs_decode_from_filename
  * @dst: If NULL, this function only sets @dst_size and returns. If
@@ -2008,13 +2019,7 @@
 	size_t dst_byte_offset = 0;
 
 	if (dst == NULL) {
-		/* Not exact; conservatively long. Every block of 4
-		 * encoded characters decodes into a block of 3
-		 * decoded characters. This segment of code provides
-		 * the caller with the maximum amount of allocated
-		 * space that @dst will need to point to in a
-		 * subsequent call. */
-		(*dst_size) = (((src_size + 1) * 3) / 4);
+		(*dst_size) = ecryptfs_max_decoded_size(src_size);
 		goto out;
 	}
 	while (src_byte_offset < src_size) {
@@ -2239,3 +2244,52 @@
 out:
 	return rc;
 }
+
+#define ENC_NAME_MAX_BLOCKLEN_8_OR_16	143
+
+int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
+			   struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
+{
+	struct blkcipher_desc desc;
+	struct mutex *tfm_mutex;
+	size_t cipher_blocksize;
+	int rc;
+
+	if (!(mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) {
+		(*namelen) = lower_namelen;
+		return 0;
+	}
+
+	rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex,
+			mount_crypt_stat->global_default_fn_cipher_name);
+	if (unlikely(rc)) {
+		(*namelen) = 0;
+		return rc;
+	}
+
+	mutex_lock(tfm_mutex);
+	cipher_blocksize = crypto_blkcipher_blocksize(desc.tfm);
+	mutex_unlock(tfm_mutex);
+
+	/* Return an exact amount for the common cases */
+	if (lower_namelen == NAME_MAX
+	    && (cipher_blocksize == 8 || cipher_blocksize == 16)) {
+		(*namelen) = ENC_NAME_MAX_BLOCKLEN_8_OR_16;
+		return 0;
+	}
+
+	/* Return a safe estimate for the uncommon cases */
+	(*namelen) = lower_namelen;
+	(*namelen) -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE;
+	/* Since this is the max decoded size, subtract 1 "decoded block" len */
+	(*namelen) = ecryptfs_max_decoded_size(*namelen) - 3;
+	(*namelen) -= ECRYPTFS_TAG_70_MAX_METADATA_SIZE;
+	(*namelen) -= ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES;
+	/* Worst case is that the filename is padded nearly a full block size */
+	(*namelen) -= cipher_blocksize - 1;
+
+	if ((*namelen) < 0)
+		(*namelen) = 0;
+
+	return 0;
+}
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index a2362df..867b64c 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -162,6 +162,10 @@
 #define ECRYPTFS_NON_NULL 0x42 /* A reasonable substitute for NULL */
 #define MD5_DIGEST_SIZE 16
 #define ECRYPTFS_TAG_70_DIGEST_SIZE MD5_DIGEST_SIZE
+#define ECRYPTFS_TAG_70_MIN_METADATA_SIZE (1 + ECRYPTFS_MIN_PKT_LEN_SIZE \
+					   + ECRYPTFS_SIG_SIZE + 1 + 1)
+#define ECRYPTFS_TAG_70_MAX_METADATA_SIZE (1 + ECRYPTFS_MAX_PKT_LEN_SIZE \
+					   + ECRYPTFS_SIG_SIZE + 1 + 1)
 #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FEK_ENCRYPTED."
 #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX_SIZE 23
 #define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FNEK_ENCRYPTED."
@@ -701,6 +705,8 @@
 			     size_t *packet_size,
 			     struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
 			     char *data, size_t max_packet_size);
+int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
+			   struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
 int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
 		       loff_t offset);
 
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 19892d7..ab35b11 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -1085,6 +1085,8 @@
 	}
 
 	rc = vfs_setxattr(lower_dentry, name, value, size, flags);
+	if (!rc)
+		fsstack_copy_attr_all(dentry->d_inode, lower_dentry->d_inode);
 out:
 	return rc;
 }
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 8e3b943..2333203 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -679,10 +679,7 @@
 	 * Octets N3-N4: Block-aligned encrypted filename
 	 *  - Consists of a minimum number of random characters, a \0
 	 *    separator, and then the filename */
-	s->max_packet_size = (1                   /* Tag 70 identifier */
-			      + 3                 /* Max Tag 70 packet size */
-			      + ECRYPTFS_SIG_SIZE /* FNEK sig */
-			      + 1                 /* Cipher identifier */
+	s->max_packet_size = (ECRYPTFS_TAG_70_MAX_METADATA_SIZE
 			      + s->block_aligned_filename_size);
 	if (dest == NULL) {
 		(*packet_size) = s->max_packet_size;
@@ -934,10 +931,10 @@
 		goto out;
 	}
 	s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
-	if (max_packet_size < (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)) {
+	if (max_packet_size < ECRYPTFS_TAG_70_MIN_METADATA_SIZE) {
 		printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be "
 		       "at least [%d]\n", __func__, max_packet_size,
-			(1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1));
+		       ECRYPTFS_TAG_70_MIN_METADATA_SIZE);
 		rc = -EINVAL;
 		goto out;
 	}
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
index 349209d..3a06f40 100644
--- a/fs/ecryptfs/miscdev.c
+++ b/fs/ecryptfs/miscdev.c
@@ -429,7 +429,7 @@
 		goto memdup;
 	} else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) {
 		printk(KERN_WARNING "%s: Acceptable packet size range is "
-		       "[%d-%lu], but amount of data written is [%zu].",
+		       "[%d-%zu], but amount of data written is [%zu].",
 		       __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count);
 		return -EINVAL;
 	}
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 10ec695..a46b3a8 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -150,7 +150,7 @@
 			/* This is a header extent */
 			char *page_virt;
 
-			page_virt = kmap_atomic(page, KM_USER0);
+			page_virt = kmap_atomic(page);
 			memset(page_virt, 0, PAGE_CACHE_SIZE);
 			/* TODO: Support more than one header extent */
 			if (view_extent_num == 0) {
@@ -163,7 +163,7 @@
 							       crypt_stat,
 							       &written);
 			}
-			kunmap_atomic(page_virt, KM_USER0);
+			kunmap_atomic(page_virt);
 			flush_dcache_page(page);
 			if (rc) {
 				printk(KERN_ERR "%s: Error reading xattr "
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index 5c0106f..b2a34a1 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -156,7 +156,7 @@
 			       ecryptfs_page_idx, rc);
 			goto out;
 		}
-		ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0);
+		ecryptfs_page_virt = kmap_atomic(ecryptfs_page);
 
 		/*
 		 * pos: where we're now writing, offset: where the request was
@@ -179,7 +179,7 @@
 			       (data + data_offset), num_bytes);
 			data_offset += num_bytes;
 		}
-		kunmap_atomic(ecryptfs_page_virt, KM_USER0);
+		kunmap_atomic(ecryptfs_page_virt);
 		flush_dcache_page(ecryptfs_page);
 		SetPageUptodate(ecryptfs_page);
 		unlock_page(ecryptfs_page);
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 9df7fd6..cf15282 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -30,6 +30,8 @@
 #include <linux/seq_file.h>
 #include <linux/file.h>
 #include <linux/crypto.h>
+#include <linux/statfs.h>
+#include <linux/magic.h>
 #include "ecryptfs_kernel.h"
 
 struct kmem_cache *ecryptfs_inode_info_cache;
@@ -102,10 +104,20 @@
 static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
 	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+	int rc;
 
 	if (!lower_dentry->d_sb->s_op->statfs)
 		return -ENOSYS;
-	return lower_dentry->d_sb->s_op->statfs(lower_dentry, buf);
+
+	rc = lower_dentry->d_sb->s_op->statfs(lower_dentry, buf);
+	if (rc)
+		return rc;
+
+	buf->f_type = ECRYPTFS_SUPER_MAGIC;
+	rc = ecryptfs_set_f_namelen(&buf->f_namelen, buf->f_namelen,
+	       &ecryptfs_superblock_to_private(dentry->d_sb)->mount_crypt_stat);
+
+	return rc;
 }
 
 /**
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index aabdfc3..ea54cde 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -320,6 +320,11 @@
 	return !list_empty(p);
 }
 
+static inline struct eppoll_entry *ep_pwq_from_wait(wait_queue_t *p)
+{
+	return container_of(p, struct eppoll_entry, wait);
+}
+
 /* Get the "struct epitem" from a wait queue pointer */
 static inline struct epitem *ep_item_from_wait(wait_queue_t *p)
 {
@@ -467,6 +472,18 @@
 	put_cpu();
 }
 
+static void ep_remove_wait_queue(struct eppoll_entry *pwq)
+{
+	wait_queue_head_t *whead;
+
+	rcu_read_lock();
+	/* If it is cleared by POLLFREE, it should be rcu-safe */
+	whead = rcu_dereference(pwq->whead);
+	if (whead)
+		remove_wait_queue(whead, &pwq->wait);
+	rcu_read_unlock();
+}
+
 /*
  * This function unregisters poll callbacks from the associated file
  * descriptor.  Must be called with "mtx" held (or "epmutex" if called from
@@ -481,7 +498,7 @@
 		pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
 
 		list_del(&pwq->llink);
-		remove_wait_queue(pwq->whead, &pwq->wait);
+		ep_remove_wait_queue(pwq);
 		kmem_cache_free(pwq_cache, pwq);
 	}
 }
@@ -842,6 +859,17 @@
 	struct epitem *epi = ep_item_from_wait(wait);
 	struct eventpoll *ep = epi->ep;
 
+	if ((unsigned long)key & POLLFREE) {
+		ep_pwq_from_wait(wait)->whead = NULL;
+		/*
+		 * whead = NULL above can race with ep_remove_wait_queue()
+		 * which can do another remove_wait_queue() after us, so we
+		 * can't use __remove_wait_queue(). whead->lock is held by
+		 * the caller.
+		 */
+		list_del_init(&wait->task_list);
+	}
+
 	spin_lock_irqsave(&ep->lock, flags);
 
 	/*
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index f855916..5b4a936 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -53,14 +53,6 @@
 };
 
 /*
- * Include the creation of the trace points after defining the
- * wb_writeback_work structure so that the definition remains local to this
- * file.
- */
-#define CREATE_TRACE_POINTS
-#include <trace/events/writeback.h>
-
-/*
  * We don't actually have pdflush, but this one is exported though /proc...
  */
 int nr_pdflush_threads;
@@ -92,6 +84,14 @@
 	return list_entry(head, struct inode, i_wb_list);
 }
 
+/*
+ * Include the creation of the trace points after defining the
+ * wb_writeback_work structure and inline functions so that the definition
+ * remains local to this file.
+ */
+#define CREATE_TRACE_POINTS
+#include <trace/events/writeback.h>
+
 /* Wakeup flusher thread or forker thread to fork it. Requires bdi->wb_lock. */
 static void bdi_wakeup_flusher(struct backing_dev_info *bdi)
 {
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 376816f..351a3e7 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -167,14 +167,19 @@
 	spin_unlock(&lru_lock);
 }
 
-static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
+static void __gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
 {
-	spin_lock(&lru_lock);
 	if (!list_empty(&gl->gl_lru)) {
 		list_del_init(&gl->gl_lru);
 		atomic_dec(&lru_count);
 		clear_bit(GLF_LRU, &gl->gl_flags);
 	}
+}
+
+static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
+{
+	spin_lock(&lru_lock);
+	__gfs2_glock_remove_from_lru(gl);
 	spin_unlock(&lru_lock);
 }
 
@@ -217,11 +222,12 @@
 	struct gfs2_sbd *sdp = gl->gl_sbd;
 	struct address_space *mapping = gfs2_glock2aspace(gl);
 
-	if (atomic_dec_and_test(&gl->gl_ref)) {
+	if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) {
+		__gfs2_glock_remove_from_lru(gl);
+		spin_unlock(&lru_lock);
 		spin_lock_bucket(gl->gl_hash);
 		hlist_bl_del_rcu(&gl->gl_list);
 		spin_unlock_bucket(gl->gl_hash);
-		gfs2_glock_remove_from_lru(gl);
 		GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
 		GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
 		trace_gfs2_glock_put(gl);
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index a7d611b..5698746 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -391,10 +391,6 @@
 	int error;
 	int dblocks = 1;
 
-	error = gfs2_rindex_update(sdp);
-	if (error)
-		fs_warn(sdp, "rindex update returns %d\n", error);
-
 	error = gfs2_inplace_reserve(dip, RES_DINODE);
 	if (error)
 		goto out;
@@ -1043,6 +1039,7 @@
 	rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
 	if (!rgd)
 		goto out_inodes;
+
 	gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
 
 
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 6aacf3f..24f609c 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -800,6 +800,11 @@
 		fs_err(sdp, "can't get quota file inode: %d\n", error);
 		goto fail_rindex;
 	}
+
+	error = gfs2_rindex_update(sdp);
+	if (error)
+		goto fail_qinode;
+
 	return 0;
 
 fail_qinode:
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 981bfa3..49ada95 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -683,16 +683,21 @@
 	struct gfs2_glock *gl = ip->i_gl;
 	struct gfs2_holder ri_gh;
 	int error = 0;
+	int unlock_required = 0;
 
 	/* Read new copy from disk if we don't have the latest */
 	if (!sdp->sd_rindex_uptodate) {
 		mutex_lock(&sdp->sd_rindex_mutex);
-		error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh);
-		if (error)
-			return error;
+		if (!gfs2_glock_is_locked_by_me(gl)) {
+			error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh);
+			if (error)
+				return error;
+			unlock_required = 1;
+		}
 		if (!sdp->sd_rindex_uptodate)
 			error = gfs2_ri_update(ip);
-		gfs2_glock_dq_uninit(&ri_gh);
+		if (unlock_required)
+			gfs2_glock_dq_uninit(&ri_gh);
 		mutex_unlock(&sdp->sd_rindex_mutex);
 	}
 
diff --git a/fs/inode.c b/fs/inode.c
index fb10d86..d3ebdbe 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1651,7 +1651,7 @@
  */
 void __init inode_init_early(void)
 {
-	int loop;
+	unsigned int loop;
 
 	/* If hashes are distributed across NUMA nodes, defer
 	 * hash allocation until vmalloc space is available.
@@ -1669,13 +1669,13 @@
 					&i_hash_mask,
 					0);
 
-	for (loop = 0; loop < (1 << i_hash_shift); loop++)
+	for (loop = 0; loop < (1U << i_hash_shift); loop++)
 		INIT_HLIST_HEAD(&inode_hashtable[loop]);
 }
 
 void __init inode_init(void)
 {
-	int loop;
+	unsigned int loop;
 
 	/* inode slab cache */
 	inode_cachep = kmem_cache_create("inode_cache",
@@ -1699,7 +1699,7 @@
 					&i_hash_mask,
 					0);
 
-	for (loop = 0; loop < (1 << i_hash_shift); loop++)
+	for (loop = 0; loop < (1U << i_hash_shift); loop++)
 		INIT_HLIST_HEAD(&inode_hashtable[loop]);
 }
 
diff --git a/fs/ioprio.c b/fs/ioprio.c
index f84b380..0f1b951 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -51,7 +51,7 @@
 	ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
 	if (ioc) {
 		ioc_ioprio_changed(ioc, ioprio);
-		put_io_context(ioc, NULL);
+		put_io_context(ioc);
 	}
 
 	return err;
diff --git a/fs/namei.c b/fs/namei.c
index 208c6aa..e2ba628 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1095,8 +1095,10 @@
 	struct dentry *old;
 
 	/* Don't create child dentry for a dead directory. */
-	if (unlikely(IS_DEADDIR(inode)))
+	if (unlikely(IS_DEADDIR(inode))) {
+		dput(dentry);
 		return ERR_PTR(-ENOENT);
+	}
 
 	old = inode->i_op->lookup(inode, dentry, nd);
 	if (unlikely(old)) {
@@ -1372,6 +1374,34 @@
 	return 1;
 }
 
+unsigned int full_name_hash(const unsigned char *name, unsigned int len)
+{
+	unsigned long hash = init_name_hash();
+	while (len--)
+		hash = partial_name_hash(*name++, hash);
+	return end_name_hash(hash);
+}
+EXPORT_SYMBOL(full_name_hash);
+
+/*
+ * We know there's a real path component here of at least
+ * one character.
+ */
+static inline unsigned long hash_name(const char *name, unsigned int *hashp)
+{
+	unsigned long hash = init_name_hash();
+	unsigned long len = 0, c;
+
+	c = (unsigned char)*name;
+	do {
+		len++;
+		hash = partial_name_hash(c, hash);
+		c = (unsigned char)name[len];
+	} while (c && c != '/');
+	*hashp = end_name_hash(hash);
+	return len;
+}
+
 /*
  * Name resolution.
  * This is the basic name resolution function, turning a pathname into
@@ -1392,31 +1422,22 @@
 
 	/* At this point we know we have a real path component. */
 	for(;;) {
-		unsigned long hash;
 		struct qstr this;
-		unsigned int c;
+		long len;
 		int type;
 
 		err = may_lookup(nd);
  		if (err)
 			break;
 
+		len = hash_name(name, &this.hash);
 		this.name = name;
-		c = *(const unsigned char *)name;
-
-		hash = init_name_hash();
-		do {
-			name++;
-			hash = partial_name_hash(c, hash);
-			c = *(const unsigned char *)name;
-		} while (c && (c != '/'));
-		this.len = name - (const char *) this.name;
-		this.hash = end_name_hash(hash);
+		this.len = len;
 
 		type = LAST_NORM;
-		if (this.name[0] == '.') switch (this.len) {
+		if (name[0] == '.') switch (len) {
 			case 2:
-				if (this.name[1] == '.') {
+				if (name[1] == '.') {
 					type = LAST_DOTDOT;
 					nd->flags |= LOOKUP_JUMPED;
 				}
@@ -1435,12 +1456,18 @@
 			}
 		}
 
-		/* remove trailing slashes? */
-		if (!c)
+		if (!name[len])
 			goto last_component;
-		while (*++name == '/');
-		if (!*name)
+		/*
+		 * If it wasn't NUL, we know it was '/'. Skip that
+		 * slash, and continue until no more slashes.
+		 */
+		do {
+			len++;
+		} while (unlikely(name[len] == '/'));
+		if (!name[len])
 			goto last_component;
+		name += len;
 
 		err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW);
 		if (err < 0)
@@ -1773,24 +1800,21 @@
 struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
 {
 	struct qstr this;
-	unsigned long hash;
 	unsigned int c;
 
 	WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
 
 	this.name = name;
 	this.len = len;
+	this.hash = full_name_hash(name, len);
 	if (!len)
 		return ERR_PTR(-EACCES);
 
-	hash = init_name_hash();
 	while (len--) {
 		c = *(const unsigned char *)name++;
 		if (c == '/' || c == '\0')
 			return ERR_PTR(-EACCES);
-		hash = partial_name_hash(c, hash);
 	}
-	this.hash = end_name_hash(hash);
 	/*
 	 * See if the low-level filesystem might want
 	 * to use its own hash..
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f0c849c..ec9f6ef 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3575,8 +3575,8 @@
 	}
 	if (npages > 1) {
 		/* for decoding across pages */
-		args.acl_scratch = alloc_page(GFP_KERNEL);
-		if (!args.acl_scratch)
+		res.acl_scratch = alloc_page(GFP_KERNEL);
+		if (!res.acl_scratch)
 			goto out_free;
 	}
 	args.acl_len = npages * PAGE_SIZE;
@@ -3612,8 +3612,8 @@
 	for (i = 0; i < npages; i++)
 		if (pages[i])
 			__free_page(pages[i]);
-	if (args.acl_scratch)
-		__free_page(args.acl_scratch);
+	if (res.acl_scratch)
+		__free_page(res.acl_scratch);
 	return ret;
 }
 
@@ -4883,8 +4883,10 @@
 				clp->cl_rpcclient->cl_auth->au_flavor);
 
 	res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL);
-	if (unlikely(!res.server_scope))
-		return -ENOMEM;
+	if (unlikely(!res.server_scope)) {
+		status = -ENOMEM;
+		goto out;
+	}
 
 	status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
 	if (!status)
@@ -4901,12 +4903,13 @@
 			clp->server_scope = NULL;
 		}
 
-		if (!clp->server_scope)
+		if (!clp->server_scope) {
 			clp->server_scope = res.server_scope;
-		else
-			kfree(res.server_scope);
+			goto out;
+		}
 	}
-
+	kfree(res.server_scope);
+out:
 	dprintk("<-- %s status= %d\n", __func__, status);
 	return status;
 }
@@ -5008,37 +5011,53 @@
 	return status;
 }
 
+static struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags)
+{
+	return kcalloc(max_slots, sizeof(struct nfs4_slot), gfp_flags);
+}
+
+static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
+		struct nfs4_slot *new,
+		u32 max_slots,
+		u32 ivalue)
+{
+	struct nfs4_slot *old = NULL;
+	u32 i;
+
+	spin_lock(&tbl->slot_tbl_lock);
+	if (new) {
+		old = tbl->slots;
+		tbl->slots = new;
+		tbl->max_slots = max_slots;
+	}
+	tbl->highest_used_slotid = -1;	/* no slot is currently used */
+	for (i = 0; i < tbl->max_slots; i++)
+		tbl->slots[i].seq_nr = ivalue;
+	spin_unlock(&tbl->slot_tbl_lock);
+	kfree(old);
+}
+
 /*
- * Reset a slot table
+ * (re)Initialise a slot table
  */
-static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
-				 int ivalue)
+static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
+				 u32 ivalue)
 {
 	struct nfs4_slot *new = NULL;
-	int i;
-	int ret = 0;
+	int ret = -ENOMEM;
 
 	dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
 		max_reqs, tbl->max_slots);
 
 	/* Does the newly negotiated max_reqs match the existing slot table? */
 	if (max_reqs != tbl->max_slots) {
-		ret = -ENOMEM;
-		new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
-			      GFP_NOFS);
+		new = nfs4_alloc_slots(max_reqs, GFP_NOFS);
 		if (!new)
 			goto out;
-		ret = 0;
-		kfree(tbl->slots);
 	}
-	spin_lock(&tbl->slot_tbl_lock);
-	if (new) {
-		tbl->slots = new;
-		tbl->max_slots = max_reqs;
-	}
-	for (i = 0; i < tbl->max_slots; ++i)
-		tbl->slots[i].seq_nr = ivalue;
-	spin_unlock(&tbl->slot_tbl_lock);
+	ret = 0;
+
+	nfs4_add_and_init_slots(tbl, new, max_reqs, ivalue);
 	dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
 		tbl, tbl->slots, tbl->max_slots);
 out:
@@ -5061,36 +5080,6 @@
 }
 
 /*
- * Initialize slot table
- */
-static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
-		int max_slots, int ivalue)
-{
-	struct nfs4_slot *slot;
-	int ret = -ENOMEM;
-
-	BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
-
-	dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
-
-	slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS);
-	if (!slot)
-		goto out;
-	ret = 0;
-
-	spin_lock(&tbl->slot_tbl_lock);
-	tbl->max_slots = max_slots;
-	tbl->slots = slot;
-	tbl->highest_used_slotid = -1;  /* no slot is currently used */
-	spin_unlock(&tbl->slot_tbl_lock);
-	dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
-		tbl, tbl->slots, tbl->max_slots);
-out:
-	dprintk("<-- %s: return %d\n", __func__, ret);
-	return ret;
-}
-
-/*
  * Initialize or reset the forechannel and backchannel tables
  */
 static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
@@ -5101,25 +5090,16 @@
 	dprintk("--> %s\n", __func__);
 	/* Fore channel */
 	tbl = &ses->fc_slot_table;
-	if (tbl->slots == NULL) {
-		status = nfs4_init_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
-		if (status) /* -ENOMEM */
-			return status;
-	} else {
-		status = nfs4_reset_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
-		if (status)
-			return status;
-	}
+	status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
+	if (status) /* -ENOMEM */
+		return status;
 	/* Back channel */
 	tbl = &ses->bc_slot_table;
-	if (tbl->slots == NULL) {
-		status = nfs4_init_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
-		if (status)
-			/* Fore and back channel share a connection so get
-			 * both slot tables or neither */
-			nfs4_destroy_slot_tables(ses);
-	} else
-		status = nfs4_reset_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
+	status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
+	if (status && tbl->slots == NULL)
+		/* Fore and back channel share a connection so get
+		 * both slot tables or neither */
+		nfs4_destroy_slot_tables(ses);
 	return status;
 }
 
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index a53f33b..4539203 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1132,6 +1132,8 @@
 {
 	struct nfs_client *clp = server->nfs_client;
 
+	if (test_and_clear_bit(NFS_DELEGATED_STATE, &state->flags))
+		nfs_async_inode_return_delegation(state->inode, &state->stateid);
 	nfs4_state_mark_reclaim_nograce(clp, state);
 	nfs4_schedule_state_manager(clp);
 }
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 95e92e4..33bd8d0 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -2522,7 +2522,6 @@
 
 	xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
 		args->acl_pages, args->acl_pgbase, args->acl_len);
-	xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE);
 
 	encode_nops(&hdr);
 }
@@ -6032,6 +6031,10 @@
 	struct compound_hdr hdr;
 	int status;
 
+	if (res->acl_scratch != NULL) {
+		void *p = page_address(res->acl_scratch);
+		xdr_set_scratch_buffer(xdr, p, PAGE_SIZE);
+	}
 	status = decode_compound_hdr(xdr, &hdr);
 	if (status)
 		goto out;
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index f14fde2..e028199 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1,7 +1,7 @@
 /**
  * attrib.c - NTFS attribute operations.  Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2007 Anton Altaparmakov
+ * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -345,10 +345,10 @@
 	unsigned long flags;
 	bool is_retry = false;
 
+	BUG_ON(!ni);
 	ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
 			ni->mft_no, (unsigned long long)vcn,
 			write_locked ? "write" : "read");
-	BUG_ON(!ni);
 	BUG_ON(!NInoNonResident(ni));
 	BUG_ON(vcn < 0);
 	if (!ni->runlist.rl) {
@@ -469,9 +469,9 @@
 	int err = 0;
 	bool is_retry = false;
 
+	BUG_ON(!ni);
 	ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.",
 			ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out");
-	BUG_ON(!ni);
 	BUG_ON(!NInoNonResident(ni));
 	BUG_ON(vcn < 0);
 	if (!ni->runlist.rl) {
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 382857f..3014a36 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -1,7 +1,7 @@
 /**
  * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2011 Anton Altaparmakov and Tuxera Inc.
+ * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -1367,7 +1367,7 @@
 			ntfs_error(vol->sb, "Failed to merge runlists for mft "
 					"bitmap.");
 			if (ntfs_cluster_free_from_rl(vol, rl2)) {
-				ntfs_error(vol->sb, "Failed to dealocate "
+				ntfs_error(vol->sb, "Failed to deallocate "
 						"allocated cluster.%s", es);
 				NVolSetErrors(vol);
 			}
@@ -1805,7 +1805,7 @@
 		ntfs_error(vol->sb, "Failed to merge runlists for mft data "
 				"attribute.");
 		if (ntfs_cluster_free_from_rl(vol, rl2)) {
-			ntfs_error(vol->sb, "Failed to dealocate clusters "
+			ntfs_error(vol->sb, "Failed to deallocate clusters "
 					"from the mft data attribute.%s", es);
 			NVolSetErrors(vol);
 		}
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 5a4a8af..f907611 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1,7 +1,7 @@
 /*
  * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2011 Anton Altaparmakov and Tuxera Inc.
+ * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
  * Copyright (c) 2001,2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -1239,7 +1239,6 @@
 {
 	MFT_REF mref;
 	struct inode *vi;
-	ntfs_inode *ni;
 	struct page *page;
 	u32 *kaddr, *kend;
 	ntfs_name *name = NULL;
@@ -1290,7 +1289,6 @@
 				"is not the system volume.", i_size_read(vi));
 		goto iput_out;
 	}
-	ni = NTFS_I(vi);
 	page = ntfs_map_page(vi->i_mapping, 0);
 	if (IS_ERR(page)) {
 		ntfs_error(vol->sb, "Failed to read from hiberfil.sys.");
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index be24469..a9856e3 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1053,7 +1053,7 @@
 	handle_t *handle = NULL;
 	struct buffer_head *old_dir_bh = NULL;
 	struct buffer_head *new_dir_bh = NULL;
-	nlink_t old_dir_nlink = old_dir->i_nlink;
+	u32 old_dir_nlink = old_dir->i_nlink;
 	struct ocfs2_dinode *old_di;
 	struct ocfs2_dir_lookup_result old_inode_dot_dot_res = { NULL, };
 	struct ocfs2_dir_lookup_result target_lookup_res = { NULL, };
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 7898cd6..fc2c438 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -292,11 +292,26 @@
 	}
 }
 
+/* Return 1 if 'cmd' will block on frozen filesystem */
+static int quotactl_cmd_write(int cmd)
+{
+	switch (cmd) {
+	case Q_GETFMT:
+	case Q_GETINFO:
+	case Q_SYNC:
+	case Q_XGETQSTAT:
+	case Q_XGETQUOTA:
+	case Q_XQUOTASYNC:
+		return 0;
+	}
+	return 1;
+}
+
 /*
  * look up a superblock on which quota ops will be performed
  * - use the name of a block device to find the superblock thereon
  */
-static struct super_block *quotactl_block(const char __user *special)
+static struct super_block *quotactl_block(const char __user *special, int cmd)
 {
 #ifdef CONFIG_BLOCK
 	struct block_device *bdev;
@@ -309,7 +324,10 @@
 	putname(tmp);
 	if (IS_ERR(bdev))
 		return ERR_CAST(bdev);
-	sb = get_super(bdev);
+	if (quotactl_cmd_write(cmd))
+		sb = get_super_thawed(bdev);
+	else
+		sb = get_super(bdev);
 	bdput(bdev);
 	if (!sb)
 		return ERR_PTR(-ENODEV);
@@ -361,7 +379,7 @@
 			pathp = &path;
 	}
 
-	sb = quotactl_block(special);
+	sb = quotactl_block(special, cmds);
 	if (IS_ERR(sb)) {
 		ret = PTR_ERR(sb);
 		goto out;
diff --git a/fs/select.c b/fs/select.c
index d33418f..e782258 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -912,7 +912,7 @@
 }
 
 SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
-		long, timeout_msecs)
+		int, timeout_msecs)
 {
 	struct timespec end_time, *to = NULL;
 	int ret;
diff --git a/fs/signalfd.c b/fs/signalfd.c
index 492465b..7ae2a57 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -30,6 +30,21 @@
 #include <linux/signalfd.h>
 #include <linux/syscalls.h>
 
+void signalfd_cleanup(struct sighand_struct *sighand)
+{
+	wait_queue_head_t *wqh = &sighand->signalfd_wqh;
+	/*
+	 * The lockless check can race with remove_wait_queue() in progress,
+	 * but in this case its caller should run under rcu_read_lock() and
+	 * sighand_cachep is SLAB_DESTROY_BY_RCU, we can safely return.
+	 */
+	if (likely(!waitqueue_active(wqh)))
+		return;
+
+	/* wait_queue_t->func(POLLFREE) should do remove_wait_queue() */
+	wake_up_poll(wqh, POLLHUP | POLLFREE);
+}
+
 struct signalfd_ctx {
 	sigset_t sigmask;
 };
diff --git a/fs/super.c b/fs/super.c
index 6015c02..6277ec6 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -634,6 +634,28 @@
 EXPORT_SYMBOL(get_super);
 
 /**
+ *	get_super_thawed - get thawed superblock of a device
+ *	@bdev: device to get the superblock for
+ *
+ *	Scans the superblock list and finds the superblock of the file system
+ *	mounted on the device. The superblock is returned once it is thawed
+ *	(or immediately if it was not frozen). %NULL is returned if no match
+ *	is found.
+ */
+struct super_block *get_super_thawed(struct block_device *bdev)
+{
+	while (1) {
+		struct super_block *s = get_super(bdev);
+		if (!s || s->s_frozen == SB_UNFROZEN)
+			return s;
+		up_read(&s->s_umount);
+		vfs_check_frozen(s, SB_FREEZE_WRITE);
+		put_super(s);
+	}
+}
+EXPORT_SYMBOL(get_super_thawed);
+
+/**
  * get_active_super - get an active reference to the superblock of a device
  * @bdev: device to get the superblock for
  *
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h
index 292eff1..ab7c53f 100644
--- a/fs/xfs/kmem.h
+++ b/fs/xfs/kmem.h
@@ -110,10 +110,4 @@
 extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
 extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
 
-static inline int
-kmem_shake_allow(gfp_t gfp_mask)
-{
-	return ((gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS));
-}
-
 #endif /* __XFS_SUPPORT_KMEM_H__ */
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index b4ff40b..53db20e 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -63,82 +63,6 @@
 static struct lock_class_key xfs_dquot_other_class;
 
 /*
- * Allocate and initialize a dquot. We don't always allocate fresh memory;
- * we try to reclaim a free dquot if the number of incore dquots are above
- * a threshold.
- * The only field inside the core that gets initialized at this point
- * is the d_id field. The idea is to fill in the entire q_core
- * when we read in the on disk dquot.
- */
-STATIC xfs_dquot_t *
-xfs_qm_dqinit(
-	xfs_mount_t  *mp,
-	xfs_dqid_t   id,
-	uint	     type)
-{
-	xfs_dquot_t	*dqp;
-	boolean_t	brandnewdquot;
-
-	brandnewdquot = xfs_qm_dqalloc_incore(&dqp);
-	dqp->dq_flags = type;
-	dqp->q_core.d_id = cpu_to_be32(id);
-	dqp->q_mount = mp;
-
-	/*
-	 * No need to re-initialize these if this is a reclaimed dquot.
-	 */
-	if (brandnewdquot) {
-		INIT_LIST_HEAD(&dqp->q_freelist);
-		mutex_init(&dqp->q_qlock);
-		init_waitqueue_head(&dqp->q_pinwait);
-
-		/*
-		 * Because we want to use a counting completion, complete
-		 * the flush completion once to allow a single access to
-		 * the flush completion without blocking.
-		 */
-		init_completion(&dqp->q_flush);
-		complete(&dqp->q_flush);
-
-		trace_xfs_dqinit(dqp);
-	} else {
-		/*
-		 * Only the q_core portion was zeroed in dqreclaim_one().
-		 * So, we need to reset others.
-		 */
-		dqp->q_nrefs = 0;
-		dqp->q_blkno = 0;
-		INIT_LIST_HEAD(&dqp->q_mplist);
-		INIT_LIST_HEAD(&dqp->q_hashlist);
-		dqp->q_bufoffset = 0;
-		dqp->q_fileoffset = 0;
-		dqp->q_transp = NULL;
-		dqp->q_gdquot = NULL;
-		dqp->q_res_bcount = 0;
-		dqp->q_res_icount = 0;
-		dqp->q_res_rtbcount = 0;
-		atomic_set(&dqp->q_pincount, 0);
-		dqp->q_hash = NULL;
-		ASSERT(list_empty(&dqp->q_freelist));
-
-		trace_xfs_dqreuse(dqp);
-	}
-
-	/*
-	 * In either case we need to make sure group quotas have a different
-	 * lock class than user quotas, to make sure lockdep knows we can
-	 * locks of one of each at the same time.
-	 */
-	if (!(type & XFS_DQ_USER))
-		lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);
-
-	/*
-	 * log item gets initialized later
-	 */
-	return (dqp);
-}
-
-/*
  * This is called to free all the memory associated with a dquot
  */
 void
@@ -215,10 +139,10 @@
 
 	if (!d->d_btimer) {
 		if ((d->d_blk_softlimit &&
-		     (be64_to_cpu(d->d_bcount) >=
+		     (be64_to_cpu(d->d_bcount) >
 		      be64_to_cpu(d->d_blk_softlimit))) ||
 		    (d->d_blk_hardlimit &&
-		     (be64_to_cpu(d->d_bcount) >=
+		     (be64_to_cpu(d->d_bcount) >
 		      be64_to_cpu(d->d_blk_hardlimit)))) {
 			d->d_btimer = cpu_to_be32(get_seconds() +
 					mp->m_quotainfo->qi_btimelimit);
@@ -227,10 +151,10 @@
 		}
 	} else {
 		if ((!d->d_blk_softlimit ||
-		     (be64_to_cpu(d->d_bcount) <
+		     (be64_to_cpu(d->d_bcount) <=
 		      be64_to_cpu(d->d_blk_softlimit))) &&
 		    (!d->d_blk_hardlimit ||
-		    (be64_to_cpu(d->d_bcount) <
+		    (be64_to_cpu(d->d_bcount) <=
 		     be64_to_cpu(d->d_blk_hardlimit)))) {
 			d->d_btimer = 0;
 		}
@@ -238,10 +162,10 @@
 
 	if (!d->d_itimer) {
 		if ((d->d_ino_softlimit &&
-		     (be64_to_cpu(d->d_icount) >=
+		     (be64_to_cpu(d->d_icount) >
 		      be64_to_cpu(d->d_ino_softlimit))) ||
 		    (d->d_ino_hardlimit &&
-		     (be64_to_cpu(d->d_icount) >=
+		     (be64_to_cpu(d->d_icount) >
 		      be64_to_cpu(d->d_ino_hardlimit)))) {
 			d->d_itimer = cpu_to_be32(get_seconds() +
 					mp->m_quotainfo->qi_itimelimit);
@@ -250,10 +174,10 @@
 		}
 	} else {
 		if ((!d->d_ino_softlimit ||
-		     (be64_to_cpu(d->d_icount) <
+		     (be64_to_cpu(d->d_icount) <=
 		      be64_to_cpu(d->d_ino_softlimit)))  &&
 		    (!d->d_ino_hardlimit ||
-		     (be64_to_cpu(d->d_icount) <
+		     (be64_to_cpu(d->d_icount) <=
 		      be64_to_cpu(d->d_ino_hardlimit)))) {
 			d->d_itimer = 0;
 		}
@@ -261,10 +185,10 @@
 
 	if (!d->d_rtbtimer) {
 		if ((d->d_rtb_softlimit &&
-		     (be64_to_cpu(d->d_rtbcount) >=
+		     (be64_to_cpu(d->d_rtbcount) >
 		      be64_to_cpu(d->d_rtb_softlimit))) ||
 		    (d->d_rtb_hardlimit &&
-		     (be64_to_cpu(d->d_rtbcount) >=
+		     (be64_to_cpu(d->d_rtbcount) >
 		      be64_to_cpu(d->d_rtb_hardlimit)))) {
 			d->d_rtbtimer = cpu_to_be32(get_seconds() +
 					mp->m_quotainfo->qi_rtbtimelimit);
@@ -273,10 +197,10 @@
 		}
 	} else {
 		if ((!d->d_rtb_softlimit ||
-		     (be64_to_cpu(d->d_rtbcount) <
+		     (be64_to_cpu(d->d_rtbcount) <=
 		      be64_to_cpu(d->d_rtb_softlimit))) &&
 		    (!d->d_rtb_hardlimit ||
-		     (be64_to_cpu(d->d_rtbcount) <
+		     (be64_to_cpu(d->d_rtbcount) <=
 		      be64_to_cpu(d->d_rtb_hardlimit)))) {
 			d->d_rtbtimer = 0;
 		}
@@ -567,7 +491,32 @@
 	int			error;
 	int			cancelflags = 0;
 
-	dqp = xfs_qm_dqinit(mp, id, type);
+
+	dqp = kmem_zone_zalloc(xfs_Gqm->qm_dqzone, KM_SLEEP);
+
+	dqp->dq_flags = type;
+	dqp->q_core.d_id = cpu_to_be32(id);
+	dqp->q_mount = mp;
+	INIT_LIST_HEAD(&dqp->q_freelist);
+	mutex_init(&dqp->q_qlock);
+	init_waitqueue_head(&dqp->q_pinwait);
+
+	/*
+	 * Because we want to use a counting completion, complete
+	 * the flush completion once to allow a single access to
+	 * the flush completion without blocking.
+	 */
+	init_completion(&dqp->q_flush);
+	complete(&dqp->q_flush);
+
+	/*
+	 * Make sure group quotas have a different lock class than user
+	 * quotas.
+	 */
+	if (!(type & XFS_DQ_USER))
+		lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);
+
+	atomic_inc(&xfs_Gqm->qm_totaldquots);
 
 	trace_xfs_dqread(dqp);
 
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 541a508..0ed9ee7 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1489,7 +1489,7 @@
 	old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
 	old_len = item->ri_buf[item->ri_cnt-1].i_len;
 
-	ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0u);
+	ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP);
 	memcpy(&ptr[old_len], dp, len); /* d, s, l */
 	item->ri_buf[item->ri_cnt-1].i_len += len;
 	item->ri_buf[item->ri_cnt-1].i_addr = ptr;
@@ -1981,7 +1981,7 @@
 
 	if (!errs && ddq->d_id) {
 		if (ddq->d_blk_softlimit &&
-		    be64_to_cpu(ddq->d_bcount) >=
+		    be64_to_cpu(ddq->d_bcount) >
 				be64_to_cpu(ddq->d_blk_softlimit)) {
 			if (!ddq->d_btimer) {
 				if (flags & XFS_QMOPT_DOWARN)
@@ -1992,7 +1992,7 @@
 			}
 		}
 		if (ddq->d_ino_softlimit &&
-		    be64_to_cpu(ddq->d_icount) >=
+		    be64_to_cpu(ddq->d_icount) >
 				be64_to_cpu(ddq->d_ino_softlimit)) {
 			if (!ddq->d_itimer) {
 				if (flags & XFS_QMOPT_DOWARN)
@@ -2003,7 +2003,7 @@
 			}
 		}
 		if (ddq->d_rtb_softlimit &&
-		    be64_to_cpu(ddq->d_rtbcount) >=
+		    be64_to_cpu(ddq->d_rtbcount) >
 				be64_to_cpu(ddq->d_rtb_softlimit)) {
 			if (!ddq->d_rtbtimer) {
 				if (flags & XFS_QMOPT_DOWARN)
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 671f37e..c436def 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -50,7 +50,6 @@
  */
 struct mutex	xfs_Gqm_lock;
 struct xfs_qm	*xfs_Gqm;
-uint		ndquot;
 
 kmem_zone_t	*qm_dqzone;
 kmem_zone_t	*qm_dqtrxzone;
@@ -93,7 +92,6 @@
 		goto out_free_udqhash;
 
 	hsize /= sizeof(xfs_dqhash_t);
-	ndquot = hsize << 8;
 
 	xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);
 	xqm->qm_dqhashmask = hsize - 1;
@@ -137,7 +135,6 @@
 		xqm->qm_dqtrxzone = qm_dqtrxzone;
 
 	atomic_set(&xqm->qm_totaldquots, 0);
-	xqm->qm_dqfree_ratio = XFS_QM_DQFREE_RATIO;
 	xqm->qm_nrefs = 0;
 	return xqm;
 
@@ -1600,216 +1597,150 @@
 	return 0;
 }
 
-
-
-/*
- * Pop the least recently used dquot off the freelist and recycle it.
- */
-STATIC struct xfs_dquot *
-xfs_qm_dqreclaim_one(void)
+STATIC void
+xfs_qm_dqfree_one(
+	struct xfs_dquot	*dqp)
 {
-	struct xfs_dquot	*dqp;
-	int			restarts = 0;
+	struct xfs_mount	*mp = dqp->q_mount;
+	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 
-	mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
-restart:
-	list_for_each_entry(dqp, &xfs_Gqm->qm_dqfrlist, q_freelist) {
-		struct xfs_mount *mp = dqp->q_mount;
+	mutex_lock(&dqp->q_hash->qh_lock);
+	list_del_init(&dqp->q_hashlist);
+	dqp->q_hash->qh_version++;
+	mutex_unlock(&dqp->q_hash->qh_lock);
 
-		if (!xfs_dqlock_nowait(dqp))
-			continue;
+	mutex_lock(&qi->qi_dqlist_lock);
+	list_del_init(&dqp->q_mplist);
+	qi->qi_dquots--;
+	qi->qi_dqreclaims++;
+	mutex_unlock(&qi->qi_dqlist_lock);
 
-		/*
-		 * This dquot has already been grabbed by dqlookup.
-		 * Remove it from the freelist and try again.
-		 */
-		if (dqp->q_nrefs) {
-			trace_xfs_dqreclaim_want(dqp);
-			XQM_STATS_INC(xqmstats.xs_qm_dqwants);
+	xfs_qm_dqdestroy(dqp);
+}
 
-			list_del_init(&dqp->q_freelist);
-			xfs_Gqm->qm_dqfrlist_cnt--;
-			restarts++;
-			goto dqunlock;
-		}
+STATIC void
+xfs_qm_dqreclaim_one(
+	struct xfs_dquot	*dqp,
+	struct list_head	*dispose_list)
+{
+	struct xfs_mount	*mp = dqp->q_mount;
+	int			error;
 
-		ASSERT(dqp->q_hash);
-		ASSERT(!list_empty(&dqp->q_mplist));
+	if (!xfs_dqlock_nowait(dqp))
+		goto out_busy;
 
-		/*
-		 * Try to grab the flush lock. If this dquot is in the process
-		 * of getting flushed to disk, we don't want to reclaim it.
-		 */
-		if (!xfs_dqflock_nowait(dqp))
-			goto dqunlock;
-
-		/*
-		 * We have the flush lock so we know that this is not in the
-		 * process of being flushed. So, if this is dirty, flush it
-		 * DELWRI so that we don't get a freelist infested with
-		 * dirty dquots.
-		 */
-		if (XFS_DQ_IS_DIRTY(dqp)) {
-			int	error;
-
-			trace_xfs_dqreclaim_dirty(dqp);
-
-			/*
-			 * We flush it delayed write, so don't bother
-			 * releasing the freelist lock.
-			 */
-			error = xfs_qm_dqflush(dqp, SYNC_TRYLOCK);
-			if (error) {
-				xfs_warn(mp, "%s: dquot %p flush failed",
-					__func__, dqp);
-			}
-			goto dqunlock;
-		}
-		xfs_dqfunlock(dqp);
-
-		/*
-		 * Prevent lookup now that we are going to reclaim the dquot.
-		 * Once XFS_DQ_FREEING is set lookup won't touch the dquot,
-		 * thus we can drop the lock now.
-		 */
-		dqp->dq_flags |= XFS_DQ_FREEING;
+	/*
+	 * This dquot has acquired a reference in the meantime remove it from
+	 * the freelist and try again.
+	 */
+	if (dqp->q_nrefs) {
 		xfs_dqunlock(dqp);
 
-		mutex_lock(&dqp->q_hash->qh_lock);
-		list_del_init(&dqp->q_hashlist);
-		dqp->q_hash->qh_version++;
-		mutex_unlock(&dqp->q_hash->qh_lock);
+		trace_xfs_dqreclaim_want(dqp);
+		XQM_STATS_INC(xqmstats.xs_qm_dqwants);
 
-		mutex_lock(&mp->m_quotainfo->qi_dqlist_lock);
-		list_del_init(&dqp->q_mplist);
-		mp->m_quotainfo->qi_dquots--;
-		mp->m_quotainfo->qi_dqreclaims++;
-		mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock);
-
-		ASSERT(dqp->q_nrefs == 0);
 		list_del_init(&dqp->q_freelist);
 		xfs_Gqm->qm_dqfrlist_cnt--;
-
-		mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
-		return dqp;
-dqunlock:
-		xfs_dqunlock(dqp);
-		if (restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
-			break;
-		goto restart;
+		return;
 	}
 
-	mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
-	return NULL;
-}
+	ASSERT(dqp->q_hash);
+	ASSERT(!list_empty(&dqp->q_mplist));
 
-/*
- * Traverse the freelist of dquots and attempt to reclaim a maximum of
- * 'howmany' dquots. This operation races with dqlookup(), and attempts to
- * favor the lookup function ...
- */
-STATIC int
-xfs_qm_shake_freelist(
-	int	howmany)
-{
-	int		nreclaimed = 0;
-	xfs_dquot_t	*dqp;
+	/*
+	 * Try to grab the flush lock. If this dquot is in the process of
+	 * getting flushed to disk, we don't want to reclaim it.
+	 */
+	if (!xfs_dqflock_nowait(dqp))
+		goto out_busy;
 
-	if (howmany <= 0)
-		return 0;
+	/*
+	 * We have the flush lock so we know that this is not in the
+	 * process of being flushed. So, if this is dirty, flush it
+	 * DELWRI so that we don't get a freelist infested with
+	 * dirty dquots.
+	 */
+	if (XFS_DQ_IS_DIRTY(dqp)) {
+		trace_xfs_dqreclaim_dirty(dqp);
 
-	while (nreclaimed < howmany) {
-		dqp = xfs_qm_dqreclaim_one();
-		if (!dqp)
-			return nreclaimed;
-		xfs_qm_dqdestroy(dqp);
-		nreclaimed++;
+		/*
+		 * We flush it delayed write, so don't bother releasing the
+		 * freelist lock.
+		 */
+		error = xfs_qm_dqflush(dqp, 0);
+		if (error) {
+			xfs_warn(mp, "%s: dquot %p flush failed",
+				 __func__, dqp);
+		}
+
+		/*
+		 * Give the dquot another try on the freelist, as the
+		 * flushing will take some time.
+		 */
+		goto out_busy;
 	}
-	return nreclaimed;
+	xfs_dqfunlock(dqp);
+
+	/*
+	 * Prevent lookups now that we are past the point of no return.
+	 */
+	dqp->dq_flags |= XFS_DQ_FREEING;
+	xfs_dqunlock(dqp);
+
+	ASSERT(dqp->q_nrefs == 0);
+	list_move_tail(&dqp->q_freelist, dispose_list);
+	xfs_Gqm->qm_dqfrlist_cnt--;
+
+	trace_xfs_dqreclaim_done(dqp);
+	XQM_STATS_INC(xqmstats.xs_qm_dqreclaims);
+	return;
+
+out_busy:
+	xfs_dqunlock(dqp);
+
+	/*
+	 * Move the dquot to the tail of the list so that we don't spin on it.
+	 */
+	list_move_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist);
+
+	trace_xfs_dqreclaim_busy(dqp);
+	XQM_STATS_INC(xqmstats.xs_qm_dqreclaim_misses);
 }
 
-/*
- * The kmem_shake interface is invoked when memory is running low.
- */
-/* ARGSUSED */
 STATIC int
 xfs_qm_shake(
-	struct shrinker	*shrink,
-	struct shrink_control *sc)
+	struct shrinker		*shrink,
+	struct shrink_control	*sc)
 {
-	int	ndqused, nfree, n;
-	gfp_t gfp_mask = sc->gfp_mask;
+	int			nr_to_scan = sc->nr_to_scan;
+	LIST_HEAD		(dispose_list);
+	struct xfs_dquot	*dqp;
 
-	if (!kmem_shake_allow(gfp_mask))
+	if ((sc->gfp_mask & (__GFP_FS|__GFP_WAIT)) != (__GFP_FS|__GFP_WAIT))
 		return 0;
-	if (!xfs_Gqm)
-		return 0;
+	if (!nr_to_scan)
+		goto out;
 
-	nfree = xfs_Gqm->qm_dqfrlist_cnt; /* free dquots */
-	/* incore dquots in all f/s's */
-	ndqused = atomic_read(&xfs_Gqm->qm_totaldquots) - nfree;
-
-	ASSERT(ndqused >= 0);
-
-	if (nfree <= ndqused && nfree < ndquot)
-		return 0;
-
-	ndqused *= xfs_Gqm->qm_dqfree_ratio;	/* target # of free dquots */
-	n = nfree - ndqused - ndquot;		/* # over target */
-
-	return xfs_qm_shake_freelist(MAX(nfree, n));
-}
-
-
-/*------------------------------------------------------------------*/
-
-/*
- * Return a new incore dquot. Depending on the number of
- * dquots in the system, we either allocate a new one on the kernel heap,
- * or reclaim a free one.
- * Return value is B_TRUE if we allocated a new dquot, B_FALSE if we managed
- * to reclaim an existing one from the freelist.
- */
-boolean_t
-xfs_qm_dqalloc_incore(
-	xfs_dquot_t **O_dqpp)
-{
-	xfs_dquot_t	*dqp;
-
-	/*
-	 * Check against high water mark to see if we want to pop
-	 * a nincompoop dquot off the freelist.
-	 */
-	if (atomic_read(&xfs_Gqm->qm_totaldquots) >= ndquot) {
-		/*
-		 * Try to recycle a dquot from the freelist.
-		 */
-		if ((dqp = xfs_qm_dqreclaim_one())) {
-			XQM_STATS_INC(xqmstats.xs_qm_dqreclaims);
-			/*
-			 * Just zero the core here. The rest will get
-			 * reinitialized by caller. XXX we shouldn't even
-			 * do this zero ...
-			 */
-			memset(&dqp->q_core, 0, sizeof(dqp->q_core));
-			*O_dqpp = dqp;
-			return B_FALSE;
-		}
-		XQM_STATS_INC(xqmstats.xs_qm_dqreclaim_misses);
+	mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
+	while (!list_empty(&xfs_Gqm->qm_dqfrlist)) {
+		if (nr_to_scan-- <= 0)
+			break;
+		dqp = list_first_entry(&xfs_Gqm->qm_dqfrlist, struct xfs_dquot,
+				       q_freelist);
+		xfs_qm_dqreclaim_one(dqp, &dispose_list);
 	}
+	mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
 
-	/*
-	 * Allocate a brand new dquot on the kernel heap and return it
-	 * to the caller to initialize.
-	 */
-	ASSERT(xfs_Gqm->qm_dqzone != NULL);
-	*O_dqpp = kmem_zone_zalloc(xfs_Gqm->qm_dqzone, KM_SLEEP);
-	atomic_inc(&xfs_Gqm->qm_totaldquots);
-
-	return B_TRUE;
+	while (!list_empty(&dispose_list)) {
+		dqp = list_first_entry(&dispose_list, struct xfs_dquot,
+				       q_freelist);
+		list_del_init(&dqp->q_freelist);
+		xfs_qm_dqfree_one(dqp);
+	}
+out:
+	return (xfs_Gqm->qm_dqfrlist_cnt / 100) * sysctl_vfs_cache_pressure;
 }
 
-
 /*
  * Start a transaction and write the incore superblock changes to
  * disk. flags parameter indicates which fields have changed.
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 9b4f3ad..9a9b997 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -26,24 +26,12 @@
 struct xfs_qm;
 struct xfs_inode;
 
-extern uint		ndquot;
 extern struct mutex	xfs_Gqm_lock;
 extern struct xfs_qm	*xfs_Gqm;
 extern kmem_zone_t	*qm_dqzone;
 extern kmem_zone_t	*qm_dqtrxzone;
 
 /*
- * Ditto, for xfs_qm_dqreclaim_one.
- */
-#define XFS_QM_RECLAIM_MAX_RESTARTS	4
-
-/*
- * Ideal ratio of free to in use dquots. Quota manager makes an attempt
- * to keep this balance.
- */
-#define XFS_QM_DQFREE_RATIO		2
-
-/*
  * Dquot hashtable constants/threshold values.
  */
 #define XFS_QM_HASHSIZE_LOW		(PAGE_SIZE / sizeof(xfs_dqhash_t))
@@ -74,7 +62,6 @@
 	int		 qm_dqfrlist_cnt;
 	atomic_t	 qm_totaldquots; /* total incore dquots */
 	uint		 qm_nrefs;	 /* file systems with quota on */
-	int		 qm_dqfree_ratio;/* ratio of free to inuse dquots */
 	kmem_zone_t	*qm_dqzone;	 /* dquot mem-alloc zone */
 	kmem_zone_t	*qm_dqtrxzone;	 /* t_dqinfo of transactions */
 } xfs_qm_t;
@@ -143,7 +130,6 @@
 extern int		xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
 
 /* dquot stuff */
-extern boolean_t	xfs_qm_dqalloc_incore(xfs_dquot_t **);
 extern int		xfs_qm_dqpurge_all(xfs_mount_t *, uint);
 extern void		xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
 
diff --git a/fs/xfs/xfs_qm_stats.c b/fs/xfs/xfs_qm_stats.c
index 8671a0b..5729ba5 100644
--- a/fs/xfs/xfs_qm_stats.c
+++ b/fs/xfs/xfs_qm_stats.c
@@ -42,9 +42,9 @@
 {
 	/* maximum; incore; ratio free to inuse; freelist */
 	seq_printf(m, "%d\t%d\t%d\t%u\n",
-			ndquot,
+			0,
 			xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
-			xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0,
+			0,
 			xfs_Gqm? xfs_Gqm->qm_dqfrlist_cnt : 0);
 	return 0;
 }
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index eafbcff..711a86e 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -813,11 +813,11 @@
 	     (XFS_IS_OQUOTA_ENFORCED(mp) &&
 			(dst->d_flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)))) &&
 	    dst->d_id != 0) {
-		if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) &&
+		if (((int) dst->d_bcount > (int) dst->d_blk_softlimit) &&
 		    (dst->d_blk_softlimit > 0)) {
 			ASSERT(dst->d_btimer != 0);
 		}
-		if (((int) dst->d_icount >= (int) dst->d_ino_softlimit) &&
+		if (((int) dst->d_icount > (int) dst->d_ino_softlimit) &&
 		    (dst->d_ino_softlimit > 0)) {
 			ASSERT(dst->d_itimer != 0);
 		}
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 6b6df58..bb134a8 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -733,11 +733,10 @@
 DEFINE_DQUOT_EVENT(xfs_dqadjust);
 DEFINE_DQUOT_EVENT(xfs_dqreclaim_want);
 DEFINE_DQUOT_EVENT(xfs_dqreclaim_dirty);
-DEFINE_DQUOT_EVENT(xfs_dqreclaim_unlink);
+DEFINE_DQUOT_EVENT(xfs_dqreclaim_busy);
+DEFINE_DQUOT_EVENT(xfs_dqreclaim_done);
 DEFINE_DQUOT_EVENT(xfs_dqattach_found);
 DEFINE_DQUOT_EVENT(xfs_dqattach_get);
-DEFINE_DQUOT_EVENT(xfs_dqinit);
-DEFINE_DQUOT_EVENT(xfs_dqreuse);
 DEFINE_DQUOT_EVENT(xfs_dqalloc);
 DEFINE_DQUOT_EVENT(xfs_dqtobp_read);
 DEFINE_DQUOT_EVENT(xfs_dqread);
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 329b06a..7adcdf1 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1151,8 +1151,8 @@
 {
 	struct xfs_log_item_desc *lidp;
 
-	ASSERT(lip->li_mountp = tp->t_mountp);
-	ASSERT(lip->li_ailp = tp->t_mountp->m_ail);
+	ASSERT(lip->li_mountp == tp->t_mountp);
+	ASSERT(lip->li_ailp == tp->t_mountp->m_ail);
 
 	lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS);
 
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 4d00ee6..c4ba366 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -649,12 +649,12 @@
 			 * nblks.
 			 */
 			if (hardlimit > 0ULL &&
-			    hardlimit <= nblks + *resbcountp) {
+			    hardlimit < nblks + *resbcountp) {
 				xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
 				goto error_return;
 			}
 			if (softlimit > 0ULL &&
-			    softlimit <= nblks + *resbcountp) {
+			    softlimit < nblks + *resbcountp) {
 				if ((timer != 0 && get_seconds() > timer) ||
 				    (warns != 0 && warns >= warnlimit)) {
 					xfs_quota_warn(mp, dqp,
@@ -677,11 +677,13 @@
 			if (!softlimit)
 				softlimit = q->qi_isoftlimit;
 
-			if (hardlimit > 0ULL && count >= hardlimit) {
+			if (hardlimit > 0ULL &&
+			    hardlimit < ninos + count) {
 				xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
 				goto error_return;
 			}
-			if (softlimit > 0ULL && count >= softlimit) {
+			if (softlimit > 0ULL &&
+			    softlimit < ninos + count) {
 				if  ((timer != 0 && get_seconds() > timer) ||
 				     (warns != 0 && warns >= warnlimit)) {
 					xfs_quota_warn(mp, dqp,
diff --git a/include/asm-generic/io-64-nonatomic-hi-lo.h b/include/asm-generic/io-64-nonatomic-hi-lo.h
new file mode 100644
index 0000000..a6806a9
--- /dev/null
+++ b/include/asm-generic/io-64-nonatomic-hi-lo.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_IO_64_NONATOMIC_HI_LO_H_
+#define _ASM_IO_64_NONATOMIC_HI_LO_H_
+
+#include <linux/io.h>
+#include <asm-generic/int-ll64.h>
+
+#ifndef readq
+static inline __u64 readq(const volatile void __iomem *addr)
+{
+	const volatile u32 __iomem *p = addr;
+	u32 low, high;
+
+	high = readl(p + 1);
+	low = readl(p);
+
+	return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(__u64 val, volatile void __iomem *addr)
+{
+	writel(val >> 32, addr + 4);
+	writel(val, addr);
+}
+#endif
+
+#endif	/* _ASM_IO_64_NONATOMIC_HI_LO_H_ */
diff --git a/include/asm-generic/io-64-nonatomic-lo-hi.h b/include/asm-generic/io-64-nonatomic-lo-hi.h
new file mode 100644
index 0000000..ca546b1
--- /dev/null
+++ b/include/asm-generic/io-64-nonatomic-lo-hi.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_IO_64_NONATOMIC_LO_HI_H_
+#define _ASM_IO_64_NONATOMIC_LO_HI_H_
+
+#include <linux/io.h>
+#include <asm-generic/int-ll64.h>
+
+#ifndef readq
+static inline __u64 readq(const volatile void __iomem *addr)
+{
+	const volatile u32 __iomem *p = addr;
+	u32 low, high;
+
+	low = readl(p);
+	high = readl(p + 1);
+
+	return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(__u64 val, volatile void __iomem *addr)
+{
+	writel(val, addr);
+	writel(val >> 32, addr + 4);
+}
+#endif
+
+#endif	/* _ASM_IO_64_NONATOMIC_LO_HI_H_ */
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index 8a3d4fd..6afd7d6 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -70,7 +70,7 @@
 /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
 extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
-#else
+#elif defined(CONFIG_GENERIC_IOMAP)
 struct pci_dev;
 static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
 { }
diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h
index e58fcf8..ce37349 100644
--- a/include/asm-generic/pci_iomap.h
+++ b/include/asm-generic/pci_iomap.h
@@ -25,7 +25,7 @@
 #define __pci_ioport_map(dev, port, nr) ioport_map((port), (nr))
 #endif
 
-#else
+#elif defined(CONFIG_GENERIC_PCI_IOMAP)
 static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
 {
 	return NULL;
diff --git a/include/asm-generic/poll.h b/include/asm-generic/poll.h
index 44bce83..9ce7f44 100644
--- a/include/asm-generic/poll.h
+++ b/include/asm-generic/poll.h
@@ -28,6 +28,8 @@
 #define POLLRDHUP       0x2000
 #endif
 
+#define POLLFREE	0x4000	/* currently only for epoll */
+
 struct pollfd {
 	int fd;
 	short events;
diff --git a/include/drm/Kbuild b/include/drm/Kbuild
index a5c0e10..1e38a19 100644
--- a/include/drm/Kbuild
+++ b/include/drm/Kbuild
@@ -2,6 +2,7 @@
 header-y += drm_fourcc.h
 header-y += drm_mode.h
 header-y += drm_sarea.h
+header-y += exynos_drm.h
 header-y += i810_drm.h
 header-y += i915_drm.h
 header-y += mga_drm.h
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h
index 5e120f1..1ed3aae 100644
--- a/include/drm/exynos_drm.h
+++ b/include/drm/exynos_drm.h
@@ -97,15 +97,30 @@
 #define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS	DRM_IOWR(DRM_COMMAND_BASE + \
 		DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
 
+#ifdef __KERNEL__
+
+/**
+ * A structure for lcd panel information.
+ *
+ * @timing: default video mode for initializing
+ * @width_mm: physical size of lcd width.
+ * @height_mm: physical size of lcd height.
+ */
+struct exynos_drm_panel_info {
+	struct fb_videomode timing;
+	u32 width_mm;
+	u32 height_mm;
+};
+
 /**
  * Platform Specific Structure for DRM based FIMD.
  *
- * @timing: default video mode for initializing
+ * @panel: default panel info for initializing
  * @default_win: default window layer number to be used for UI.
  * @bpp: default bit per pixel.
  */
 struct exynos_drm_fimd_pdata {
-	struct fb_videomode		timing;
+	struct exynos_drm_panel_info panel;
 	u32				vidcon0;
 	u32				vidcon1;
 	unsigned int			default_win;
@@ -139,4 +154,5 @@
 	unsigned int			bpp;
 };
 
-#endif
+#endif	/* __KERNEL__ */
+#endif	/* _EXYNOS_DRM_H_ */
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 3c1063a..94300fe 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -56,6 +56,26 @@
 }
 
 /**
+ * rol64 - rotate a 64-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u64 rol64(__u64 word, unsigned int shift)
+{
+	return (word << shift) | (word >> (64 - shift));
+}
+
+/**
+ * ror64 - rotate a 64-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u64 ror64(__u64 word, unsigned int shift)
+{
+	return (word >> shift) | (word << (64 - shift));
+}
+
+/**
  * rol32 - rotate a 32-bit value left
  * @word: value to rotate
  * @shift: bits to roll
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 6c6a1f0..606cf33 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -399,9 +399,6 @@
 	/* Throttle data */
 	struct throtl_data *td;
 #endif
-#ifdef CONFIG_LOCKDEP
-	int			ioc_release_depth;
-#endif
 };
 
 #define QUEUE_FLAG_QUEUED	1	/* uses generic tag queueing */
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index 35eae4b..7c48029 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -952,7 +952,8 @@
     	char name[20];                  /* name of the device type */
 /* per-device flags */
         __u8 sanyo_slot		: 2;	/* Sanyo 3 CD changer support */
-        __u8 reserved		: 6;	/* not used yet */
+        __u8 keeplocked		: 1;	/* CDROM_LOCKDOOR status */
+        __u8 reserved		: 5;	/* not used yet */
 	int cdda_method;		/* see flags */
 	__u8 last_sense;
 	__u8 media_written;		/* dirty flag, DVD+RW bookkeeping */
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 41c9f65..7e05fce 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -561,5 +561,9 @@
 		unsigned long liovcnt, const struct compat_iovec __user *rvec,
 		unsigned long riovcnt, unsigned long flags);
 
+#else
+
+#define is_compat_task() (0)
+
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index d64a55b..4270bed 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -54,18 +54,17 @@
 static inline int dentry_cmp(const unsigned char *cs, size_t scount,
 				const unsigned char *ct, size_t tcount)
 {
-	int ret;
 	if (scount != tcount)
 		return 1;
+
 	do {
-		ret = (*cs != *ct);
-		if (ret)
-			break;
+		if (*cs != *ct)
+			return 1;
 		cs++;
 		ct++;
 		tcount--;
 	} while (tcount);
-	return ret;
+	return 0;
 }
 
 /* Name hashing routines. Initial hash value */
@@ -89,14 +88,7 @@
 }
 
 /* Compute the hash for a name string. */
-static inline unsigned int
-full_name_hash(const unsigned char *name, unsigned int len)
-{
-	unsigned long hash = init_name_hash();
-	while (len--)
-		hash = partial_name_hash(*name++, hash);
-	return end_name_hash(hash);
-}
+extern unsigned int full_name_hash(const unsigned char *, unsigned int);
 
 /*
  * Try to keep struct dentry aligned on 64 byte cachelines (this will
@@ -309,7 +301,8 @@
 extern struct dentry *d_lookup(struct dentry *, struct qstr *);
 extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *);
 extern struct dentry *__d_lookup(struct dentry *, struct qstr *);
-extern struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
+extern struct dentry *__d_lookup_rcu(const struct dentry *parent,
+				const struct qstr *name,
 				unsigned *seq, struct inode **inode);
 
 /**
diff --git a/include/linux/digsig.h b/include/linux/digsig.h
index b01558b..6f85a07 100644
--- a/include/linux/digsig.h
+++ b/include/linux/digsig.h
@@ -30,7 +30,7 @@
 
 struct pubkey_hdr {
 	uint8_t		version;	/* key format version */
-	time_t		timestamp;	/* key made, always 0 for now */
+	uint32_t	timestamp;	/* key made, always 0 for now */
 	uint8_t		algo;
 	uint8_t		nmpi;
 	char		mpi[0];
@@ -38,7 +38,7 @@
 
 struct signature_hdr {
 	uint8_t		version;	/* signature format version */
-	time_t		timestamp;	/* signature made */
+	uint32_t	timestamp;	/* signature made */
 	uint8_t		algo;
 	uint8_t		hash;
 	uint8_t		keyid[8];
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index c24f3d7..7d4e035 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -42,12 +42,6 @@
 	elevator_merged_fn *elevator_merged_fn;
 	elevator_merge_req_fn *elevator_merge_req_fn;
 	elevator_allow_merge_fn *elevator_allow_merge_fn;
-
-	/*
-	 * Used for both plugged list and elevator merging and in the
-	 * former case called without queue_lock.  Read comment on top of
-	 * attempt_plug_merge() for details.
-	 */
 	elevator_bio_merged_fn *elevator_bio_merged_fn;
 
 	elevator_dispatch_fn *elevator_dispatch_fn;
@@ -122,7 +116,6 @@
 extern void elv_add_request(struct request_queue *, struct request *, int);
 extern void __elv_add_request(struct request_queue *, struct request *, int);
 extern int elv_merge(struct request_queue *, struct request **, struct bio *);
-extern int elv_try_merge(struct request *, struct bio *);
 extern void elv_merge_requests(struct request_queue *, struct request *,
 			       struct request *);
 extern void elv_merged_request(struct request_queue *, struct request *, int);
@@ -155,7 +148,7 @@
 extern int elevator_init(struct request_queue *, char *);
 extern void elevator_exit(struct elevator_queue *);
 extern int elevator_change(struct request_queue *, const char *);
-extern int elv_rq_merge_ok(struct request *, struct bio *);
+extern bool elv_rq_merge_ok(struct request *, struct bio *);
 
 /*
  * Helper functions.
diff --git a/include/linux/fb.h b/include/linux/fb.h
index c18122f..a395b8c 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1003,6 +1003,7 @@
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
 extern int unregister_framebuffer(struct fb_info *fb_info);
+extern int unlink_framebuffer(struct fb_info *fb_info);
 extern void remove_conflicting_framebuffers(struct apertures_struct *a,
 				const char *name, bool primary);
 extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 386da09..69cd5bb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2496,6 +2496,7 @@
 extern void put_filesystem(struct file_system_type *fs);
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
+extern struct super_block *get_super_thawed(struct block_device *);
 extern struct super_block *get_active_super(struct block_device *bdev);
 extern void drop_super(struct super_block *sb);
 extern void iterate_supers(void (*)(struct super_block *, void *), void *);
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 62b908e..0ae065a 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -35,7 +35,7 @@
 #include <linux/mod_devicetable.h>
 
 
-#define MAX_PAGE_BUFFER_COUNT				18
+#define MAX_PAGE_BUFFER_COUNT				19
 #define MAX_MULTIPAGE_BUFFER_COUNT			32 /* 128K */
 
 #pragma pack(push, 1)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index c52d4b5..4b24ff4 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -137,6 +137,7 @@
 	IFLA_AF_SPEC,
 	IFLA_GROUP,		/* Group the device belongs to */
 	IFLA_NET_NS_FD,
+	IFLA_EXT_MASK,		/* Extended info mask, VFs, etc */
 	__IFLA_MAX
 };
 
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index 7e1371c..119773e 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -133,7 +133,7 @@
 
 struct task_struct;
 #ifdef CONFIG_BLOCK
-void put_io_context(struct io_context *ioc, struct request_queue *locked_q);
+void put_io_context(struct io_context *ioc);
 void exit_io_context(struct task_struct *task);
 struct io_context *get_task_io_context(struct task_struct *task,
 				       gfp_t gfp_flags, int node);
@@ -141,8 +141,7 @@
 void ioc_cgroup_changed(struct io_context *ioc);
 #else
 struct io_context;
-static inline void put_io_context(struct io_context *ioc,
-				  struct request_queue *locked_q) { }
+static inline void put_io_context(struct io_context *ioc) { }
 static inline void exit_io_context(struct task_struct *task) { }
 #endif
 
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 9f22ba5..19a41d1 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -217,6 +217,7 @@
 #define MMC_CARD_SDXC		(1<<6)		/* card is SDXC */
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
+#define MMC_STATE_SLEEP		(1<<9)		/* card is in sleep state */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	/* use func->cur_blksize */
@@ -382,6 +383,7 @@
 #define mmc_sd_card_uhs(c)	((c)->state & MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
+#define mmc_card_is_sleep(c)	((c)->state & MMC_STATE_SLEEP)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -393,7 +395,9 @@
 #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
+#define mmc_card_set_sleep(c)	((c)->state |= MMC_STATE_SLEEP)
 
+#define mmc_card_clr_sleep(c)	((c)->state &= ~MMC_STATE_SLEEP)
 /*
  * Quirk add/remove for MMC products.
  */
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index e8779c6..aae5d1f 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -14,6 +14,8 @@
 #ifndef LINUX_MMC_DW_MMC_H
 #define LINUX_MMC_DW_MMC_H
 
+#include <linux/scatterlist.h>
+
 #define MAX_MCI_SLOTS	2
 
 enum dw_mci_state {
@@ -40,7 +42,7 @@
  * @lock: Spinlock protecting the queue and associated data.
  * @regs: Pointer to MMIO registers.
  * @sg: Scatterlist entry currently being processed by PIO code, if any.
- * @pio_offset: Offset into the current scatterlist entry.
+ * @sg_miter: PIO mapping scatterlist iterator.
  * @cur_slot: The slot which is currently using the controller.
  * @mrq: The request currently being processed on @cur_slot,
  *	or NULL if the controller is idle.
@@ -115,7 +117,7 @@
 	void __iomem		*regs;
 
 	struct scatterlist	*sg;
-	unsigned int		pio_offset;
+	struct sg_mapping_iter	sg_miter;
 
 	struct dw_mci_slot	*cur_slot;
 	struct mmc_request	*mrq;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 0beba1e..ee2b036 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -257,6 +257,7 @@
 #define MMC_CAP2_HS200_1_2V_SDR	(1 << 6)        /* can support */
 #define MMC_CAP2_HS200		(MMC_CAP2_HS200_1_8V_SDR | \
 				 MMC_CAP2_HS200_1_2V_SDR)
+#define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
@@ -444,4 +445,23 @@
 	return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);
 }
 
+#ifdef CONFIG_MMC_CLKGATE
+void mmc_host_clk_hold(struct mmc_host *host);
+void mmc_host_clk_release(struct mmc_host *host);
+unsigned int mmc_host_clk_rate(struct mmc_host *host);
+
+#else
+static inline void mmc_host_clk_hold(struct mmc_host *host)
+{
+}
+
+static inline void mmc_host_clk_release(struct mmc_host *host)
+{
+}
+
+static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
+{
+	return host->ios.clock;
+}
+#endif
 #endif /* LINUX_MMC_HOST_H */
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 8797ed1..4dd5bd6 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -285,8 +285,8 @@
 	struct module *me;
 };
 
-#define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \
-		     ~(__alignof__(struct ebt_replace)-1))
+#define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \
+		     ~(__alignof__(struct _xt_align)-1))
 extern struct ebt_table *ebt_register_table(struct net *net,
 					    const struct ebt_table *table);
 extern void ebt_unregister_table(struct net *net, struct ebt_table *table);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index a764cef..d6ba9a1 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -614,7 +614,6 @@
 	size_t				acl_len;
 	unsigned int			acl_pgbase;
 	struct page **			acl_pages;
-	struct page *			acl_scratch;
 	struct nfs4_sequence_args 	seq_args;
 };
 
@@ -624,6 +623,7 @@
 	size_t				acl_len;
 	size_t				acl_data_offset;
 	int				acl_flags;
+	struct page *			acl_scratch;
 	struct nfs4_sequence_res	seq_res;
 };
 
diff --git a/include/linux/proportions.h b/include/linux/proportions.h
index ef35bb7..26a8a4e 100644
--- a/include/linux/proportions.h
+++ b/include/linux/proportions.h
@@ -81,7 +81,11 @@
  * Limit the time part in order to ensure there are some bits left for the
  * cycle counter and fraction multiply.
  */
+#if BITS_PER_LONG == 32
 #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4)
+#else
+#define PROP_MAX_SHIFT (BITS_PER_LONG/2)
+#endif
 
 #define PROP_FRAC_SHIFT		(BITS_PER_LONG - PROP_MAX_SHIFT - 1)
 #define PROP_FRAC_BASE		(1UL << PROP_FRAC_SHIFT)
diff --git a/include/linux/regset.h b/include/linux/regset.h
index 8abee65..686f373 100644
--- a/include/linux/regset.h
+++ b/include/linux/regset.h
@@ -335,8 +335,11 @@
 {
 	const struct user_regset *regset = &view->regsets[setno];
 
+	if (!regset->get)
+		return -EOPNOTSUPP;
+
 	if (!access_ok(VERIFY_WRITE, data, size))
-		return -EIO;
+		return -EFAULT;
 
 	return regset->get(target, regset, offset, size, NULL, data);
 }
@@ -358,8 +361,11 @@
 {
 	const struct user_regset *regset = &view->regsets[setno];
 
+	if (!regset->set)
+		return -EOPNOTSUPP;
+
 	if (!access_ok(VERIFY_READ, data, size))
-		return -EIO;
+		return -EFAULT;
 
 	return regset->set(target, regset, offset, size, NULL, data);
 }
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 8e872ea..577592e 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -602,6 +602,9 @@
 #define TCA_ACT_TAB 1 /* attr type must be >=1 */	
 #define TCAA_MAX 1
 
+/* New extended info filters for IFLA_EXT_MASK */
+#define RTEXT_FILTER_VF		(1 << 0)
+
 /* End of information exported to user level */
 
 #ifdef __KERNEL__
diff --git a/include/linux/signalfd.h b/include/linux/signalfd.h
index 3ff4961..247399b 100644
--- a/include/linux/signalfd.h
+++ b/include/linux/signalfd.h
@@ -61,13 +61,16 @@
 		wake_up(&tsk->sighand->signalfd_wqh);
 }
 
+extern void signalfd_cleanup(struct sighand_struct *sighand);
+
 #else /* CONFIG_SIGNALFD */
 
 static inline void signalfd_notify(struct task_struct *tsk, int sig) { }
 
+static inline void signalfd_cleanup(struct sighand_struct *sighand) { }
+
 #endif /* CONFIG_SIGNALFD */
 
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_SIGNALFD_H */
-
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 50db9b0..ae86ade 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1465,6 +1465,16 @@
 }
 #endif /* NET_SKBUFF_DATA_USES_OFFSET */
 
+static inline void skb_mac_header_rebuild(struct sk_buff *skb)
+{
+	if (skb_mac_header_was_set(skb)) {
+		const unsigned char *old_mac = skb_mac_header(skb);
+
+		skb_set_mac_header(skb, -skb->mac_len);
+		memmove(skb_mac_header(skb), old_mac, skb->mac_len);
+	}
+}
+
 static inline int skb_checksum_start_offset(const struct sk_buff *skb)
 {
 	return skb->csum_start - skb_headroom(skb);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 515669f..8ec1153 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -624,7 +624,7 @@
 asmlinkage long sys_socketcall(int call, unsigned long __user *args);
 asmlinkage long sys_listen(int, int);
 asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
-				long timeout);
+				int timeout);
 asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
 			fd_set __user *exp, struct timeval __user *tvp);
 asmlinkage long sys_old_select(struct sel_arg_struct __user *arg);
diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h
index 31fdb4c..0b83acd 100644
--- a/include/linux/usb/ch11.h
+++ b/include/linux/usb/ch11.h
@@ -61,12 +61,6 @@
 #define USB_PORT_FEAT_TEST              21
 #define USB_PORT_FEAT_INDICATOR         22
 #define USB_PORT_FEAT_C_PORT_L1         23
-#define USB_PORT_FEAT_C_PORT_LINK_STATE	25
-#define USB_PORT_FEAT_C_PORT_CONFIG_ERROR 26
-#define USB_PORT_FEAT_PORT_REMOTE_WAKE_MASK 27
-#define USB_PORT_FEAT_BH_PORT_RESET     28
-#define USB_PORT_FEAT_C_BH_PORT_RESET   29
-#define USB_PORT_FEAT_FORCE_LINKPM_ACCEPT 30
 
 /*
  * Port feature selectors added by USB 3.0 spec.
@@ -75,8 +69,8 @@
 #define USB_PORT_FEAT_LINK_STATE		5
 #define USB_PORT_FEAT_U1_TIMEOUT		23
 #define USB_PORT_FEAT_U2_TIMEOUT		24
-#define USB_PORT_FEAT_C_LINK_STATE		25
-#define USB_PORT_FEAT_C_CONFIG_ERR		26
+#define USB_PORT_FEAT_C_PORT_LINK_STATE		25
+#define USB_PORT_FEAT_C_PORT_CONFIG_ERROR	26
 #define USB_PORT_FEAT_REMOTE_WAKE_MASK		27
 #define USB_PORT_FEAT_BH_PORT_RESET		28
 #define USB_PORT_FEAT_C_BH_PORT_RESET		29
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 61b2905..3b6f628 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -589,7 +589,7 @@
  */
 static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd)
 {
-	return le16_to_cpu(epd->wMaxPacketSize);
+	return __le16_to_cpu(epd->wMaxPacketSize);
 }
 
 /*-------------------------------------------------------------------------*/
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index abaad6e..4a82ca0 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -256,4 +256,6 @@
 int sco_init(void);
 void sco_exit(void);
 
+void bt_sock_reclassify_lock(struct sock *sk, int proto);
+
 #endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ea9231f..453893b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -540,7 +540,7 @@
 static inline void hci_conn_hold(struct hci_conn *conn)
 {
 	atomic_inc(&conn->refcnt);
-	cancel_delayed_work_sync(&conn->disc_work);
+	cancel_delayed_work(&conn->disc_work);
 }
 
 static inline void hci_conn_put(struct hci_conn *conn)
@@ -559,9 +559,9 @@
 		} else {
 			timeo = msecs_to_jiffies(10);
 		}
-		cancel_delayed_work_sync(&conn->disc_work);
+		cancel_delayed_work(&conn->disc_work);
 		queue_delayed_work(conn->hdev->workqueue,
-					&conn->disc_work, jiffies + timeo);
+					&conn->disc_work, timeo);
 	}
 }
 
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 68f5891..b1664ed 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -611,7 +611,7 @@
 {
 	BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
 
-	if (!__cancel_delayed_work(work))
+	if (!cancel_delayed_work(work))
 		l2cap_chan_hold(chan);
 	schedule_delayed_work(work, timeout);
 }
@@ -619,20 +619,20 @@
 static inline void l2cap_clear_timer(struct l2cap_chan *chan,
 					struct delayed_work *work)
 {
-	if (__cancel_delayed_work(work))
+	if (cancel_delayed_work(work))
 		l2cap_chan_put(chan);
 }
 
 #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
 #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
 #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
-		L2CAP_DEFAULT_RETRANS_TO);
+		msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
 #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
 #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
-		L2CAP_DEFAULT_MONITOR_TO);
+		msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
 #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
 #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
-		L2CAP_DEFAULT_ACK_TO);
+		msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
 #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
 
 static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
@@ -834,7 +834,7 @@
 struct l2cap_chan *l2cap_chan_create(struct sock *sk);
 void l2cap_chan_close(struct l2cap_chan *chan, int reason);
 void l2cap_chan_destroy(struct l2cap_chan *chan);
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 								bdaddr_t *dst);
 int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
 								u32 priority);
diff --git a/include/net/flow.h b/include/net/flow.h
index 9b58243..6c469db 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -93,6 +93,16 @@
 	fl4->fl4_dport = dport;
 	fl4->fl4_sport = sport;
 }
+
+/* Reset some input parameters after previous lookup */
+static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __u8 tos,
+					__be32 daddr, __be32 saddr)
+{
+	fl4->flowi4_oif = oif;
+	fl4->flowi4_tos = tos;
+	fl4->daddr = daddr;
+	fl4->saddr = saddr;
+}
 				      
 
 struct flowi6 {
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 8a2b0ae..ab86036 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -209,7 +209,7 @@
 __nf_conntrack_find(struct net *net, u16 zone,
 		    const struct nf_conntrack_tuple *tuple);
 
-extern void nf_conntrack_hash_insert(struct nf_conn *ct);
+extern int nf_conntrack_hash_check_insert(struct nf_conn *ct);
 extern void nf_ct_delete_from_lists(struct nf_conn *ct);
 extern void nf_ct_insert_dying_list(struct nf_conn *ct);
 
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index 7b2d431..d58fdec 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -37,19 +37,51 @@
 
 extern void sock_update_netprioidx(struct sock *sk);
 
-static inline struct cgroup_netprio_state
-		*task_netprio_state(struct task_struct *p)
+#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP)
+
+static inline u32 task_netprioidx(struct task_struct *p)
 {
-#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
-	return container_of(task_subsys_state(p, net_prio_subsys_id),
-			    struct cgroup_netprio_state, css);
-#else
-	return NULL;
-#endif
+	struct cgroup_netprio_state *state;
+	u32 idx;
+
+	rcu_read_lock();
+	state = container_of(task_subsys_state(p, net_prio_subsys_id),
+			     struct cgroup_netprio_state, css);
+	idx = state->prioidx;
+	rcu_read_unlock();
+	return idx;
+}
+
+#elif IS_MODULE(CONFIG_NETPRIO_CGROUP)
+
+static inline u32 task_netprioidx(struct task_struct *p)
+{
+	struct cgroup_netprio_state *state;
+	int subsys_id;
+	u32 idx = 0;
+
+	rcu_read_lock();
+	subsys_id = rcu_dereference_index_check(net_prio_subsys_id,
+						rcu_read_lock_held());
+	if (subsys_id >= 0) {
+		state = container_of(task_subsys_state(p, subsys_id),
+				     struct cgroup_netprio_state, css);
+		idx = state->prioidx;
+	}
+	rcu_read_unlock();
+	return idx;
 }
 
 #else
 
+static inline u32 task_netprioidx(struct task_struct *p)
+{
+	return 0;
+}
+
+#endif /* CONFIG_NETPRIO_CGROUP */
+
+#else
 #define sock_update_netprioidx(sk)
 #endif
 
diff --git a/include/net/route.h b/include/net/route.h
index 91855d1..b1c0d5b 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -270,6 +270,7 @@
 		if (IS_ERR(rt))
 			return rt;
 		ip_rt_put(rt);
+		flowi4_update_output(fl4, oif, tos, fl4->daddr, fl4->saddr);
 	}
 	security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
 	return ip_route_output_flow(net, fl4, sk);
@@ -284,6 +285,9 @@
 		fl4->fl4_dport = dport;
 		fl4->fl4_sport = sport;
 		ip_rt_put(rt);
+		flowi4_update_output(fl4, sk->sk_bound_dev_if,
+				     RT_CONN_FLAGS(sk), fl4->daddr,
+				     fl4->saddr);
 		security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
 		return ip_route_output_flow(sock_net(sk), fl4, sk);
 	}
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 678f1ff..3702939 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -6,7 +6,7 @@
 
 typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, void *);
 typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *);
-typedef u16 (*rtnl_calcit_func)(struct sk_buff *);
+typedef u16 (*rtnl_calcit_func)(struct sk_buff *, struct nlmsghdr *);
 
 extern int	__rtnl_register(int protocol, int msgtype,
 				rtnl_doit_func, rtnl_dumpit_func,
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index f6bb08b..55ce96b 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -220,9 +220,16 @@
 
 struct qdisc_skb_cb {
 	unsigned int		pkt_len;
-	long			data[];
+	unsigned char		data[24];
 };
 
+static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
+{
+	struct qdisc_skb_cb *qcb;
+	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(unsigned int) + sz);
+	BUILD_BUG_ON(sizeof(qcb->data) < sz);
+}
+
 static inline int qdisc_qlen(const struct Qdisc *q)
 {
 	return q->q.qlen;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index d49db01..42c29bf 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -273,6 +273,14 @@
 	return seq3 - seq2 >= seq1 - seq2;
 }
 
+static inline bool tcp_out_of_memory(struct sock *sk)
+{
+	if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
+	    sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2))
+		return true;
+	return false;
+}
+
 static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
 {
 	struct percpu_counter *ocp = sk->sk_prot->orphan_count;
@@ -283,13 +291,11 @@
 		if (orphans << shift > sysctl_tcp_max_orphans)
 			return true;
 	}
-
-	if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-	    sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2))
-		return true;
 	return false;
 }
 
+extern bool tcp_check_oom(struct sock *sk, int shift);
+
 /* syncookies: remember time of last synqueue overflow */
 static inline void tcp_synq_overflow(struct sock *sk)
 {
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 6ba596b..e33ed1b 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -370,56 +370,6 @@
 			(unsigned long long)__entry->vruntime)
 );
 
-#ifdef CREATE_TRACE_POINTS
-static inline u64 trace_get_sleeptime(struct task_struct *tsk)
-{
-#ifdef CONFIG_SCHEDSTATS
-	u64 block, sleep;
-
-	block = tsk->se.statistics.block_start;
-	sleep = tsk->se.statistics.sleep_start;
-	tsk->se.statistics.block_start = 0;
-	tsk->se.statistics.sleep_start = 0;
-
-	return block ? block : sleep ? sleep : 0;
-#else
-	return 0;
-#endif
-}
-#endif
-
-/*
- * Tracepoint for accounting sleeptime (time the task is sleeping
- * or waiting for I/O).
- */
-TRACE_EVENT(sched_stat_sleeptime,
-
-	TP_PROTO(struct task_struct *tsk, u64 now),
-
-	TP_ARGS(tsk, now),
-
-	TP_STRUCT__entry(
-		__array( char,	comm,	TASK_COMM_LEN	)
-		__field( pid_t,	pid			)
-		__field( u64,	sleeptime		)
-	),
-
-	TP_fast_assign(
-		memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
-		__entry->pid		= tsk->pid;
-		__entry->sleeptime = trace_get_sleeptime(tsk);
-		__entry->sleeptime = __entry->sleeptime ?
-				now - __entry->sleeptime : 0;
-	)
-	TP_perf_assign(
-		__perf_count(__entry->sleeptime);
-	),
-
-	TP_printk("comm=%s pid=%d sleeptime=%Lu [ns]",
-			__entry->comm, __entry->pid,
-			(unsigned long long)__entry->sleeptime)
-);
-
 /*
  * Tracepoint for showing priority inheritance modifying a tasks
  * priority.
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h
index 8588a89..5973410 100644
--- a/include/trace/events/writeback.h
+++ b/include/trace/events/writeback.h
@@ -47,7 +47,10 @@
 		__field(int, reason)
 	),
 	TP_fast_assign(
-		strncpy(__entry->name, dev_name(bdi->dev), 32);
+		struct device *dev = bdi->dev;
+		if (!dev)
+			dev = default_backing_dev_info.dev;
+		strncpy(__entry->name, dev_name(dev), 32);
 		__entry->nr_pages = work->nr_pages;
 		__entry->sb_dev = work->sb ? work->sb->s_dev : 0;
 		__entry->sync_mode = work->sync_mode;
@@ -426,7 +429,7 @@
 
 	TP_fast_assign(
 		strncpy(__entry->name,
-			dev_name(inode->i_mapping->backing_dev_info->dev), 32);
+			dev_name(inode_to_bdi(inode)->dev), 32);
 		__entry->ino		= inode->i_ino;
 		__entry->state		= inode->i_state;
 		__entry->dirtied_when	= inode->dirtied_when;
diff --git a/include/video/exynos_dp.h b/include/video/exynos_dp.h
new file mode 100644
index 0000000..8847a9d
--- /dev/null
+++ b/include/video/exynos_dp.h
@@ -0,0 +1,131 @@
+/*
+ * Samsung SoC DP device support
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * 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 _EXYNOS_DP_H
+#define _EXYNOS_DP_H
+
+#define DP_TIMEOUT_LOOP_COUNT 100
+#define MAX_CR_LOOP 5
+#define MAX_EQ_LOOP 4
+
+enum link_rate_type {
+	LINK_RATE_1_62GBPS = 0x06,
+	LINK_RATE_2_70GBPS = 0x0a
+};
+
+enum link_lane_count_type {
+	LANE_COUNT1 = 1,
+	LANE_COUNT2 = 2,
+	LANE_COUNT4 = 4
+};
+
+enum link_training_state {
+	START,
+	CLOCK_RECOVERY,
+	EQUALIZER_TRAINING,
+	FINISHED,
+	FAILED
+};
+
+enum voltage_swing_level {
+	VOLTAGE_LEVEL_0,
+	VOLTAGE_LEVEL_1,
+	VOLTAGE_LEVEL_2,
+	VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+	PRE_EMPHASIS_LEVEL_0,
+	PRE_EMPHASIS_LEVEL_1,
+	PRE_EMPHASIS_LEVEL_2,
+	PRE_EMPHASIS_LEVEL_3,
+};
+
+enum pattern_set {
+	PRBS7,
+	D10_2,
+	TRAINING_PTN1,
+	TRAINING_PTN2,
+	DP_NONE
+};
+
+enum color_space {
+	COLOR_RGB,
+	COLOR_YCBCR422,
+	COLOR_YCBCR444
+};
+
+enum color_depth {
+	COLOR_6,
+	COLOR_8,
+	COLOR_10,
+	COLOR_12
+};
+
+enum color_coefficient {
+	COLOR_YCBCR601,
+	COLOR_YCBCR709
+};
+
+enum dynamic_range {
+	VESA,
+	CEA
+};
+
+enum pll_status {
+	PLL_UNLOCKED,
+	PLL_LOCKED
+};
+
+enum clock_recovery_m_value_type {
+	CALCULATED_M,
+	REGISTER_M
+};
+
+enum video_timing_recognition_type {
+	VIDEO_TIMING_FROM_CAPTURE,
+	VIDEO_TIMING_FROM_REGISTER
+};
+
+enum analog_power_block {
+	AUX_BLOCK,
+	CH0_BLOCK,
+	CH1_BLOCK,
+	CH2_BLOCK,
+	CH3_BLOCK,
+	ANALOG_TOTAL,
+	POWER_ALL
+};
+
+struct video_info {
+	char *name;
+
+	bool h_sync_polarity;
+	bool v_sync_polarity;
+	bool interlaced;
+
+	enum color_space color_space;
+	enum dynamic_range dynamic_range;
+	enum color_coefficient ycbcr_coeff;
+	enum color_depth color_depth;
+
+	enum link_rate_type link_rate;
+	enum link_lane_count_type lane_count;
+};
+
+struct exynos_dp_platdata {
+	struct video_info *video_info;
+
+	void (*phy_init)(void);
+	void (*phy_exit)(void);
+};
+
+#endif /* _EXYNOS_DP_H */
diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h
new file mode 100644
index 0000000..772c770
--- /dev/null
+++ b/include/video/exynos_mipi_dsim.h
@@ -0,0 +1,359 @@
+/* include/video/exynos_mipi_dsim.h
+ *
+ * Platform data header for Samsung SoC MIPI-DSIM.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * 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 _EXYNOS_MIPI_DSIM_H
+#define _EXYNOS_MIPI_DSIM_H
+
+#include <linux/device.h>
+#include <linux/fb.h>
+
+#define PANEL_NAME_SIZE		(32)
+
+/*
+ * Enumerate display interface type.
+ *
+ * DSIM_COMMAND means cpu interface and rgb interface for DSIM_VIDEO.
+ *
+ * P.S. MIPI DSI Master has two display controller intefaces, RGB Interface
+ *	for main display and CPU Interface(same as I80 Interface) for main
+ *	and sub display.
+ */
+enum mipi_dsim_interface_type {
+	DSIM_COMMAND,
+	DSIM_VIDEO
+};
+
+enum mipi_dsim_virtual_ch_no {
+	DSIM_VIRTUAL_CH_0,
+	DSIM_VIRTUAL_CH_1,
+	DSIM_VIRTUAL_CH_2,
+	DSIM_VIRTUAL_CH_3
+};
+
+enum mipi_dsim_burst_mode_type {
+	DSIM_NON_BURST_SYNC_EVENT,
+	DSIM_BURST_SYNC_EVENT,
+	DSIM_NON_BURST_SYNC_PULSE,
+	DSIM_BURST,
+	DSIM_NON_VIDEO_MODE
+};
+
+enum mipi_dsim_no_of_data_lane {
+	DSIM_DATA_LANE_1,
+	DSIM_DATA_LANE_2,
+	DSIM_DATA_LANE_3,
+	DSIM_DATA_LANE_4
+};
+
+enum mipi_dsim_byte_clk_src {
+	DSIM_PLL_OUT_DIV8,
+	DSIM_EXT_CLK_DIV8,
+	DSIM_EXT_CLK_BYPASS
+};
+
+enum mipi_dsim_pixel_format {
+	DSIM_CMD_3BPP,
+	DSIM_CMD_8BPP,
+	DSIM_CMD_12BPP,
+	DSIM_CMD_16BPP,
+	DSIM_VID_16BPP_565,
+	DSIM_VID_18BPP_666PACKED,
+	DSIM_18BPP_666LOOSELYPACKED,
+	DSIM_24BPP_888
+};
+
+/*
+ * struct mipi_dsim_config - interface for configuring mipi-dsi controller.
+ *
+ * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse.
+ * @eot_disable: enable or disable EoT packet in HS mode.
+ * @auto_vertical_cnt: specifies auto vertical count mode.
+ *	in Video mode, the vertical line transition uses line counter
+ *	configured by VSA, VBP, and Vertical resolution.
+ *	If this bit is set to '1', the line counter does not use VSA and VBP
+ *	registers.(in command mode, this variable is ignored)
+ * @hse: set horizontal sync event mode.
+ *	In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC
+ *	start packet to MIPI DSI slave at MIPI DSI spec1.1r02.
+ *	this bit transfers HSYNC end packet in VSYNC pulse and Vporch area
+ *	(in mommand mode, this variable is ignored)
+ * @hfp: specifies HFP disable mode.
+ *	if this variable is set, DSI master ignores HFP area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @hbp: specifies HBP disable mode.
+ *	if this variable is set, DSI master ignores HBP area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @hsa: specifies HSA disable mode.
+ *	if this variable is set, DSI master ignores HSA area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @cma_allow: specifies the number of horizontal lines, where command packet
+ *	transmission is allowed after Stable VFP period.
+ * @e_interface: specifies interface to be used.(CPU or RGB interface)
+ * @e_virtual_ch: specifies virtual channel number that main or
+ *	sub diaplsy uses.
+ * @e_pixel_format: specifies pixel stream format for main or sub display.
+ * @e_burst_mode: selects Burst mode in Video mode.
+ *	in Non-burst mode, RGB data area is filled with RGB data and NULL
+ *	packets, according to input bandwidth of RGB interface.
+ *	In Burst mode, RGB data area is filled with RGB data only.
+ * @e_no_data_lane: specifies data lane count to be used by Master.
+ * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8)
+ *	DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported.
+ * @pll_stable_time: specifies the PLL Timer for stability of the ganerated
+ *	clock(System clock cycle base)
+ *	if the timer value goes to 0x00000000, the clock stable bit of status
+ *	and interrupt register is set.
+ * @esc_clk: specifies escape clock frequency for getting the escape clock
+ *	prescaler value.
+ * @stop_holding_cnt: specifies the interval value between transmitting
+ *	read packet(or write "set_tear_on" command) and BTA request.
+ *	after transmitting read packet or write "set_tear_on" command,
+ *	BTA requests to D-PHY automatically. this counter value specifies
+ *	the interval between them.
+ * @bta_timeout: specifies the timer for BTA.
+ *	this register specifies time out from BTA request to change
+ *	the direction with respect to Tx escape clock.
+ * @rx_timeout: specifies the timer for LP Rx mode timeout.
+ *	this register specifies time out on how long RxValid deasserts,
+ *	after RxLpdt asserts with respect to Tx escape clock.
+ *	- RxValid specifies Rx data valid indicator.
+ *	- RxLpdt specifies an indicator that D-PHY is under RxLpdt mode.
+ *	- RxValid and RxLpdt specifies signal from D-PHY.
+ */
+struct mipi_dsim_config {
+	unsigned char			auto_flush;
+	unsigned char			eot_disable;
+
+	unsigned char			auto_vertical_cnt;
+	unsigned char			hse;
+	unsigned char			hfp;
+	unsigned char			hbp;
+	unsigned char			hsa;
+	unsigned char			cmd_allow;
+
+	enum mipi_dsim_interface_type	e_interface;
+	enum mipi_dsim_virtual_ch_no	e_virtual_ch;
+	enum mipi_dsim_pixel_format	e_pixel_format;
+	enum mipi_dsim_burst_mode_type	e_burst_mode;
+	enum mipi_dsim_no_of_data_lane	e_no_data_lane;
+	enum mipi_dsim_byte_clk_src	e_byte_clk;
+
+	/*
+	 * ===========================================
+	 * |    P    |    M    |    S    |    MHz    |
+	 * -------------------------------------------
+	 * |    3    |   100   |    3    |    100    |
+	 * |    3    |   100   |    2    |    200    |
+	 * |    3    |    63   |    1    |    252    |
+	 * |    4    |   100   |    1    |    300    |
+	 * |    4    |   110   |    1    |    330    |
+	 * |   12    |   350   |    1    |    350    |
+	 * |    3    |   100   |    1    |    400    |
+	 * |    4    |   150   |    1    |    450    |
+	 * |    6    |   118   |    1    |    472    |
+	 * |	3    |   120   |    1    |    480    |
+	 * |   12    |   250   |    0    |    500    |
+	 * |    4    |   100   |    0    |    600    |
+	 * |    3    |    81   |    0    |    648    |
+	 * |    3    |    88   |    0    |    704    |
+	 * |    3    |    90   |    0    |    720    |
+	 * |    3    |   100   |    0    |    800    |
+	 * |   12    |   425   |    0    |    850    |
+	 * |    4    |   150   |    0    |    900    |
+	 * |   12    |   475   |    0    |    950    |
+	 * |    6    |   250   |    0    |   1000    |
+	 * -------------------------------------------
+	 */
+
+	/*
+	 * pms could be calculated as the following.
+	 * M * 24 / P * 2 ^ S = MHz
+	 */
+	unsigned char			p;
+	unsigned short			m;
+	unsigned char			s;
+
+	unsigned int			pll_stable_time;
+	unsigned long			esc_clk;
+
+	unsigned short			stop_holding_cnt;
+	unsigned char			bta_timeout;
+	unsigned short			rx_timeout;
+};
+
+/*
+ * struct mipi_dsim_device - global interface for mipi-dsi driver.
+ *
+ * @dev: driver model representation of the device.
+ * @id: unique device id.
+ * @clock: pointer to MIPI-DSI clock of clock framework.
+ * @irq: interrupt number to MIPI-DSI controller.
+ * @reg_base: base address to memory mapped SRF of MIPI-DSI controller.
+ *	(virtual address)
+ * @lock: the mutex protecting this data structure.
+ * @dsim_info: infomation for configuring mipi-dsi controller.
+ * @master_ops: callbacks to mipi-dsi operations.
+ * @dsim_lcd_dev: pointer to activated ddi device.
+ *	(it would be registered by mipi-dsi driver.)
+ * @dsim_lcd_drv: pointer to activated_ddi driver.
+ *	(it would be registered by mipi-dsi driver.)
+ * @lcd_info: pointer to mipi_lcd_info structure.
+ * @state: specifies status of MIPI-DSI controller.
+ *	the status could be RESET, INIT, STOP, HSCLKEN and ULPS.
+ * @data_lane: specifiec enabled data lane number.
+ *	this variable would be set by driver according to e_no_data_lane
+ *	automatically.
+ * @e_clk_src: select byte clock source.
+ * @pd: pointer to MIPI-DSI driver platform data.
+ */
+struct mipi_dsim_device {
+	struct device			*dev;
+	int				id;
+	struct resource			*res;
+	struct clk			*clock;
+	unsigned int			irq;
+	void __iomem			*reg_base;
+	struct mutex			lock;
+
+	struct mipi_dsim_config		*dsim_config;
+	struct mipi_dsim_master_ops	*master_ops;
+	struct mipi_dsim_lcd_device	*dsim_lcd_dev;
+	struct mipi_dsim_lcd_driver	*dsim_lcd_drv;
+
+	unsigned int			state;
+	unsigned int			data_lane;
+	unsigned int			e_clk_src;
+	bool				suspended;
+
+	struct mipi_dsim_platform_data	*pd;
+};
+
+/*
+ * struct mipi_dsim_platform_data - interface to platform data
+ *	for mipi-dsi driver.
+ *
+ * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driver.
+ *	lcd panel driver searched would be actived.
+ * @dsim_config: pointer of structure for configuring mipi-dsi controller.
+ * @enabled: indicate whether mipi controller got enabled or not.
+ * @lcd_panel_info: pointer for lcd panel specific structure.
+ *	this structure specifies width, height, timing and polarity and so on.
+ * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ */
+struct mipi_dsim_platform_data {
+	char				lcd_panel_name[PANEL_NAME_SIZE];
+
+	struct mipi_dsim_config		*dsim_config;
+	unsigned int			enabled;
+	void				*lcd_panel_info;
+
+	int (*phy_enable)(struct platform_device *pdev, bool on);
+};
+
+/*
+ * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations.
+ *
+ * @cmd_write: transfer command to lcd panel at LP mode.
+ * @cmd_read: read command from rx register.
+ * @get_dsim_frame_done: get the status that all screen data have been
+ *	transferred to mipi-dsi.
+ * @clear_dsim_frame_done: clear frame done status.
+ * @get_fb_frame_done: get frame done status of display controller.
+ * @trigger: trigger display controller.
+ *	- this one would be used only in case of CPU mode.
+ *  @set_early_blank_mode: set framebuffer blank mode.
+ *	- this callback should be called prior to fb_blank() by a client driver
+ *	only if needing.
+ *  @set_blank_mode: set framebuffer blank mode.
+ *	- this callback should be called after fb_blank() by a client driver
+ *	only if needing.
+ */
+
+struct mipi_dsim_master_ops {
+	int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned int data_id,
+		const unsigned char *data0, unsigned int data1);
+	int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int data_id,
+		unsigned int data0, unsigned int req_size, u8 *rx_buf);
+	int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim);
+	int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim);
+
+	int (*get_fb_frame_done)(struct fb_info *info);
+	void (*trigger)(struct fb_info *info);
+	int (*set_early_blank_mode)(struct mipi_dsim_device *dsim, int power);
+	int (*set_blank_mode)(struct mipi_dsim_device *dsim, int power);
+};
+
+/*
+ * device structure for mipi-dsi based lcd panel.
+ *
+ * @name: name of the device to use with this device, or an
+ *	alias for that name.
+ * @dev: driver model representation of the device.
+ * @id: id of device to be registered.
+ * @bus_id: bus id for identifing connected bus
+ *	and this bus id should be same as id of mipi_dsim_device.
+ * @irq: irq number for signaling when framebuffer transfer of
+ *	lcd panel module is completed.
+ *	this irq would be used only for MIPI-DSI based CPU mode lcd panel.
+ * @master: pointer to mipi-dsi master device object.
+ * @platform_data: lcd panel specific platform data.
+ */
+struct mipi_dsim_lcd_device {
+	char			*name;
+	struct device		dev;
+	int			id;
+	int			bus_id;
+	int			irq;
+
+	struct mipi_dsim_device *master;
+	void			*platform_data;
+};
+
+/*
+ * driver structure for mipi-dsi based lcd panel.
+ *
+ * this structure should be registered by lcd panel driver.
+ * mipi-dsi driver seeks lcd panel registered through name field
+ * and calls these callback functions in appropriate time.
+ *
+ * @name: name of the driver to use with this device, or an
+ *	alias for that name.
+ * @id: id of driver to be registered.
+ *	this id would be used for finding device object registered.
+ */
+struct mipi_dsim_lcd_driver {
+	char			*name;
+	int			id;
+
+	void	(*power_on)(struct mipi_dsim_lcd_device *dsim_dev, int enable);
+	void	(*set_sequence)(struct mipi_dsim_lcd_device *dsim_dev);
+	int	(*probe)(struct mipi_dsim_lcd_device *dsim_dev);
+	int	(*remove)(struct mipi_dsim_lcd_device *dsim_dev);
+	void	(*shutdown)(struct mipi_dsim_lcd_device *dsim_dev);
+	int	(*suspend)(struct mipi_dsim_lcd_device *dsim_dev);
+	int	(*resume)(struct mipi_dsim_lcd_device *dsim_dev);
+};
+
+/*
+ * register mipi_dsim_lcd_device to mipi-dsi master.
+ */
+int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device
+						*lcd_dev);
+/**
+ * register mipi_dsim_lcd_driver object defined by lcd panel driver
+ * to mipi-dsi driver.
+ */
+int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver
+						*lcd_drv);
+#endif /* _EXYNOS_MIPI_DSIM_H */
diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h
index b569329..728f9de 100644
--- a/include/video/sh_mobile_hdmi.h
+++ b/include/video/sh_mobile_hdmi.h
@@ -31,8 +31,6 @@
 #define HDMI_SND_SRC_HBR	(3 << 0)
 
 struct sh_mobile_hdmi_info {
-	struct sh_mobile_lcdc_chan_cfg	*lcd_chan;
-	struct device			*lcd_dev;
 	unsigned int			 flags;
 	long (*clk_optimize_parent)(unsigned long target, unsigned long *best_freq,
 				    unsigned long *parent_freq);
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index fe30b75..7571b27 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -147,29 +147,23 @@
 	unsigned long (*read_data)(void *handle);
 };
 
-struct module;
-struct sh_mobile_lcdc_board_cfg {
-	struct module *owner;
-	void *board_data;
-	int (*setup_sys)(void *board_data, void *sys_ops_handle,
+struct sh_mobile_lcdc_panel_cfg {
+	unsigned long width;		/* Panel width in mm */
+	unsigned long height;		/* Panel height in mm */
+	int (*setup_sys)(void *sys_ops_handle,
 			 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
-	void (*start_transfer)(void *board_data, void *sys_ops_handle,
+	void (*start_transfer)(void *sys_ops_handle,
 			       struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
-	void (*display_on)(void *board_data, struct fb_info *info);
-	void (*display_off)(void *board_data);
-	int (*set_brightness)(void *board_data, int brightness);
-	int (*get_brightness)(void *board_data);
-};
-
-struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
-	unsigned long width;
-	unsigned long height;
+	void (*display_on)(void);
+	void (*display_off)(void);
 };
 
 /* backlight info */
 struct sh_mobile_lcdc_bl_info {
 	const char *name;
 	int max_brightness;
+	int (*set_brightness)(int brightness);
+	int (*get_brightness)(void);
 };
 
 struct sh_mobile_lcdc_chan_cfg {
@@ -179,13 +173,14 @@
 	int interface_type; /* selects RGBn or SYSn I/F, see above */
 	int clock_divider;
 	unsigned long flags; /* LCDC_FLAGS_... */
-	const struct fb_videomode *lcd_cfg;
-	int num_cfg;
-	struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg;
-	struct sh_mobile_lcdc_board_cfg board_cfg;
+	const struct fb_videomode *lcd_modes;
+	int num_modes;
+	struct sh_mobile_lcdc_panel_cfg panel_cfg;
 	struct sh_mobile_lcdc_bl_info bl_info;
 	struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
-	struct sh_mobile_meram_cfg *meram_cfg;
+	const struct sh_mobile_meram_cfg *meram_cfg;
+
+	struct platform_device *tx_dev;	/* HDMI/DSI transmitter device */
 };
 
 struct sh_mobile_lcdc_info {
diff --git a/include/video/sh_mobile_meram.h b/include/video/sh_mobile_meram.h
index af602d6..29b2fd3 100644
--- a/include/video/sh_mobile_meram.h
+++ b/include/video/sh_mobile_meram.h
@@ -17,52 +17,47 @@
 struct sh_mobile_meram_priv;
 struct sh_mobile_meram_ops;
 
+/*
+ * struct sh_mobile_meram_info - MERAM platform data
+ * @reserved_icbs: Bitmask of reserved ICBs (for instance used through UIO)
+ */
 struct sh_mobile_meram_info {
 	int				addr_mode;
+	u32				reserved_icbs;
 	struct sh_mobile_meram_ops	*ops;
 	struct sh_mobile_meram_priv	*priv;
 	struct platform_device		*pdev;
 };
 
 /* icb config */
-struct sh_mobile_meram_icb {
-	int marker_icb;		/* ICB # for Marker ICB */
-	int cache_icb;		/* ICB # for Cache ICB */
-	int meram_offset;	/* MERAM Buffer Offset to use */
-	int meram_size;		/* MERAM Buffer Size to use */
-
-	int cache_unit;		/* bytes to cache per ICB */
+struct sh_mobile_meram_icb_cfg {
+	unsigned int meram_size;	/* MERAM Buffer Size to use */
 };
 
 struct sh_mobile_meram_cfg {
-	struct sh_mobile_meram_icb	icb[2];
-	int				pixelformat;
-	int				current_reg;
+	struct sh_mobile_meram_icb_cfg icb[2];
 };
 
 struct module;
 struct sh_mobile_meram_ops {
 	struct module	*module;
 	/* register usage of meram */
-	int (*meram_register)(struct sh_mobile_meram_info *meram_dev,
-			      struct sh_mobile_meram_cfg *cfg,
-			      int xres, int yres, int pixelformat,
-			      unsigned long base_addr_y,
-			      unsigned long base_addr_c,
-			      unsigned long *icb_addr_y,
-			      unsigned long *icb_addr_c, int *pitch);
+	void *(*meram_register)(struct sh_mobile_meram_info *meram_dev,
+				const struct sh_mobile_meram_cfg *cfg,
+				unsigned int xres, unsigned int yres,
+				unsigned int pixelformat,
+				unsigned int *pitch);
 
 	/* unregister usage of meram */
-	int (*meram_unregister)(struct sh_mobile_meram_info *meram_dev,
-				struct sh_mobile_meram_cfg *cfg);
+	void (*meram_unregister)(struct sh_mobile_meram_info *meram_dev,
+				 void *data);
 
 	/* update meram settings */
-	int (*meram_update)(struct sh_mobile_meram_info *meram_dev,
-			    struct sh_mobile_meram_cfg *cfg,
-			    unsigned long base_addr_y,
-			    unsigned long base_addr_c,
-			    unsigned long *icb_addr_y,
-			    unsigned long *icb_addr_c);
+	void (*meram_update)(struct sh_mobile_meram_info *meram_dev, void *data,
+			     unsigned long base_addr_y,
+			     unsigned long base_addr_c,
+			     unsigned long *icb_addr_y,
+			     unsigned long *icb_addr_c);
 };
 
 #endif /* __VIDEO_SH_MOBILE_MERAM_H__  */
diff --git a/include/video/udlfb.h b/include/video/udlfb.h
index c41f308..f9466fa 100644
--- a/include/video/udlfb.h
+++ b/include/video/udlfb.h
@@ -41,6 +41,7 @@
 	char *backing_buffer;
 	int fb_count;
 	bool virtualized; /* true when physical usb device not present */
+	struct delayed_work init_framebuffer_work;
 	struct delayed_work free_framebuffer_work;
 	atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
 	atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index ba36013..1b5c081 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -2303,7 +2303,7 @@
 static DEFINE_PER_CPU(int, perf_throttled_count);
 static DEFINE_PER_CPU(u64, perf_throttled_seq);
 
-static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count)
+static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count, bool disable)
 {
 	struct hw_perf_event *hwc = &event->hw;
 	s64 period, sample_period;
@@ -2322,9 +2322,13 @@
 	hwc->sample_period = sample_period;
 
 	if (local64_read(&hwc->period_left) > 8*sample_period) {
-		event->pmu->stop(event, PERF_EF_UPDATE);
+		if (disable)
+			event->pmu->stop(event, PERF_EF_UPDATE);
+
 		local64_set(&hwc->period_left, 0);
-		event->pmu->start(event, PERF_EF_RELOAD);
+
+		if (disable)
+			event->pmu->start(event, PERF_EF_RELOAD);
 	}
 }
 
@@ -2350,6 +2354,7 @@
 		return;
 
 	raw_spin_lock(&ctx->lock);
+	perf_pmu_disable(ctx->pmu);
 
 	list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
 		if (event->state != PERF_EVENT_STATE_ACTIVE)
@@ -2381,13 +2386,17 @@
 		/*
 		 * restart the event
 		 * reload only if value has changed
+		 * we have stopped the event so tell that
+		 * to perf_adjust_period() to avoid stopping it
+		 * twice.
 		 */
 		if (delta > 0)
-			perf_adjust_period(event, period, delta);
+			perf_adjust_period(event, period, delta, false);
 
 		event->pmu->start(event, delta > 0 ? PERF_EF_RELOAD : 0);
 	}
 
+	perf_pmu_enable(ctx->pmu);
 	raw_spin_unlock(&ctx->lock);
 }
 
@@ -4562,7 +4571,7 @@
 		hwc->freq_time_stamp = now;
 
 		if (delta > 0 && delta < 2*TICK_NSEC)
-			perf_adjust_period(event, delta, hwc->last_period);
+			perf_adjust_period(event, delta, hwc->last_period, true);
 	}
 
 	/*
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c
index b7971d6..ee706ce 100644
--- a/kernel/events/hw_breakpoint.c
+++ b/kernel/events/hw_breakpoint.c
@@ -651,10 +651,10 @@
 
  err_alloc:
 	for_each_possible_cpu(err_cpu) {
-		if (err_cpu == cpu)
-			break;
 		for (i = 0; i < TYPE_MAX; i++)
 			kfree(per_cpu(nr_task_bp_pinned[i], cpu));
+		if (err_cpu == cpu)
+			break;
 	}
 
 	return -ENOMEM;
diff --git a/kernel/fork.c b/kernel/fork.c
index 1b2ef3c..e2cd3e2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -66,6 +66,7 @@
 #include <linux/user-return-notifier.h>
 #include <linux/oom.h>
 #include <linux/khugepaged.h>
+#include <linux/signalfd.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -910,7 +911,7 @@
 			return -ENOMEM;
 
 		new_ioc->ioprio = ioc->ioprio;
-		put_io_context(new_ioc, NULL);
+		put_io_context(new_ioc);
 	}
 #endif
 	return 0;
@@ -935,8 +936,10 @@
 
 void __cleanup_sighand(struct sighand_struct *sighand)
 {
-	if (atomic_dec_and_test(&sighand->count))
+	if (atomic_dec_and_test(&sighand->count)) {
+		signalfd_cleanup(sighand);
 		kmem_cache_free(sighand_cachep, sighand);
+	}
 }
 
 
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 342d8f4..0119b9d 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -53,7 +53,7 @@
 			if (desc->irq_data.chip->irq_set_type)
 				desc->irq_data.chip->irq_set_type(&desc->irq_data,
 							 IRQ_TYPE_PROBE);
-			irq_startup(desc);
+			irq_startup(desc, false);
 		}
 		raw_spin_unlock_irq(&desc->lock);
 	}
@@ -70,7 +70,7 @@
 		raw_spin_lock_irq(&desc->lock);
 		if (!desc->action && irq_settings_can_probe(desc)) {
 			desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
-			if (irq_startup(desc))
+			if (irq_startup(desc, false))
 				desc->istate |= IRQS_PENDING;
 		}
 		raw_spin_unlock_irq(&desc->lock);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index f7c543a..fb7db75 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -157,19 +157,22 @@
 	irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
 }
 
-int irq_startup(struct irq_desc *desc)
+int irq_startup(struct irq_desc *desc, bool resend)
 {
+	int ret = 0;
+
 	irq_state_clr_disabled(desc);
 	desc->depth = 0;
 
 	if (desc->irq_data.chip->irq_startup) {
-		int ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
+		ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
 		irq_state_clr_masked(desc);
-		return ret;
+	} else {
+		irq_enable(desc);
 	}
-
-	irq_enable(desc);
-	return 0;
+	if (resend)
+		check_irq_resend(desc, desc->irq_data.irq);
+	return ret;
 }
 
 void irq_shutdown(struct irq_desc *desc)
@@ -330,6 +333,24 @@
 }
 EXPORT_SYMBOL_GPL(handle_simple_irq);
 
+/*
+ * Called unconditionally from handle_level_irq() and only for oneshot
+ * interrupts from handle_fasteoi_irq()
+ */
+static void cond_unmask_irq(struct irq_desc *desc)
+{
+	/*
+	 * We need to unmask in the following cases:
+	 * - Standard level irq (IRQF_ONESHOT is not set)
+	 * - Oneshot irq which did not wake the thread (caused by a
+	 *   spurious interrupt or a primary handler handling it
+	 *   completely).
+	 */
+	if (!irqd_irq_disabled(&desc->irq_data) &&
+	    irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot)
+		unmask_irq(desc);
+}
+
 /**
  *	handle_level_irq - Level type irq handler
  *	@irq:	the interrupt number
@@ -362,8 +383,8 @@
 
 	handle_irq_event(desc);
 
-	if (!irqd_irq_disabled(&desc->irq_data) && !(desc->istate & IRQS_ONESHOT))
-		unmask_irq(desc);
+	cond_unmask_irq(desc);
+
 out_unlock:
 	raw_spin_unlock(&desc->lock);
 }
@@ -417,6 +438,9 @@
 	preflow_handler(desc);
 	handle_irq_event(desc);
 
+	if (desc->istate & IRQS_ONESHOT)
+		cond_unmask_irq(desc);
+
 out_eoi:
 	desc->irq_data.chip->irq_eoi(&desc->irq_data);
 out_unlock:
@@ -625,7 +649,7 @@
 		irq_settings_set_noprobe(desc);
 		irq_settings_set_norequest(desc);
 		irq_settings_set_nothread(desc);
-		irq_startup(desc);
+		irq_startup(desc, true);
 	}
 out:
 	irq_put_desc_busunlock(desc, flags);
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index b795231..40378ff 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -67,7 +67,7 @@
 extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
 extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
 
-extern int irq_startup(struct irq_desc *desc);
+extern int irq_startup(struct irq_desc *desc, bool resend);
 extern void irq_shutdown(struct irq_desc *desc);
 extern void irq_enable(struct irq_desc *desc);
 extern void irq_disable(struct irq_desc *desc);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a9a9dbe..32313c0 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1027,7 +1027,7 @@
 			desc->istate |= IRQS_ONESHOT;
 
 		if (irq_settings_can_autoenable(desc))
-			irq_startup(desc);
+			irq_startup(desc, true);
 		else
 			/* Undo nested disables: */
 			desc->depth = 1;
diff --git a/kernel/params.c b/kernel/params.c
index 32ee043..4bc965d 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -97,7 +97,8 @@
 	for (i = 0; i < num_params; i++) {
 		if (parameq(param, params[i].name)) {
 			/* No one handled NULL, so do it here. */
-			if (!val && params[i].ops->set != param_set_bool)
+			if (!val && params[i].ops->set != param_set_bool
+			    && params[i].ops->set != param_set_bint)
 				return -EINVAL;
 			pr_debug("They are equal!  Calling %p\n",
 			       params[i].ops->set);
diff --git a/kernel/pid.c b/kernel/pid.c
index ce8e00d..9f08dfa 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -543,12 +543,12 @@
  */
 void __init pidhash_init(void)
 {
-	int i, pidhash_size;
+	unsigned int i, pidhash_size;
 
 	pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18,
 					   HASH_EARLY | HASH_SMALL,
 					   &pidhash_shift, NULL, 4096);
-	pidhash_size = 1 << pidhash_shift;
+	pidhash_size = 1U << pidhash_shift;
 
 	for (i = 0; i < pidhash_size; i++)
 		INIT_HLIST_HEAD(&pid_hash[i]);
diff --git a/kernel/relay.c b/kernel/relay.c
index 4335e1d..ab56a17 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -164,10 +164,14 @@
  */
 static struct rchan_buf *relay_create_buf(struct rchan *chan)
 {
-	struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
-	if (!buf)
+	struct rchan_buf *buf;
+
+	if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
 		return NULL;
 
+	buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
+	if (!buf)
+		return NULL;
 	buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL);
 	if (!buf->padding)
 		goto free_buf;
@@ -574,6 +578,8 @@
 
 	if (!(subbuf_size && n_subbufs))
 		return NULL;
+	if (subbuf_size > UINT_MAX / n_subbufs)
+		return NULL;
 
 	chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
 	if (!chan)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 5255c9d..33a0676 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1932,7 +1932,6 @@
 	local_irq_enable();
 #endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
 	finish_lock_switch(rq, prev);
-	trace_sched_stat_sleeptime(current, rq->clock);
 
 	fire_sched_in_preempt_notifiers(current);
 	if (mm)
@@ -6729,7 +6728,7 @@
 static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,
 			     void *hcpu)
 {
-	switch (action & ~CPU_TASKS_FROZEN) {
+	switch (action) {
 	case CPU_ONLINE:
 	case CPU_DOWN_FAILED:
 		cpuset_update_active_cpus();
@@ -6742,7 +6741,7 @@
 static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
 			       void *hcpu)
 {
-	switch (action & ~CPU_TASKS_FROZEN) {
+	switch (action) {
 	case CPU_DOWN_PREPARE:
 		cpuset_update_active_cpus();
 		return NOTIFY_OK;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7c6414f..aca16b8 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1003,6 +1003,7 @@
 		if (unlikely(delta > se->statistics.sleep_max))
 			se->statistics.sleep_max = delta;
 
+		se->statistics.sleep_start = 0;
 		se->statistics.sum_sleep_runtime += delta;
 
 		if (tsk) {
@@ -1019,6 +1020,7 @@
 		if (unlikely(delta > se->statistics.block_max))
 			se->statistics.block_max = delta;
 
+		se->statistics.block_start = 0;
 		se->statistics.sum_sleep_runtime += delta;
 
 		if (tsk) {
diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index 7a94c8f..b1dd3e7 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -44,12 +44,13 @@
  *
  * Don't you dare use this function.
  */
-unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *res)
+unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
 {
+	unsigned long long res;
 	unsigned int rv;
 	int overflow;
 
-	*res = 0;
+	res = 0;
 	rv = 0;
 	overflow = 0;
 	while (*s) {
@@ -64,12 +65,19 @@
 
 		if (val >= base)
 			break;
-		if (*res > div_u64(ULLONG_MAX - val, base))
-			overflow = 1;
-		*res = *res * base + val;
+		/*
+		 * Check for overflow only if we are within range of
+		 * it in the max base we support (16)
+		 */
+		if (unlikely(res & (~0ull << 60))) {
+			if (res > div_u64(ULLONG_MAX - val, base))
+				overflow = 1;
+		}
+		res = res * base + val;
 		rv++;
 		s++;
 	}
+	*p = res;
 	if (overflow)
 		rv |= KSTRTOX_OVERFLOW;
 	return rv;
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 7ba8fea..dd8e2aa 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -318,7 +318,7 @@
 	if (bdi->wb.task) {
 		trace_writeback_wake_thread(bdi);
 		wake_up_process(bdi->wb.task);
-	} else {
+	} else if (bdi->dev) {
 		/*
 		 * When bdi tasks are inactive for long time, they are killed.
 		 * In this case we have to wake-up the forker thread which
@@ -584,6 +584,8 @@
  */
 static void bdi_wb_shutdown(struct backing_dev_info *bdi)
 {
+	struct task_struct *task;
+
 	if (!bdi_cap_writeback_dirty(bdi))
 		return;
 
@@ -602,8 +604,13 @@
 	 * Finally, kill the kernel thread. We don't need to be RCU
 	 * safe anymore, since the bdi is gone from visibility.
 	 */
-	if (bdi->wb.task)
-		kthread_stop(bdi->wb.task);
+	spin_lock_bh(&bdi->wb_lock);
+	task = bdi->wb.task;
+	bdi->wb.task = NULL;
+	spin_unlock_bh(&bdi->wb_lock);
+
+	if (task)
+		kthread_stop(task);
 }
 
 /*
@@ -623,7 +630,9 @@
 
 void bdi_unregister(struct backing_dev_info *bdi)
 {
-	if (bdi->dev) {
+	struct device *dev = bdi->dev;
+
+	if (dev) {
 		bdi_set_min_ratio(bdi, 0);
 		trace_writeback_bdi_unregister(bdi);
 		bdi_prune_sb(bdi);
@@ -632,8 +641,12 @@
 		if (!bdi_cap_flush_forker(bdi))
 			bdi_wb_shutdown(bdi);
 		bdi_debug_unregister(bdi);
-		device_unregister(bdi->dev);
+
+		spin_lock_bh(&bdi->wb_lock);
 		bdi->dev = NULL;
+		spin_unlock_bh(&bdi->wb_lock);
+
+		device_unregister(dev);
 	}
 }
 EXPORT_SYMBOL(bdi_unregister);
diff --git a/mm/memblock.c b/mm/memblock.c
index 77b5f22..99f2855 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -99,9 +99,6 @@
 	phys_addr_t this_start, this_end, cand;
 	u64 i;
 
-	/* align @size to avoid excessive fragmentation on reserved array */
-	size = round_up(size, align);
-
 	/* pump up @end */
 	if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
 		end = memblock.current_limit;
@@ -731,6 +728,9 @@
 {
 	phys_addr_t found;
 
+	/* align @size to avoid excessive fragmentation on reserved array */
+	size = round_up(size, align);
+
 	found = memblock_find_in_range_node(0, max_addr, size, align, nid);
 	if (found && !memblock_reserve(found, size))
 		return found;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6728a7a..228d646 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4414,6 +4414,9 @@
 	 */
 	BUG_ON(!thresholds);
 
+	if (!thresholds->primary)
+		goto unlock;
+
 	usage = mem_cgroup_usage(memcg, type == _MEMSWAP);
 
 	/* Check if a threshold crossed before removing */
@@ -4462,7 +4465,7 @@
 
 	/* To be sure that nobody uses thresholds */
 	synchronize_rcu();
-
+unlock:
 	mutex_unlock(&memcg->thresholds_lock);
 }
 
diff --git a/mm/nommu.c b/mm/nommu.c
index b982290..f59e170 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -696,9 +696,11 @@
 	if (vma->vm_file) {
 		mapping = vma->vm_file->f_mapping;
 
+		mutex_lock(&mapping->i_mmap_mutex);
 		flush_dcache_mmap_lock(mapping);
 		vma_prio_tree_insert(vma, &mapping->i_mmap);
 		flush_dcache_mmap_unlock(mapping);
+		mutex_unlock(&mapping->i_mmap_mutex);
 	}
 
 	/* add the VMA to the tree */
@@ -760,9 +762,11 @@
 	if (vma->vm_file) {
 		mapping = vma->vm_file->f_mapping;
 
+		mutex_lock(&mapping->i_mmap_mutex);
 		flush_dcache_mmap_lock(mapping);
 		vma_prio_tree_remove(vma, &mapping->i_mmap);
 		flush_dcache_mmap_unlock(mapping);
+		mutex_unlock(&mapping->i_mmap_mutex);
 	}
 
 	/* remove from the MM's tree and list */
@@ -775,8 +779,6 @@
 
 	if (vma->vm_next)
 		vma->vm_next->vm_prev = vma->vm_prev;
-
-	vma->vm_mm = NULL;
 }
 
 /*
@@ -2052,6 +2054,7 @@
 	high = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
 
 	down_write(&nommu_region_sem);
+	mutex_lock(&inode->i_mapping->i_mmap_mutex);
 
 	/* search for VMAs that fall within the dead zone */
 	vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
@@ -2059,6 +2062,7 @@
 		/* found one - only interested if it's shared out of the page
 		 * cache */
 		if (vma->vm_flags & VM_SHARED) {
+			mutex_unlock(&inode->i_mapping->i_mmap_mutex);
 			up_write(&nommu_region_sem);
 			return -ETXTBSY; /* not quite true, but near enough */
 		}
@@ -2086,6 +2090,7 @@
 		}
 	}
 
+	mutex_unlock(&inode->i_mapping->i_mmap_mutex);
 	up_write(&nommu_region_sem);
 	return 0;
 }
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d2186ec..a13ded1 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5236,6 +5236,7 @@
 		max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
 		do_div(max, bucketsize);
 	}
+	max = min(max, 0x80000000ULL);
 
 	if (numentries > max)
 		numentries = max;
diff --git a/net/atm/clip.c b/net/atm/clip.c
index c12c258..127fe70 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -46,8 +46,8 @@
 
 static struct net_device *clip_devs;
 static struct atm_vcc *atmarpd;
-static struct neigh_table clip_tbl;
 static struct timer_list idle_timer;
+static const struct neigh_ops clip_neigh_ops;
 
 static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
 {
@@ -123,6 +123,8 @@
 	struct atmarp_entry *entry = neighbour_priv(n);
 	struct clip_vcc *cv;
 
+	if (n->ops != &clip_neigh_ops)
+		return 0;
 	for (cv = entry->vccs; cv; cv = cv->next) {
 		unsigned long exp = cv->last_use + cv->idle_timeout;
 
@@ -154,10 +156,10 @@
 
 static void idle_timer_check(unsigned long dummy)
 {
-	write_lock(&clip_tbl.lock);
-	__neigh_for_each_release(&clip_tbl, neigh_check_cb);
+	write_lock(&arp_tbl.lock);
+	__neigh_for_each_release(&arp_tbl, neigh_check_cb);
 	mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
-	write_unlock(&clip_tbl.lock);
+	write_unlock(&arp_tbl.lock);
 }
 
 static int clip_arp_rcv(struct sk_buff *skb)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index ef92864..72eb187 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -71,19 +71,16 @@
 	"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
 };
 
-static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
+void bt_sock_reclassify_lock(struct sock *sk, int proto)
 {
-	struct sock *sk = sock->sk;
-
-	if (!sk)
-		return;
-
+	BUG_ON(!sk);
 	BUG_ON(sock_owned_by_user(sk));
 
 	sock_lock_init_class_and_name(sk,
 			bt_slock_key_strings[proto], &bt_slock_key[proto],
 				bt_key_strings[proto], &bt_lock_key[proto]);
 }
+EXPORT_SYMBOL(bt_sock_reclassify_lock);
 
 int bt_sock_register(int proto, const struct net_proto_family *ops)
 {
@@ -145,7 +142,8 @@
 
 	if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
 		err = bt_proto[proto]->create(net, sock, proto, kern);
-		bt_sock_reclassify_lock(sock, proto);
+		if (!err)
+			bt_sock_reclassify_lock(sock->sk, proto);
 		module_put(bt_proto[proto]->owner);
 	}
 
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 3db4324..07bc69e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -635,6 +635,10 @@
 
 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
 		struct hci_cp_auth_requested cp;
+
+		/* encrypt must be pending if auth is also pending */
+		set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+
 		cp.handle = cpu_to_le16(conn->handle);
 		hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
 							sizeof(cp), &cp);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9de9371..5aeb624 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -640,7 +640,8 @@
 	/* Reset device */
 	skb_queue_purge(&hdev->cmd_q);
 	atomic_set(&hdev->cmd_cnt, 1);
-	if (!test_bit(HCI_RAW, &hdev->flags)) {
+	if (!test_bit(HCI_RAW, &hdev->flags) &&
+				test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
 		set_bit(HCI_INIT, &hdev->flags);
 		__hci_request(hdev, hci_reset_req, 0,
 					msecs_to_jiffies(250));
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index faf0b11..32d338c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1018,10 +1018,10 @@
 	hci_chan_del(conn->hchan);
 
 	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
-		__cancel_delayed_work(&conn->info_timer);
+		cancel_delayed_work_sync(&conn->info_timer);
 
 	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
-		__cancel_delayed_work(&conn->security_timer);
+		cancel_delayed_work_sync(&conn->security_timer);
 		smp_chan_destroy(conn);
 	}
 
@@ -1120,7 +1120,7 @@
 	return c1;
 }
 
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
 {
 	struct sock *sk = chan->sk;
 	bdaddr_t *src = &bt_sk(sk)->src;
@@ -2574,7 +2574,7 @@
 
 	if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
 					cmd->ident == conn->info_ident) {
-		__cancel_delayed_work(&conn->info_timer);
+		cancel_delayed_work(&conn->info_timer);
 
 		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
 		conn->info_ident = 0;
@@ -2970,7 +2970,8 @@
 
 	default:
 		sk->sk_err = ECONNRESET;
-		__set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
+		__set_chan_timer(chan,
+				msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT));
 		l2cap_send_disconn_req(conn, chan, ECONNRESET);
 		goto done;
 	}
@@ -3120,7 +3121,7 @@
 			conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
 		return 0;
 
-	__cancel_delayed_work(&conn->info_timer);
+	cancel_delayed_work(&conn->info_timer);
 
 	if (result != L2CAP_IR_SUCCESS) {
 		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
@@ -4478,7 +4479,8 @@
 	if (encrypt == 0x00) {
 		if (chan->sec_level == BT_SECURITY_MEDIUM) {
 			__clear_chan_timer(chan);
-			__set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
+			__set_chan_timer(chan,
+					msecs_to_jiffies(L2CAP_ENC_TIMEOUT));
 		} else if (chan->sec_level == BT_SECURITY_HIGH)
 			l2cap_chan_close(chan, ECONNREFUSED);
 	} else {
@@ -4499,7 +4501,7 @@
 
 	if (hcon->type == LE_LINK) {
 		smp_distribute_keys(conn, 0);
-		__cancel_delayed_work(&conn->security_timer);
+		cancel_delayed_work(&conn->security_timer);
 	}
 
 	rcu_read_lock();
@@ -4546,7 +4548,8 @@
 					L2CAP_CONN_REQ, sizeof(req), &req);
 			} else {
 				__clear_chan_timer(chan);
-				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+				__set_chan_timer(chan,
+					msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
 			}
 		} else if (chan->state == BT_CONNECT2) {
 			struct l2cap_conn_rsp rsp;
@@ -4566,7 +4569,8 @@
 				}
 			} else {
 				l2cap_state_change(chan, BT_DISCONN);
-				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+				__set_chan_timer(chan,
+					msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
 				res = L2CAP_CR_SEC_BLOCK;
 				stat = L2CAP_CS_NO_INFO;
 			}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c61d967..401d942 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -849,6 +849,8 @@
 	if (!sk)
 		return NULL;
 
+	bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
+
 	l2cap_sock_init(sk, parent);
 
 	return l2cap_pi(sk)->chan;
@@ -1002,7 +1004,7 @@
 	INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
 
 	sk->sk_destruct = l2cap_sock_destruct;
-	sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
+	sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
 
 	sock_reset_flag(sk, SOCK_ZAPPED);
 
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 501649b..8a60238 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1164,12 +1164,18 @@
 			break;
 
 		case BT_DISCONN:
-			/* When socket is closed and we are not RFCOMM
-			 * initiator rfcomm_process_rx already calls
-			 * rfcomm_session_put() */
-			if (s->sock->sk->sk_state != BT_CLOSED)
-				if (list_empty(&s->dlcs))
-					rfcomm_session_put(s);
+			/* rfcomm_session_put is called later so don't do
+			 * anything here otherwise we will mess up the session
+			 * reference counter:
+			 *
+			 * (a) when we are the initiator dlc_unlink will drive
+			 * the reference counter to 0 (there is no initial put
+			 * after session_add)
+			 *
+			 * (b) when we are not the initiator rfcomm_rx_process
+			 * will explicitly call put to balance the initial hold
+			 * done after session add.
+			 */
 			break;
 		}
 	}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index f066678..22169c3 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -956,6 +956,8 @@
 	if (!sk)
 		goto done;
 
+	bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
+
 	rfcomm_sock_init(sk, parent);
 	bacpy(&bt_sk(sk)->src, &src);
 	bacpy(&bt_sk(sk)->dst, &dst);
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index a986280..a97d97a 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -539,8 +539,10 @@
 	pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb);
 	memset(skb->cb, 0, sizeof(struct caif_payload_info));
 
-	if (cf_sk->layer.dn == NULL)
+	if (cf_sk->layer.dn == NULL) {
+		kfree_skb(skb);
 		return -EINVAL;
+	}
 
 	return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
 }
@@ -683,10 +685,10 @@
 		}
 		err = transmit_skb(skb, cf_sk,
 				msg->msg_flags&MSG_DONTWAIT, timeo);
-		if (err < 0) {
-			kfree_skb(skb);
+		if (err < 0)
+			/* skb is already freed */
 			goto pipe_err;
-		}
+
 		sent += size;
 	}
 
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c
index b36f24a..94b0861 100644
--- a/net/caif/cfmuxl.c
+++ b/net/caif/cfmuxl.c
@@ -248,7 +248,6 @@
 {
 	struct cfmuxl *muxl = container_obj(layr);
 	struct cflayer *layer;
-	int idx;
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(layer, &muxl->srvl_list, node) {
@@ -257,14 +256,9 @@
 
 			if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND ||
 				ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) &&
-					layer->id != 0) {
+					layer->id != 0)
+				cfmuxl_remove_uplayer(layr, layer->id);
 
-				idx = layer->id % UP_CACHE_SIZE;
-				spin_lock_bh(&muxl->receive_lock);
-				RCU_INIT_POINTER(muxl->up_cache[idx], NULL);
-				list_del_rcu(&layer->node);
-				spin_unlock_bh(&muxl->receive_lock);
-			}
 			/* NOTE: ctrlcmd is not allowed to block */
 			layer->ctrlcmd(layer, ctrl, phyid);
 		}
diff --git a/net/core/dev.c b/net/core/dev.c
index 115dee1..6ca32f6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3500,14 +3500,20 @@
 __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 {
 	struct sk_buff *p;
+	unsigned int maclen = skb->dev->hard_header_len;
 
 	for (p = napi->gro_list; p; p = p->next) {
 		unsigned long diffs;
 
 		diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
 		diffs |= p->vlan_tci ^ skb->vlan_tci;
-		diffs |= compare_ether_header(skb_mac_header(p),
-					      skb_gro_mac_header(skb));
+		if (maclen == ETH_HLEN)
+			diffs |= compare_ether_header(skb_mac_header(p),
+						      skb_gro_mac_header(skb));
+		else if (!diffs)
+			diffs = memcmp(skb_mac_header(p),
+				       skb_gro_mac_header(skb),
+				       maclen);
 		NAPI_GRO_CB(p)->same_flow = !diffs;
 		NAPI_GRO_CB(p)->flush = 0;
 	}
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 369b418..3f79db1 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1190,6 +1190,8 @@
 	if (!dev->ethtool_ops->flash_device)
 		return -EOPNOTSUPP;
 
+	efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
+
 	return dev->ethtool_ops->flash_device(dev, &efl);
 }
 
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index e287346..2a83914 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -826,6 +826,8 @@
 		write_unlock_bh(&tbl->lock);
 		cond_resched();
 		write_lock_bh(&tbl->lock);
+		nht = rcu_dereference_protected(tbl->nht,
+						lockdep_is_held(&tbl->lock));
 	}
 	/* Cycle through all hash buckets every base_reachable_time/2 ticks.
 	 * ARP entry timeouts range from 1/2 base_reachable_time to 3/2
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 556b082..ddefc51 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -194,7 +194,7 @@
 
 	poll_napi(dev);
 
-	if (dev->priv_flags & IFF_SLAVE) {
+	if (dev->flags & IFF_SLAVE) {
 		if (dev->npinfo) {
 			struct net_device *bond_dev = dev->master;
 			struct sk_buff *skb;
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 3a9fd48..4dacc44 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -58,11 +58,12 @@
 
 	spin_lock_irqsave(&prioidx_map_lock, flags);
 	prioidx = find_first_zero_bit(prioidx_map, sizeof(unsigned long) * PRIOIDX_SZ);
+	if (prioidx == sizeof(unsigned long) * PRIOIDX_SZ) {
+		spin_unlock_irqrestore(&prioidx_map_lock, flags);
+		return -ENOSPC;
+	}
 	set_bit(prioidx, prioidx_map);
 	spin_unlock_irqrestore(&prioidx_map_lock, flags);
-	if (prioidx == sizeof(unsigned long) * PRIOIDX_SZ)
-		return -ENOSPC;
-
 	atomic_set(&max_prioidx, prioidx);
 	*prio = prioidx;
 	return 0;
@@ -107,7 +108,7 @@
 static void update_netdev_tables(void)
 {
 	struct net_device *dev;
-	u32 max_len = atomic_read(&max_prioidx);
+	u32 max_len = atomic_read(&max_prioidx) + 1;
 	struct netprio_map *map;
 
 	rtnl_lock();
@@ -270,7 +271,6 @@
 {
 	struct net_device *dev = ptr;
 	struct netprio_map *old;
-	u32 max_len = atomic_read(&max_prioidx);
 
 	/*
 	 * Note this is called with rtnl_lock held so we have update side
@@ -278,11 +278,6 @@
 	 */
 
 	switch (event) {
-
-	case NETDEV_REGISTER:
-		if (max_len)
-			extend_netdev_table(dev, max_len);
-		break;
 	case NETDEV_UNREGISTER:
 		old = rtnl_dereference(dev->priomap);
 		RCU_INIT_POINTER(dev->priomap, NULL);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 65aebd4..606a6e8 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -60,7 +60,6 @@
 };
 
 static DEFINE_MUTEX(rtnl_mutex);
-static u16 min_ifinfo_dump_size;
 
 void rtnl_lock(void)
 {
@@ -724,10 +723,11 @@
 }
 
 /* All VF info */
-static inline int rtnl_vfinfo_size(const struct net_device *dev)
+static inline int rtnl_vfinfo_size(const struct net_device *dev,
+				   u32 ext_filter_mask)
 {
-	if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
-
+	if (dev->dev.parent && dev_is_pci(dev->dev.parent) &&
+	    (ext_filter_mask & RTEXT_FILTER_VF)) {
 		int num_vfs = dev_num_vf(dev->dev.parent);
 		size_t size = nla_total_size(sizeof(struct nlattr));
 		size += nla_total_size(num_vfs * sizeof(struct nlattr));
@@ -766,7 +766,8 @@
 		return port_self_size;
 }
 
-static noinline size_t if_nlmsg_size(const struct net_device *dev)
+static noinline size_t if_nlmsg_size(const struct net_device *dev,
+				     u32 ext_filter_mask)
 {
 	return NLMSG_ALIGN(sizeof(struct ifinfomsg))
 	       + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -784,8 +785,9 @@
 	       + nla_total_size(4) /* IFLA_MASTER */
 	       + nla_total_size(1) /* IFLA_OPERSTATE */
 	       + nla_total_size(1) /* IFLA_LINKMODE */
-	       + nla_total_size(4) /* IFLA_NUM_VF */
-	       + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
+	       + nla_total_size(ext_filter_mask
+			        & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
+	       + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
 	       + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
 	       + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
 	       + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */
@@ -868,7 +870,7 @@
 
 static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 			    int type, u32 pid, u32 seq, u32 change,
-			    unsigned int flags)
+			    unsigned int flags, u32 ext_filter_mask)
 {
 	struct ifinfomsg *ifm;
 	struct nlmsghdr *nlh;
@@ -941,10 +943,11 @@
 		goto nla_put_failure;
 	copy_rtnl_link_stats64(nla_data(attr), stats);
 
-	if (dev->dev.parent)
+	if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF))
 		NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
 
-	if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
+	if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent
+	    && (ext_filter_mask & RTEXT_FILTER_VF)) {
 		int i;
 
 		struct nlattr *vfinfo, *vf;
@@ -1048,6 +1051,8 @@
 	struct net_device *dev;
 	struct hlist_head *head;
 	struct hlist_node *node;
+	struct nlattr *tb[IFLA_MAX+1];
+	u32 ext_filter_mask = 0;
 
 	s_h = cb->args[0];
 	s_idx = cb->args[1];
@@ -1055,6 +1060,12 @@
 	rcu_read_lock();
 	cb->seq = net->dev_base_seq;
 
+	nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
+		    ifla_policy);
+
+	if (tb[IFLA_EXT_MASK])
+		ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
 	for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
 		idx = 0;
 		head = &net->dev_index_head[h];
@@ -1064,7 +1075,8 @@
 			if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
 					     NETLINK_CB(cb->skb).pid,
 					     cb->nlh->nlmsg_seq, 0,
-					     NLM_F_MULTI) <= 0)
+					     NLM_F_MULTI,
+					     ext_filter_mask) <= 0)
 				goto out;
 
 			nl_dump_check_consistent(cb, nlmsg_hdr(skb));
@@ -1100,6 +1112,7 @@
 	[IFLA_VF_PORTS]		= { .type = NLA_NESTED },
 	[IFLA_PORT_SELF]	= { .type = NLA_NESTED },
 	[IFLA_AF_SPEC]		= { .type = NLA_NESTED },
+	[IFLA_EXT_MASK]		= { .type = NLA_U32 },
 };
 EXPORT_SYMBOL(ifla_policy);
 
@@ -1509,8 +1522,6 @@
 
 	if (send_addr_notify)
 		call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
-	min_ifinfo_dump_size = max_t(u16, if_nlmsg_size(dev),
-				     min_ifinfo_dump_size);
 
 	return err;
 }
@@ -1842,6 +1853,7 @@
 	struct net_device *dev = NULL;
 	struct sk_buff *nskb;
 	int err;
+	u32 ext_filter_mask = 0;
 
 	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
 	if (err < 0)
@@ -1850,6 +1862,9 @@
 	if (tb[IFLA_IFNAME])
 		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
 
+	if (tb[IFLA_EXT_MASK])
+		ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
 	ifm = nlmsg_data(nlh);
 	if (ifm->ifi_index > 0)
 		dev = __dev_get_by_index(net, ifm->ifi_index);
@@ -1861,12 +1876,12 @@
 	if (dev == NULL)
 		return -ENODEV;
 
-	nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
+	nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL);
 	if (nskb == NULL)
 		return -ENOBUFS;
 
 	err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
-			       nlh->nlmsg_seq, 0, 0);
+			       nlh->nlmsg_seq, 0, 0, ext_filter_mask);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in if_nlmsg_size */
 		WARN_ON(err == -EMSGSIZE);
@@ -1877,8 +1892,31 @@
 	return err;
 }
 
-static u16 rtnl_calcit(struct sk_buff *skb)
+static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
+	struct net *net = sock_net(skb->sk);
+	struct net_device *dev;
+	struct nlattr *tb[IFLA_MAX+1];
+	u32 ext_filter_mask = 0;
+	u16 min_ifinfo_dump_size = 0;
+
+	nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ifla_policy);
+
+	if (tb[IFLA_EXT_MASK])
+		ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
+	if (!ext_filter_mask)
+		return NLMSG_GOODSIZE;
+	/*
+	 * traverse the list of net devices and compute the minimum
+	 * buffer size based upon the filter mask.
+	 */
+	list_for_each_entry(dev, &net->dev_base_head, dev_list) {
+		min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
+					     if_nlmsg_size(dev,
+						           ext_filter_mask));
+	}
+
 	return min_ifinfo_dump_size;
 }
 
@@ -1913,13 +1951,11 @@
 	int err = -ENOBUFS;
 	size_t if_info_size;
 
-	skb = nlmsg_new((if_info_size = if_nlmsg_size(dev)), GFP_KERNEL);
+	skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL);
 	if (skb == NULL)
 		goto errout;
 
-	min_ifinfo_dump_size = max_t(u16, if_info_size, min_ifinfo_dump_size);
-
-	err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0);
+	err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0, 0);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in if_nlmsg_size() */
 		WARN_ON(err == -EMSGSIZE);
@@ -1977,7 +2013,7 @@
 			return -EOPNOTSUPP;
 		calcit = rtnl_get_calcit(family, type);
 		if (calcit)
-			min_dump_alloc = calcit(skb);
+			min_dump_alloc = calcit(skb, nlh);
 
 		__rtnl_unlock();
 		rtnl = net->rtnl;
diff --git a/net/core/sock.c b/net/core/sock.c
index 3e81fd2..02f8dfe 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1171,13 +1171,10 @@
 
 void sock_update_netprioidx(struct sock *sk)
 {
-	struct cgroup_netprio_state *state;
 	if (in_interrupt())
 		return;
-	rcu_read_lock();
-	state = task_netprio_state(current);
-	sk->sk_cgrp_prioidx = state ? state->prioidx : 0;
-	rcu_read_unlock();
+
+	sk->sk_cgrp_prioidx = task_netprioidx(current);
 }
 EXPORT_SYMBOL_GPL(sock_update_netprioidx);
 #endif
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index aa2a2c7..d183262 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -409,7 +409,7 @@
 
 config INET_UDP_DIAG
 	tristate "UDP: socket monitoring interface"
-	depends on INET_DIAG
+	depends on INET_DIAG && (IPV6 || IPV6=n)
 	default n
 	---help---
 	  Support for UDP socket monitoring interface used by the ss tool.
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 59402be..63e4989 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -863,7 +863,8 @@
 			if (addr_type == RTN_UNICAST  &&
 			    (arp_fwd_proxy(in_dev, dev, rt) ||
 			     arp_fwd_pvlan(in_dev, dev, rt, sip, tip) ||
-			     pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) {
+			     (rt->dst.dev != dev &&
+			      pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))) {
 				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
 				if (n)
 					neigh_release(n);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6b3ca5b..38673d2 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -65,7 +65,7 @@
    it is infeasible task. The most general solutions would be
    to keep skb->encapsulation counter (sort of local ttl),
    and silently drop packet when it expires. It is a good
-   solution, but it supposes maintaing new variable in ALL
+   solution, but it supposes maintaining new variable in ALL
    skb, even if no tunneling is used.
 
    Current solution: xmit_recursion breaks dead loops. This is a percpu
@@ -91,14 +91,14 @@
 
    One of them is to parse packet trying to detect inner encapsulation
    made by our node. It is difficult or even impossible, especially,
-   taking into account fragmentation. TO be short, tt is not solution at all.
+   taking into account fragmentation. TO be short, ttl is not solution at all.
 
    Current solution: The solution was UNEXPECTEDLY SIMPLE.
    We force DF flag on tunnels with preconfigured hop limit,
    that is ALL. :-) Well, it does not remove the problem completely,
    but exponential growth of network traffic is changed to linear
    (branches, that exceed pmtu are pruned) and tunnel mtu
-   fastly degrades to value <68, where looping stops.
+   rapidly degrades to value <68, where looping stops.
    Yes, it is not good if there exists a router in the loop,
    which does not force DF, even when encapsulating packets have DF set.
    But it is not our problem! Nobody could accuse us, we made
@@ -457,8 +457,8 @@
    GRE tunnels with enabled checksum. Tell them "thank you".
 
    Well, I wonder, rfc1812 was written by Cisco employee,
-   what the hell these idiots break standrads established
-   by themself???
+   what the hell these idiots break standards established
+   by themselves???
  */
 
 	const struct iphdr *iph = (const struct iphdr *)skb->data;
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 1e60f76..42dd1a9 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -573,8 +573,8 @@
 		}
 		if (srrptr + 3 <= srrspace) {
 			opt->is_changed = 1;
-			ip_rt_get_source(&optptr[srrptr-1], skb, rt);
 			ip_hdr(skb)->daddr = opt->nexthop;
+			ip_rt_get_source(&optptr[srrptr-1], skb, rt);
 			optptr[2] = srrptr+4;
 		} else if (net_ratelimit())
 			printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index aea5a19..b072386 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -630,6 +630,7 @@
 
 	pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
 
+	err = -EOPNOTSUPP;
 	if (flags & MSG_OOB)
 		goto out;
 
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 4cb9cd2..7a7724d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -778,7 +778,6 @@
 static __net_init int ipv4_sysctl_init_net(struct net *net)
 {
 	struct ctl_table *table;
-	unsigned long limit;
 
 	table = ipv4_net_table;
 	if (!net_eq(net, &init_net)) {
@@ -815,11 +814,6 @@
 	net->ipv4.sysctl_rt_cache_rebuild_count = 4;
 
 	tcp_init_mem(net);
-	limit = nr_free_buffer_pages() / 8;
-	limit = max(limit, 128UL);
-	net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3;
-	net->ipv4.sysctl_tcp_mem[1] = limit;
-	net->ipv4.sysctl_tcp_mem[2] = net->ipv4.sysctl_tcp_mem[0] * 2;
 
 	net->ipv4.ipv4_hdr = register_net_sysctl_table(net,
 			net_ipv4_ctl_path, table);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 06373b4..22ef5f9 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1876,6 +1876,20 @@
 }
 EXPORT_SYMBOL(tcp_shutdown);
 
+bool tcp_check_oom(struct sock *sk, int shift)
+{
+	bool too_many_orphans, out_of_socket_memory;
+
+	too_many_orphans = tcp_too_many_orphans(sk, shift);
+	out_of_socket_memory = tcp_out_of_memory(sk);
+
+	if (too_many_orphans && net_ratelimit())
+		pr_info("TCP: too many orphaned sockets\n");
+	if (out_of_socket_memory && net_ratelimit())
+		pr_info("TCP: out of memory -- consider tuning tcp_mem\n");
+	return too_many_orphans || out_of_socket_memory;
+}
+
 void tcp_close(struct sock *sk, long timeout)
 {
 	struct sk_buff *skb;
@@ -2015,10 +2029,7 @@
 	}
 	if (sk->sk_state != TCP_CLOSE) {
 		sk_mem_reclaim(sk);
-		if (tcp_too_many_orphans(sk, 0)) {
-			if (net_ratelimit())
-				printk(KERN_INFO "TCP: too many of orphaned "
-				       "sockets\n");
+		if (tcp_check_oom(sk, 0)) {
 			tcp_set_state(sk, TCP_CLOSE);
 			tcp_send_active_reset(sk, GFP_ATOMIC);
 			NET_INC_STATS_BH(sock_net(sk),
@@ -3218,7 +3229,6 @@
 
 void tcp_init_mem(struct net *net)
 {
-	/* Set per-socket limits to no more than 1/128 the pressure threshold */
 	unsigned long limit = nr_free_buffer_pages() / 8;
 	limit = max(limit, 128UL);
 	net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3;
@@ -3230,7 +3240,8 @@
 {
 	struct sk_buff *skb = NULL;
 	unsigned long limit;
-	int i, max_share, cnt;
+	int max_share, cnt;
+	unsigned int i;
 	unsigned long jiffy = jiffies;
 
 	BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
@@ -3273,7 +3284,7 @@
 					&tcp_hashinfo.bhash_size,
 					NULL,
 					64 * 1024);
-	tcp_hashinfo.bhash_size = 1 << tcp_hashinfo.bhash_size;
+	tcp_hashinfo.bhash_size = 1U << tcp_hashinfo.bhash_size;
 	for (i = 0; i < tcp_hashinfo.bhash_size; i++) {
 		spin_lock_init(&tcp_hashinfo.bhash[i].lock);
 		INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain);
@@ -3287,7 +3298,8 @@
 	sysctl_max_syn_backlog = max(128, cnt / 256);
 
 	tcp_init_mem(&init_net);
-	limit = nr_free_buffer_pages() / 8;
+	/* Set per-socket limits to no more than 1/128 the pressure threshold */
+	limit = nr_free_buffer_pages() << (PAGE_SHIFT - 10);
 	limit = max(limit, 128UL);
 	max_share = min(4UL*1024*1024, limit);
 
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 976034f..53c8ce4 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1307,25 +1307,26 @@
 	return in_sack;
 }
 
-static u8 tcp_sacktag_one(const struct sk_buff *skb, struct sock *sk,
-			  struct tcp_sacktag_state *state,
+/* Mark the given newly-SACKed range as such, adjusting counters and hints. */
+static u8 tcp_sacktag_one(struct sock *sk,
+			  struct tcp_sacktag_state *state, u8 sacked,
+			  u32 start_seq, u32 end_seq,
 			  int dup_sack, int pcount)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	u8 sacked = TCP_SKB_CB(skb)->sacked;
 	int fack_count = state->fack_count;
 
 	/* Account D-SACK for retransmitted packet. */
 	if (dup_sack && (sacked & TCPCB_RETRANS)) {
 		if (tp->undo_marker && tp->undo_retrans &&
-		    after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker))
+		    after(end_seq, tp->undo_marker))
 			tp->undo_retrans--;
 		if (sacked & TCPCB_SACKED_ACKED)
 			state->reord = min(fack_count, state->reord);
 	}
 
 	/* Nothing to do; acked frame is about to be dropped (was ACKed). */
-	if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
+	if (!after(end_seq, tp->snd_una))
 		return sacked;
 
 	if (!(sacked & TCPCB_SACKED_ACKED)) {
@@ -1344,13 +1345,13 @@
 				/* New sack for not retransmitted frame,
 				 * which was in hole. It is reordering.
 				 */
-				if (before(TCP_SKB_CB(skb)->seq,
+				if (before(start_seq,
 					   tcp_highest_sack_seq(tp)))
 					state->reord = min(fack_count,
 							   state->reord);
 
 				/* SACK enhanced F-RTO (RFC4138; Appendix B) */
-				if (!after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark))
+				if (!after(end_seq, tp->frto_highmark))
 					state->flag |= FLAG_ONLY_ORIG_SACKED;
 			}
 
@@ -1368,8 +1369,7 @@
 
 		/* Lost marker hint past SACKed? Tweak RFC3517 cnt */
 		if (!tcp_is_fack(tp) && (tp->lost_skb_hint != NULL) &&
-		    before(TCP_SKB_CB(skb)->seq,
-			   TCP_SKB_CB(tp->lost_skb_hint)->seq))
+		    before(start_seq, TCP_SKB_CB(tp->lost_skb_hint)->seq))
 			tp->lost_cnt_hint += pcount;
 
 		if (fack_count > tp->fackets_out)
@@ -1388,6 +1388,9 @@
 	return sacked;
 }
 
+/* Shift newly-SACKed bytes from this skb to the immediately previous
+ * already-SACKed sk_buff. Mark the newly-SACKed bytes as such.
+ */
 static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
 			   struct tcp_sacktag_state *state,
 			   unsigned int pcount, int shifted, int mss,
@@ -1395,10 +1398,13 @@
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *prev = tcp_write_queue_prev(sk, skb);
+	u32 start_seq = TCP_SKB_CB(skb)->seq;	/* start of newly-SACKed */
+	u32 end_seq = start_seq + shifted;	/* end of newly-SACKed */
 
 	BUG_ON(!pcount);
 
-	if (skb == tp->lost_skb_hint)
+	/* Adjust hint for FACK. Non-FACK is handled in tcp_sacktag_one(). */
+	if (tcp_is_fack(tp) && (skb == tp->lost_skb_hint))
 		tp->lost_cnt_hint += pcount;
 
 	TCP_SKB_CB(prev)->end_seq += shifted;
@@ -1424,8 +1430,11 @@
 		skb_shinfo(skb)->gso_type = 0;
 	}
 
-	/* We discard results */
-	tcp_sacktag_one(skb, sk, state, dup_sack, pcount);
+	/* Adjust counters and hints for the newly sacked sequence range but
+	 * discard the return value since prev is already marked.
+	 */
+	tcp_sacktag_one(sk, state, TCP_SKB_CB(skb)->sacked,
+			start_seq, end_seq, dup_sack, pcount);
 
 	/* Difference in this won't matter, both ACKed by the same cumul. ACK */
 	TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS);
@@ -1664,10 +1673,14 @@
 			break;
 
 		if (in_sack) {
-			TCP_SKB_CB(skb)->sacked = tcp_sacktag_one(skb, sk,
-								  state,
-								  dup_sack,
-								  tcp_skb_pcount(skb));
+			TCP_SKB_CB(skb)->sacked =
+				tcp_sacktag_one(sk,
+						state,
+						TCP_SKB_CB(skb)->sacked,
+						TCP_SKB_CB(skb)->seq,
+						TCP_SKB_CB(skb)->end_seq,
+						dup_sack,
+						tcp_skb_pcount(skb));
 
 			if (!before(TCP_SKB_CB(skb)->seq,
 				    tcp_highest_sack_seq(tp)))
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 337ba4c..94d683a 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -651,6 +651,11 @@
 				      arg.iov[0].iov_len, IPPROTO_TCP, 0);
 	arg.csumoffset = offsetof(struct tcphdr, check) / 2;
 	arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
+	/* When socket is gone, all binding information is lost.
+	 * routing might fail in this case. using iif for oif to
+	 * make sure we can deliver it
+	 */
+	arg.bound_dev_if = sk ? sk->sk_bound_dev_if : inet_iif(skb);
 
 	net = dev_net(skb_dst(skb)->dev);
 	arg.tos = ip_hdr(skb)->tos;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index a516d1e..cd2e072 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -77,10 +77,7 @@
 	if (sk->sk_err_soft)
 		shift++;
 
-	if (tcp_too_many_orphans(sk, shift)) {
-		if (net_ratelimit())
-			printk(KERN_INFO "Out of socket memory\n");
-
+	if (tcp_check_oom(sk, shift)) {
 		/* Catch exceptional cases, when connection requires reset.
 		 *      1. Last segment was sent recently. */
 		if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN ||
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 6341818..e3db3f9 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -110,10 +110,7 @@
 
 	skb_push(skb, sizeof(*iph));
 	skb_reset_network_header(skb);
-
-	memmove(skb->data - skb->mac_len, skb_mac_header(skb),
-		skb->mac_len);
-	skb_set_mac_header(skb, -skb->mac_len);
+	skb_mac_header_rebuild(skb);
 
 	xfrm4_beet_make_header(skb);
 
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 534972e..ed4bf11 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -66,7 +66,6 @@
 
 static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-	const unsigned char *old_mac;
 	int err = -EINVAL;
 
 	if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
@@ -84,10 +83,9 @@
 	if (!(x->props.flags & XFRM_STATE_NOECN))
 		ipip_ecn_decapsulate(skb);
 
-	old_mac = skb_mac_header(skb);
-	skb_set_mac_header(skb, -skb->mac_len);
-	memmove(skb_mac_header(skb), old_mac, skb->mac_len);
 	skb_reset_network_header(skb);
+	skb_mac_header_rebuild(skb);
+
 	err = 0;
 
 out:
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index c7e95c8..5aa3981 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1926,8 +1926,10 @@
 	};
 
 	dst = ip6_route_output(net, NULL, &fl6);
-	if (!dst)
+	if (dst->error) {
+		dst_release(dst);
 		goto out_free;
+	}
 
 	skb_dst_drop(skb);
 	skb_dst_set(skb, dst);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index d8f02ef..c964958 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1545,9 +1545,10 @@
 			 &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
 
 	dst = ip6_route_output(net, NULL, &fl6);
-	if (dst == NULL)
+	if (dst->error) {
+		dst_release(dst);
 		return;
-
+	}
 	dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
 	if (IS_ERR(dst))
 		return;
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index a81ce94..9949a35 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -80,7 +80,6 @@
 static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
 {
 	struct ipv6hdr *ip6h;
-	const unsigned char *old_mac;
 	int size = sizeof(struct ipv6hdr);
 	int err;
 
@@ -90,10 +89,7 @@
 
 	__skb_push(skb, size);
 	skb_reset_network_header(skb);
-
-	old_mac = skb_mac_header(skb);
-	skb_set_mac_header(skb, -skb->mac_len);
-	memmove(skb_mac_header(skb), old_mac, skb->mac_len);
+	skb_mac_header_rebuild(skb);
 
 	xfrm6_beet_make_header(skb);
 
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 261e6e6..9f2095b 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -63,7 +63,6 @@
 static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
 	int err = -EINVAL;
-	const unsigned char *old_mac;
 
 	if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
 		goto out;
@@ -80,10 +79,9 @@
 	if (!(x->props.flags & XFRM_STATE_NOECN))
 		ipip6_ecn_decapsulate(skb);
 
-	old_mac = skb_mac_header(skb);
-	skb_set_mac_header(skb, -skb->mac_len);
-	memmove(skb_mac_header(skb), old_mac, skb->mac_len);
 	skb_reset_network_header(skb);
+	skb_mac_header_rebuild(skb);
+
 	err = 0;
 
 out:
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 2406b3e..d86217d 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -63,14 +63,14 @@
 	test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
 
 	int res = scnprintf(buf, sizeof(buf),
-			    "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+			    "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
 			    TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
 			    TEST(PS_DRIVER), TEST(AUTHORIZED),
 			    TEST(SHORT_PREAMBLE),
 			    TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
 			    TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
 			    TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
-			    TEST(TDLS_PEER_AUTH));
+			    TEST(TDLS_PEER_AUTH), TEST(RATE_CONTROL));
 #undef TEST
 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 }
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0a0d94a..b142bd4 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -910,6 +910,8 @@
 		wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
 			    result);
 
+	ieee80211_led_init(local);
+
 	rtnl_lock();
 
 	result = ieee80211_init_rate_ctrl_alg(local,
@@ -931,8 +933,6 @@
 
 	rtnl_unlock();
 
-	ieee80211_led_init(local);
-
 	local->network_latency_notifier.notifier_call =
 		ieee80211_max_network_latency;
 	result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 5a5a776..ad64f4d 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -336,7 +336,7 @@
 	int i;
 	u32 mask;
 
-	if (sta) {
+	if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
 		ista = &sta->sta;
 		priv_sta = sta->rate_ctrl_priv;
 	}
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 168427b..80cfc00 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -41,7 +41,7 @@
 	struct ieee80211_sta *ista = &sta->sta;
 	void *priv_sta = sta->rate_ctrl_priv;
 
-	if (!ref)
+	if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
 		return;
 
 	ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
@@ -62,6 +62,7 @@
 	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
 	ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
+	set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
 }
 
 static inline void rate_control_rate_update(struct ieee80211_local *local,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 7514091..5a5e504 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -611,7 +611,7 @@
 	index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
 						tid_agg_rx->buf_size;
 	if (!tid_agg_rx->reorder_buf[index] &&
-	    tid_agg_rx->stored_mpdu_num > 1) {
+	    tid_agg_rx->stored_mpdu_num) {
 		/*
 		 * No buffers ready to be released, but check whether any
 		 * frames in the reorder buffer have timed out.
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6f77f12..bfed851 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -52,6 +52,7 @@
  * @WLAN_STA_SP: Station is in a service period, so don't try to
  *	reply to other uAPSD trigger frames or PS-Poll.
  * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
+ * @WLAN_STA_RATE_CONTROL: rate control was initialized for this station.
  */
 enum ieee80211_sta_info_flags {
 	WLAN_STA_AUTH,
@@ -71,6 +72,7 @@
 	WLAN_STA_UAPSD,
 	WLAN_STA_SP,
 	WLAN_STA_4ADDR_EVENT,
+	WLAN_STA_RATE_CONTROL,
 };
 
 enum ieee80211_sta_state {
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 611c335..2555816 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -232,6 +232,7 @@
 	__be16 dport = 0;		/* destination port to forward */
 	unsigned int flags;
 	struct ip_vs_conn_param param;
+	const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
 	union nf_inet_addr snet;	/* source network of the client,
 					   after masking */
 
@@ -267,7 +268,6 @@
 	{
 		int protocol = iph.protocol;
 		const union nf_inet_addr *vaddr = &iph.daddr;
-		const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
 		__be16 vport = 0;
 
 		if (dst_port == svc->port) {
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 76613f5..ed86a3b 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -404,19 +404,49 @@
 			   &net->ct.hash[repl_hash]);
 }
 
-void nf_conntrack_hash_insert(struct nf_conn *ct)
+int
+nf_conntrack_hash_check_insert(struct nf_conn *ct)
 {
 	struct net *net = nf_ct_net(ct);
 	unsigned int hash, repl_hash;
+	struct nf_conntrack_tuple_hash *h;
+	struct hlist_nulls_node *n;
 	u16 zone;
 
 	zone = nf_ct_zone(ct);
-	hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
-	repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+	hash = hash_conntrack(net, zone,
+			      &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+	repl_hash = hash_conntrack(net, zone,
+				   &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
 
+	spin_lock_bh(&nf_conntrack_lock);
+
+	/* See if there's one in the list already, including reverse */
+	hlist_nulls_for_each_entry(h, n, &net->ct.hash[hash], hnnode)
+		if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+				      &h->tuple) &&
+		    zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
+			goto out;
+	hlist_nulls_for_each_entry(h, n, &net->ct.hash[repl_hash], hnnode)
+		if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
+				      &h->tuple) &&
+		    zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
+			goto out;
+
+	add_timer(&ct->timeout);
+	nf_conntrack_get(&ct->ct_general);
 	__nf_conntrack_hash_insert(ct, hash, repl_hash);
+	NF_CT_STAT_INC(net, insert);
+	spin_unlock_bh(&nf_conntrack_lock);
+
+	return 0;
+
+out:
+	NF_CT_STAT_INC(net, insert_failed);
+	spin_unlock_bh(&nf_conntrack_lock);
+	return -EEXIST;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
+EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert);
 
 /* Confirm a connection given skb; places it in hash table */
 int
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 9307b03..30c9d4c 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1367,15 +1367,12 @@
 						    nf_ct_protonum(ct));
 		if (helper == NULL) {
 			rcu_read_unlock();
-			spin_unlock_bh(&nf_conntrack_lock);
 #ifdef CONFIG_MODULES
 			if (request_module("nfct-helper-%s", helpname) < 0) {
-				spin_lock_bh(&nf_conntrack_lock);
 				err = -EOPNOTSUPP;
 				goto err1;
 			}
 
-			spin_lock_bh(&nf_conntrack_lock);
 			rcu_read_lock();
 			helper = __nf_conntrack_helper_find(helpname,
 							    nf_ct_l3num(ct),
@@ -1468,8 +1465,10 @@
 	if (tstamp)
 		tstamp->start = ktime_to_ns(ktime_get_real());
 
-	add_timer(&ct->timeout);
-	nf_conntrack_hash_insert(ct);
+	err = nf_conntrack_hash_check_insert(ct);
+	if (err < 0)
+		goto err2;
+
 	rcu_read_unlock();
 
 	return ct;
@@ -1490,6 +1489,7 @@
 	struct nf_conntrack_tuple otuple, rtuple;
 	struct nf_conntrack_tuple_hash *h = NULL;
 	struct nfgenmsg *nfmsg = nlmsg_data(nlh);
+	struct nf_conn *ct;
 	u_int8_t u3 = nfmsg->nfgen_family;
 	u16 zone;
 	int err;
@@ -1510,27 +1510,22 @@
 			return err;
 	}
 
-	spin_lock_bh(&nf_conntrack_lock);
 	if (cda[CTA_TUPLE_ORIG])
-		h = __nf_conntrack_find(net, zone, &otuple);
+		h = nf_conntrack_find_get(net, zone, &otuple);
 	else if (cda[CTA_TUPLE_REPLY])
-		h = __nf_conntrack_find(net, zone, &rtuple);
+		h = nf_conntrack_find_get(net, zone, &rtuple);
 
 	if (h == NULL) {
 		err = -ENOENT;
 		if (nlh->nlmsg_flags & NLM_F_CREATE) {
-			struct nf_conn *ct;
 			enum ip_conntrack_events events;
 
 			ct = ctnetlink_create_conntrack(net, zone, cda, &otuple,
 							&rtuple, u3);
-			if (IS_ERR(ct)) {
-				err = PTR_ERR(ct);
-				goto out_unlock;
-			}
+			if (IS_ERR(ct))
+				return PTR_ERR(ct);
+
 			err = 0;
-			nf_conntrack_get(&ct->ct_general);
-			spin_unlock_bh(&nf_conntrack_lock);
 			if (test_bit(IPS_EXPECTED_BIT, &ct->status))
 				events = IPCT_RELATED;
 			else
@@ -1545,23 +1540,19 @@
 						      ct, NETLINK_CB(skb).pid,
 						      nlmsg_report(nlh));
 			nf_ct_put(ct);
-		} else
-			spin_unlock_bh(&nf_conntrack_lock);
+		}
 
 		return err;
 	}
 	/* implicit 'else' */
 
-	/* We manipulate the conntrack inside the global conntrack table lock,
-	 * so there's no need to increase the refcount */
 	err = -EEXIST;
+	ct = nf_ct_tuplehash_to_ctrack(h);
 	if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
-		struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
-
+		spin_lock_bh(&nf_conntrack_lock);
 		err = ctnetlink_change_conntrack(ct, cda);
+		spin_unlock_bh(&nf_conntrack_lock);
 		if (err == 0) {
-			nf_conntrack_get(&ct->ct_general);
-			spin_unlock_bh(&nf_conntrack_lock);
 			nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
 						      (1 << IPCT_ASSURED) |
 						      (1 << IPCT_HELPER) |
@@ -1570,15 +1561,10 @@
 						      (1 << IPCT_MARK),
 						      ct, NETLINK_CB(skb).pid,
 						      nlmsg_report(nlh));
-			nf_ct_put(ct);
-		} else
-			spin_unlock_bh(&nf_conntrack_lock);
-
-		return err;
+		}
 	}
 
-out_unlock:
-	spin_unlock_bh(&nf_conntrack_lock);
+	nf_ct_put(ct);
 	return err;
 }
 
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index b3a7db6..ce60cf0 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -203,6 +203,27 @@
 	return status;
 }
 
+#ifdef CONFIG_BRIDGE_NETFILTER
+/* When called from bridge netfilter, skb->data must point to MAC header
+ * before calling skb_gso_segment(). Else, original MAC header is lost
+ * and segmented skbs will be sent to wrong destination.
+ */
+static void nf_bridge_adjust_skb_data(struct sk_buff *skb)
+{
+	if (skb->nf_bridge)
+		__skb_push(skb, skb->network_header - skb->mac_header);
+}
+
+static void nf_bridge_adjust_segmented_data(struct sk_buff *skb)
+{
+	if (skb->nf_bridge)
+		__skb_pull(skb, skb->network_header - skb->mac_header);
+}
+#else
+#define nf_bridge_adjust_skb_data(s) do {} while (0)
+#define nf_bridge_adjust_segmented_data(s) do {} while (0)
+#endif
+
 int nf_queue(struct sk_buff *skb,
 	     struct list_head *elem,
 	     u_int8_t pf, unsigned int hook,
@@ -212,7 +233,7 @@
 	     unsigned int queuenum)
 {
 	struct sk_buff *segs;
-	int err;
+	int err = -EINVAL;
 	unsigned int queued;
 
 	if (!skb_is_gso(skb))
@@ -228,23 +249,25 @@
 		break;
 	}
 
+	nf_bridge_adjust_skb_data(skb);
 	segs = skb_gso_segment(skb, 0);
 	/* Does not use PTR_ERR to limit the number of error codes that can be
 	 * returned by nf_queue.  For instance, callers rely on -ECANCELED to mean
 	 * 'ignore this hook'.
 	 */
 	if (IS_ERR(segs))
-		return -EINVAL;
-
+		goto out_err;
 	queued = 0;
 	err = 0;
 	do {
 		struct sk_buff *nskb = segs->next;
 
 		segs->next = NULL;
-		if (err == 0)
+		if (err == 0) {
+			nf_bridge_adjust_segmented_data(segs);
 			err = __nf_queue(segs, elem, pf, hook, indev,
 					   outdev, okfn, queuenum);
+		}
 		if (err == 0)
 			queued++;
 		else
@@ -252,11 +275,12 @@
 		segs = nskb;
 	} while (segs);
 
-	/* also free orig skb if only some segments were queued */
-	if (unlikely(err && queued))
-		err = 0;
-	if (err == 0)
+	if (queued) {
 		kfree_skb(skb);
+		return 0;
+	}
+  out_err:
+	nf_bridge_adjust_segmented_data(skb);
 	return err;
 }
 
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index 3aae66f..4d50579 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -152,9 +152,10 @@
 	fl6.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
 			   (iph->flow_lbl[1] << 8) | iph->flow_lbl[2];
 	dst = ip6_route_output(net, NULL, &fl6);
-	if (dst == NULL)
+	if (dst->error) {
+		dst_release(dst);
 		return false;
-
+	}
 	skb_dst_drop(skb);
 	skb_dst_set(skb, dst);
 	skb->dev      = dst->dev;
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 4cba13e..ae3a035 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -232,7 +232,7 @@
 	if (toklen <= (n_parts + 1) * 4)
 		return -EINVAL;
 
-	princ->name_parts = kcalloc(sizeof(char *), n_parts, GFP_KERNEL);
+	princ->name_parts = kcalloc(n_parts, sizeof(char *), GFP_KERNEL);
 	if (!princ->name_parts)
 		return -ENOMEM;
 
@@ -355,7 +355,7 @@
 
 		_debug("n_elem %d", n_elem);
 
-		td = kcalloc(sizeof(struct krb5_tagged_data), n_elem,
+		td = kcalloc(n_elem, sizeof(struct krb5_tagged_data),
 			     GFP_KERNEL);
 		if (!td)
 			return -ENOMEM;
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index e465064..7e267d7 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -148,8 +148,7 @@
 
 static inline struct choke_skb_cb *choke_skb_cb(const struct sk_buff *skb)
 {
-	BUILD_BUG_ON(sizeof(skb->cb) <
-		sizeof(struct qdisc_skb_cb) + sizeof(struct choke_skb_cb));
+	qdisc_cb_private_validate(skb, sizeof(struct choke_skb_cb));
 	return (struct choke_skb_cb *)qdisc_skb_cb(skb)->data;
 }
 
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 2776012..5da548f 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -130,8 +130,7 @@
 
 static inline struct netem_skb_cb *netem_skb_cb(struct sk_buff *skb)
 {
-	BUILD_BUG_ON(sizeof(skb->cb) <
-		sizeof(struct qdisc_skb_cb) + sizeof(struct netem_skb_cb));
+	qdisc_cb_private_validate(skb, sizeof(struct netem_skb_cb));
 	return (struct netem_skb_cb *)qdisc_skb_cb(skb)->data;
 }
 
@@ -502,9 +501,8 @@
 
 		/* if more time remaining? */
 		if (cb->time_to_send <= psched_get_time()) {
-			skb = qdisc_dequeue_tail(sch);
-			if (unlikely(!skb))
-				goto qdisc_dequeue;
+			__skb_unlink(skb, &sch->q);
+			sch->qstats.backlog -= qdisc_pkt_len(skb);
 
 #ifdef CONFIG_NET_CLS_ACT
 			/*
@@ -540,7 +538,6 @@
 		qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
 	}
 
-qdisc_dequeue:
 	if (q->qdisc) {
 		skb = q->qdisc->ops->dequeue(q->qdisc);
 		if (skb)
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 96e42ca..d7eea99 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -94,8 +94,7 @@
 
 static inline struct sfb_skb_cb *sfb_skb_cb(const struct sk_buff *skb)
 {
-	BUILD_BUG_ON(sizeof(skb->cb) <
-		sizeof(struct qdisc_skb_cb) + sizeof(struct sfb_skb_cb));
+	qdisc_cb_private_validate(skb, sizeof(struct sfb_skb_cb));
 	return (struct sfb_skb_cb *)qdisc_skb_cb(skb)->data;
 }
 
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 67494ae..60d4718 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -166,9 +166,8 @@
 
 static inline struct sfq_skb_cb *sfq_skb_cb(const struct sk_buff *skb)
 {
-       BUILD_BUG_ON(sizeof(skb->cb) <
-               sizeof(struct qdisc_skb_cb) + sizeof(struct sfq_skb_cb));
-       return (struct sfq_skb_cb *)qdisc_skb_cb(skb)->data;
+	qdisc_cb_private_validate(skb, sizeof(struct sfq_skb_cb));
+	return (struct sfq_skb_cb *)qdisc_skb_cb(skb)->data;
 }
 
 static unsigned int sfq_hash(const struct sfq_sched_data *q,
diff --git a/scripts/coccicheck b/scripts/coccicheck
index 3c27764..823e972 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -9,15 +9,10 @@
 #    FLAGS="-ignore_unknown_options -very_quiet"
 #    OPTIONS=$*
 
-    if [ "$KBUILD_EXTMOD" = "" ] ; then
-        # Workaround for Coccinelle < 0.2.3
-        FLAGS="-I $srctree/include -very_quiet"
-        shift $(( $# - 1 ))
-        OPTIONS=$1
-    else
-	echo M= is not currently supported when C=1 or C=2
-	exit 1
-    fi
+# Workaround for Coccinelle < 0.2.3
+	FLAGS="-I $srctree/include -very_quiet"
+	shift $(( $# - 1 ))
+	OPTIONS=$1
 else
     ONLINE=0
     FLAGS="-very_quiet"
diff --git a/scripts/depmod.sh b/scripts/depmod.sh
index a272356..2ae4817 100755
--- a/scripts/depmod.sh
+++ b/scripts/depmod.sh
@@ -9,12 +9,6 @@
 DEPMOD=$1
 KERNELRELEASE=$2
 
-if ! "$DEPMOD" -V 2>/dev/null | grep -q module-init-tools; then
-	echo "Warning: you may need to install module-init-tools" >&2
-	echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt" >&2
-	sleep 1
-fi
-
 if ! test -r System.map -a -x "$DEPMOD"; then
 	exit 0
 fi
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index e8c9695..b89efe6 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -46,11 +46,37 @@
 	void *function;
 };
 
+#define ___cat(a,b) a ## b
+#define __cat(a,b) ___cat(a,b)
+
+/* we need some special handling for this host tool running eventually on
+ * Darwin. The Mach-O section handling is a bit different than ELF section
+ * handling. The differnces in detail are:
+ *  a) we have segments which have sections
+ *  b) we need a API call to get the respective section symbols */
+#if defined(__MACH__)
+#include <mach-o/getsect.h>
+
+#define INIT_SECTION(name)  do {					\
+		unsigned long name ## _len;				\
+		char *__cat(pstart_,name) = getsectdata("__TEXT",	\
+			#name, &__cat(name,_len));			\
+		char *__cat(pstop_,name) = __cat(pstart_,name) +	\
+			__cat(name, _len);				\
+		__cat(__start_,name) = (void *)__cat(pstart_,name);	\
+		__cat(__stop_,name) = (void *)__cat(pstop_,name);	\
+	} while (0)
+#define SECTION(name)   __attribute__((section("__TEXT, " #name)))
+
+struct devtable **__start___devtable, **__stop___devtable;
+#else
+#define INIT_SECTION(name) /* no-op for ELF */
+#define SECTION(name)   __attribute__((section(#name)))
+
 /* We construct a table of pointers in an ELF section (pointers generally
  * go unpadded by gcc).  ld creates boundary syms for us. */
 extern struct devtable *__start___devtable[], *__stop___devtable[];
-#define ___cat(a,b) a ## b
-#define __cat(a,b) ___cat(a,b)
+#endif /* __MACH__ */
 
 #if __GNUC__ == 3 && __GNUC_MINOR__ < 3
 # define __used			__attribute__((__unused__))
@@ -65,8 +91,8 @@
 						(type *)NULL,		\
 						(char *)NULL)),		\
 		sizeof(type), (function) };				\
-	static struct devtable *__attribute__((section("__devtable"))) \
-		__used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
+	static struct devtable *SECTION(__devtable) __used \
+		__cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
 
 #define ADD(str, sep, cond, field)                              \
 do {                                                            \
@@ -932,7 +958,7 @@
 		(id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
 	return 1;
 }
-ADD_TO_DEVTABLE("isa", struct isapnp_device_id, do_isapnp_entry);
+ADD_TO_DEVTABLE("isapnp", struct isapnp_device_id, do_isapnp_entry);
 
 /*
  * Append a match expression for a single masked hex digit.
@@ -1080,6 +1106,7 @@
 		do_pnp_card_entries(symval, sym->st_size, mod);
 	else {
 		struct devtable **p;
+		INIT_SECTION(__devtable);
 
 		for (p = __start___devtable; p < __stop___devtable; p++) {
 			if (sym_is(name, namelen, (*p)->device_id)) {
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 2bd594e..9adb667 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1494,6 +1494,13 @@
 	return 0;
 }
 
+#ifndef R_ARM_CALL
+#define R_ARM_CALL	28
+#endif
+#ifndef R_ARM_JUMP24
+#define R_ARM_JUMP24	29
+#endif
+
 static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 {
 	unsigned int r_typ = ELF_R_TYPE(r->r_info);
@@ -1505,6 +1512,8 @@
 		              (elf->symtab_start + ELF_R_SYM(r->r_info));
 		break;
 	case R_ARM_PC24:
+	case R_ARM_CALL:
+	case R_ARM_JUMP24:
 		/* From ARM ABI: ((S + A) | T) - P */
 		r->r_addend = (int)(long)(elf->hdr +
 		              sechdr->sh_offset +
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index f6cbc3d..3c6c0b1 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -238,14 +238,14 @@
 fi
 
 # Build header package
-(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$)
-(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> /tmp/files$$)
-(cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$)
+(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > "$objtree/debian/hdrsrcfiles")
+(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> "$objtree/debian/hdrsrcfiles")
+(cd $objtree; find .config Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles")
 destdir=$kernel_headers_dir/usr/src/linux-headers-$version
 mkdir -p "$destdir"
-(cd $srctree; tar -c -f - -T /tmp/files$$) | (cd $destdir; tar -xf -)
-(cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -)
-rm -f /tmp/files$$ /tmp/objfiles$$
+(cd $srctree; tar -c -f - -T "$objtree/debian/hdrsrcfiles") | (cd $destdir; tar -xf -)
+(cd $objtree; tar -c -f - -T "$objtree/debian/hdrobjfiles") | (cd $destdir; tar -xf -)
+rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
 arch=$(dpkg --print-architecture)
 
 cat <<EOF >> debian/control
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 95ffa6a..496f14c 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2684,10 +2684,9 @@
 		err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
 		if (err < 0)
 			goto out_err;
+		opl3->private_data = chip;
 	}
 
-	opl3->private_data = chip;
-
 	sprintf(card->longname, "%s at 0x%lx, irq %i",
 		card->shortname, chip->ctrl_io, chip->irq);
 
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c2c65f6..6843073 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1759,7 +1759,11 @@
 	parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
 	parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
 	parm |= index << AC_AMP_SET_INDEX_SHIFT;
-	parm |= val;
+	if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) &&
+	    (info->amp_caps & AC_AMPCAP_MIN_MUTE))
+		; /* set the zero value as a fake mute */
+	else
+		parm |= val;
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
 	info->vol[ch] = val;
 }
@@ -2026,7 +2030,7 @@
 	val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
 	val1 += ofs;
 	val1 = ((int)val1) * ((int)val2);
-	if (min_mute)
+	if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
 		val2 |= TLV_DB_SCALE_MUTE;
 	if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
 		return -EFAULT;
@@ -5114,7 +5118,7 @@
 	const char *pfx = "", *sfx = "";
 
 	/* handle as a speaker if it's a fixed line-out */
-	if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT)
+	if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
 		name = "Speaker";
 	/* check the location */
 	switch (attr) {
@@ -5173,7 +5177,7 @@
 
 	switch (get_defcfg_device(def_conf)) {
 	case AC_JACK_LINE_OUT:
-		return fill_audio_out_name(codec, nid, cfg, "Line-Out",
+		return fill_audio_out_name(codec, nid, cfg, "Line Out",
 					   label, maxlen, indexp);
 	case AC_JACK_SPEAKER:
 		return fill_audio_out_name(codec, nid, cfg, "Speaker",
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e9f71dc..f0f1943 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -298,6 +298,9 @@
 #define AC_AMPCAP_MUTE			(1<<31)    /* mute capable */
 #define AC_AMPCAP_MUTE_SHIFT		31
 
+/* driver-specific amp-caps: using bits 24-30 */
+#define AC_AMPCAP_MIN_MUTE		(1 << 30) /* min-volume = mute */
+
 /* Connection list */
 #define AC_CLIST_LENGTH			(0x7f<<0)
 #define AC_CLIST_LONG			(1<<7)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index bc5a993..c83ccdb 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -609,7 +609,7 @@
 		"Front Speaker", "Surround Speaker", "Bass Speaker"
 	};
 	static const char * const line_outs[] = {
-		"Front Line-Out", "Surround Line-Out", "Bass Line-Out"
+		"Front Line Out", "Surround Line Out", "Bass Line Out"
 	};
 
 	fix_volume_caps(codec, dac);
@@ -635,7 +635,7 @@
 		if (num_ctls > 1)
 			name = line_outs[idx];
 		else
-			name = "Line-Out";
+			name = "Line Out";
 		break;
 	}
 
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a7a5733..d29d6d3 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3482,7 +3482,7 @@
 		"Disabled", "Enabled"
 	};
 	static const char * const texts3[] = {
-		"Disabled", "Speaker Only", "Line-Out+Speaker"
+		"Disabled", "Speaker Only", "Line Out+Speaker"
 	};
 	const char * const *texts;
 
@@ -4079,7 +4079,8 @@
 		err = snd_hda_ctl_add(codec, nid, kctl);
 		if (err < 0)
 			return err;
-		if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE))
+		if (!(query_amp_caps(codec, nid, hda_dir) &
+		      (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)))
 			break;
 	}
 	return 0;
@@ -4379,6 +4380,22 @@
 	{}
 };
 
+/* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
+ * can be created (bko#42825)
+ */
+static void add_cx5051_fake_mutes(struct hda_codec *codec)
+{
+	static hda_nid_t out_nids[] = {
+		0x10, 0x11, 0
+	};
+	hda_nid_t *p;
+
+	for (p = out_nids; *p; p++)
+		snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
+					  AC_AMPCAP_MIN_MUTE |
+					  query_amp_caps(codec, *p, HDA_OUTPUT));
+}
+
 static int patch_conexant_auto(struct hda_codec *codec)
 {
 	struct conexant_spec *spec;
@@ -4397,6 +4414,9 @@
 	case 0x14f15045:
 		spec->single_adc_amp = 1;
 		break;
+	case 0x14f15051:
+		add_cx5051_fake_mutes(codec);
+		break;
 	}
 
 	apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9350f3c..f286bb8 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -80,6 +80,8 @@
 	ALC_AUTOMUTE_MIXER,	/* mute/unmute mixer widget AMP */
 };
 
+#define MAX_VOL_NIDS	0x40
+
 struct alc_spec {
 	/* codec parameterization */
 	const struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
@@ -118,8 +120,8 @@
 	const hda_nid_t *capsrc_nids;
 	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
 	hda_nid_t mixer_nid;		/* analog-mixer NID */
-	DECLARE_BITMAP(vol_ctls, 0x20 << 1);
-	DECLARE_BITMAP(sw_ctls, 0x20 << 1);
+	DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
+	DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
 
 	/* capture setup for dynamic dual-adc switch */
 	hda_nid_t cur_adc;
@@ -800,7 +802,7 @@
 		"Disabled", "Enabled"
 	};
 	static const char * const texts3[] = {
-		"Disabled", "Speaker Only", "Line-Out+Speaker"
+		"Disabled", "Speaker Only", "Line Out+Speaker"
 	};
 	const char * const *texts;
 
@@ -1854,7 +1856,7 @@
 	"Headphone Playback Volume",
 	"Speaker Playback Volume",
 	"Mono Playback Volume",
-	"Line-Out Playback Volume",
+	"Line Out Playback Volume",
 	"CLFE Playback Volume",
 	"Bass Speaker Playback Volume",
 	"PCM Playback Volume",
@@ -1871,7 +1873,7 @@
 	"Speaker Playback Switch",
 	"Mono Playback Switch",
 	"IEC958 Playback Switch",
-	"Line-Out Playback Switch",
+	"Line Out Playback Switch",
 	"CLFE Playback Switch",
 	"Bass Speaker Playback Switch",
 	"PCM Playback Switch",
@@ -3149,7 +3151,10 @@
 static inline unsigned int get_ctl_pos(unsigned int data)
 {
 	hda_nid_t nid = get_amp_nid_(data);
-	unsigned int dir = get_amp_direction_(data);
+	unsigned int dir;
+	if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
+		return 0;
+	dir = get_amp_direction_(data);
 	return (nid << 1) | dir;
 }
 
@@ -3792,7 +3797,7 @@
 	else
 		nums = spec->num_adc_nids;
 	for (c = 0; c < nums; c++)
-		alc_mux_select(codec, 0, spec->cur_mux[c], true);
+		alc_mux_select(codec, c, spec->cur_mux[c], true);
 }
 
 /* add mic boosts if needed */
@@ -4374,6 +4379,7 @@
 	ALC882_FIXUP_ACER_ASPIRE_8930G,
 	ALC882_FIXUP_ASPIRE_8930G_VERBS,
 	ALC885_FIXUP_MACPRO_GPIO,
+	ALC889_FIXUP_DAC_ROUTE,
 };
 
 static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4427,6 +4433,31 @@
 	alc882_gpio_mute(codec, 1, 0);
 }
 
+/* Fix the connection of some pins for ALC889:
+ * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
+ * work correctly (bko#42740)
+ */
+static void alc889_fixup_dac_route(struct hda_codec *codec,
+				   const struct alc_fixup *fix, int action)
+{
+	if (action == ALC_FIXUP_ACT_PRE_PROBE) {
+		/* fake the connections during parsing the tree */
+		hda_nid_t conn1[2] = { 0x0c, 0x0d };
+		hda_nid_t conn2[2] = { 0x0e, 0x0f };
+		snd_hda_override_conn_list(codec, 0x14, 2, conn1);
+		snd_hda_override_conn_list(codec, 0x15, 2, conn1);
+		snd_hda_override_conn_list(codec, 0x18, 2, conn2);
+		snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
+	} else if (action == ALC_FIXUP_ACT_PROBE) {
+		/* restore the connections */
+		hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
+		snd_hda_override_conn_list(codec, 0x14, 5, conn);
+		snd_hda_override_conn_list(codec, 0x15, 5, conn);
+		snd_hda_override_conn_list(codec, 0x18, 5, conn);
+		snd_hda_override_conn_list(codec, 0x1a, 5, conn);
+	}
+}
+
 static const struct alc_fixup alc882_fixups[] = {
 	[ALC882_FIXUP_ABIT_AW9D_MAX] = {
 		.type = ALC_FIXUP_PINS,
@@ -4574,6 +4605,10 @@
 		.type = ALC_FIXUP_FUNC,
 		.v.func = alc885_fixup_macpro_gpio,
 	},
+	[ALC889_FIXUP_DAC_ROUTE] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc889_fixup_dac_route,
+	},
 };
 
 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4598,6 +4633,7 @@
 	SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
 		      ALC882_FIXUP_ACER_ASPIRE_4930G),
 	SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
+	SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
 	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
 	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
 	SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 948f0be..9dbb573 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4629,7 +4629,7 @@
 		unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
 		if (no_hp_sensing(spec, i))
 			continue;
-		if (presence)
+		if (1 /*presence*/)
 			stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
 #if 0 /* FIXME */
 /* Resetting the pinctl like below may lead to (a sort of) regressions
@@ -5078,9 +5078,9 @@
 				spec->gpio_dir, spec->gpio_data);
 	} else {
 		notmtd_lvl = spec->gpio_led_polarity ?
-				AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD;
+				AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
 		muted_lvl = spec->gpio_led_polarity ?
-				AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
+				AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_50;
 		spec->vref_led = muted ? muted_lvl : notmtd_lvl;
 		stac_vrefout_set(codec,	spec->vref_mute_led_nid,
 				 spec->vref_led);
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 284e311..dff9a00 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -666,6 +666,9 @@
 	/* init input-src */
 	for (i = 0; i < spec->num_adc_nids; i++) {
 		int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
+		/* secondary ADCs must have the unique MUX */
+		if (i > 0 && !spec->mux_nids[i])
+			break;
 		if (spec->mux_nids[adc_idx]) {
 			int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
 			snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 9f3b01b..e0a4263 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2102,6 +2102,12 @@
 	},
 	{
 		.subvendor = 0x161f,
+		.subdevice = 0x202f,
+		.name = "Gateway M520",
+		.type = AC97_TUNE_INV_EAPD
+	},
+	{
+		.subvendor = 0x161f,
 		.subdevice = 0x203a,
 		.name = "Gateway 4525GZ",		/* AD1981B */
 		.type = AC97_TUNE_INV_EAPD
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 5ef70b5..278c0a0 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -146,13 +146,10 @@
 
 	SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
 			 0, 0xFF, 1, out_tlv),
-
-	SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0),
 };
 
-static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
-	SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0),
-};
+static const struct snd_kcontrol_new ak4642_headphone_control =
+	SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0);
 
 static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
 	SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
@@ -165,13 +162,12 @@
 	SND_SOC_DAPM_OUTPUT("HPOUTR"),
 	SND_SOC_DAPM_OUTPUT("LINEOUT"),
 
-	SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0,
-			   &ak4642_hpout_mixer_controls[0],
-			   ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+	SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0),
+	SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0,
+			    &ak4642_headphone_control),
 
-	SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0,
-			   &ak4642_hpout_mixer_controls[0],
-			   ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+	SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0),
 
 	SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0,
 			   &ak4642_lout_mixer_controls[0],
@@ -184,12 +180,17 @@
 static const struct snd_soc_dapm_route ak4642_intercon[] = {
 
 	/* Outputs */
-	{"HPOUTL", NULL, "HPOUTL Mixer"},
-	{"HPOUTR", NULL, "HPOUTR Mixer"},
+	{"HPOUTL", NULL, "HPL Out"},
+	{"HPOUTR", NULL, "HPR Out"},
 	{"LINEOUT", NULL, "LINEOUT Mixer"},
 
-	{"HPOUTL Mixer", "DACH", "DAC"},
-	{"HPOUTR Mixer", "DACH", "DAC"},
+	{"HPL Out", NULL, "Headphone Enable"},
+	{"HPR Out", NULL, "Headphone Enable"},
+
+	{"Headphone Enable", "Switch", "DACH"},
+
+	{"DACH", NULL, "DAC"},
+
 	{"LINEOUT Mixer", "DACL", "DAC"},
 };
 
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 29c4b02..0ac228b 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2564,7 +2564,7 @@
 	return 0;
 }
 
-static const char *st_text[] = { "None", "Right", "Left" };
+static const char *st_text[] = { "None", "Left", "Right" };
 
 static const struct soc_enum str_enum =
 	SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text);
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 01d1f74..b6adbed 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -112,7 +112,7 @@
 		break;
 	case SND_SOC_DAIFMT_DSP_A:
 		/* data on rising edge of bclk, frame high 1clk before data */
-		strcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
+		strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
 		break;
 	}
 
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index db6c89a..ea4a82d0 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1152,12 +1152,8 @@
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
 	struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream));
-	int samples_pos = io->buff_sample_pos - 1;
 
-	if (samples_pos < 0)
-		samples_pos = 0;
-
-	return fsi_sample2frame(fsi, samples_pos);
+	return fsi_sample2frame(fsi, io->buff_sample_pos);
 }
 
 static struct snd_pcm_ops fsi_pcm_ops = {
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1f55ded..1315663 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3068,9 +3068,13 @@
 	 * standby.
 	 */
 	if (powerdown) {
-		snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE);
+		if (dapm->bias_level == SND_SOC_BIAS_ON)
+			snd_soc_dapm_set_bias_level(dapm,
+						    SND_SOC_BIAS_PREPARE);
 		dapm_seq_run(dapm, &down_list, 0, false);
-		snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY);
+		if (dapm->bias_level == SND_SOC_BIAS_PREPARE)
+			snd_soc_dapm_set_bias_level(dapm,
+						    SND_SOC_BIAS_STANDBY);
 	}
 }
 
@@ -3083,7 +3087,9 @@
 
 	list_for_each_entry(codec, &card->codec_dev_list, list) {
 		soc_dapm_shutdown_codec(&codec->dapm);
-		snd_soc_dapm_set_bias_level(&codec->dapm, SND_SOC_BIAS_OFF);
+		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+			snd_soc_dapm_set_bias_level(&codec->dapm,
+						    SND_SOC_BIAS_OFF);
 	}
 }
 
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 2cf87f5..fde9a7a 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -311,8 +311,10 @@
 
 	spin_lock(&dev->spinlock);
 
-	if (dev->input_panic || dev->output_panic)
+	if (dev->input_panic || dev->output_panic) {
 		ptr = SNDRV_PCM_POS_XRUN;
+		goto unlock;
+	}
 
 	if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		ptr = bytes_to_frames(sub->runtime,
@@ -321,6 +323,7 @@
 		ptr = bytes_to_frames(sub->runtime,
 					dev->audio_in_buf_pos[index]);
 
+unlock:
 	spin_unlock(&dev->spinlock);
 	return ptr;
 }
diff --git a/sound/usb/card.h b/sound/usb/card.h
index a39edcc..da5fa1a 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -1,6 +1,7 @@
 #ifndef __USBAUDIO_CARD_H
 #define __USBAUDIO_CARD_H
 
+#define MAX_NR_RATES	1024
 #define MAX_PACKS	20
 #define MAX_PACKS_HS	(MAX_PACKS * 8)	/* in high speed mode */
 #define MAX_URBS	8
diff --git a/sound/usb/format.c b/sound/usb/format.c
index e09aba1..ddfef57 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -209,8 +209,6 @@
 	return 0;
 }
 
-#define MAX_UAC2_NR_RATES 1024
-
 /*
  * Helper function to walk the array of sample rate triplets reported by
  * the device. The problem is that we need to parse whole array first to
@@ -255,7 +253,7 @@
 			fp->rates |= snd_pcm_rate_to_rate_bit(rate);
 
 			nr_rates++;
-			if (nr_rates >= MAX_UAC2_NR_RATES) {
+			if (nr_rates >= MAX_NR_RATES) {
 				snd_printk(KERN_ERR "invalid uac2 rates\n");
 				break;
 			}
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index a3ddac0..2781726 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -132,10 +132,14 @@
 	unsigned *rate_table = NULL;
 
 	fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
-	if (! fp) {
+	if (!fp) {
 		snd_printk(KERN_ERR "cannot memdup\n");
 		return -ENOMEM;
 	}
+	if (fp->nr_rates > MAX_NR_RATES) {
+		kfree(fp);
+		return -EINVAL;
+	}
 	if (fp->nr_rates > 0) {
 		rate_table = kmemdup(fp->rate_table,
 				     sizeof(int) * fp->nr_rates, GFP_KERNEL);
diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm.S b/tools/perf/bench/mem-memcpy-x86-64-asm.S
index a57b66e..185a96d 100644
--- a/tools/perf/bench/mem-memcpy-x86-64-asm.S
+++ b/tools/perf/bench/mem-memcpy-x86-64-asm.S
@@ -1,2 +1,8 @@
 
 #include "../../../arch/x86/lib/memcpy_64.S"
+/*
+ * We need to provide note.GNU-stack section, saying that we want
+ * NOT executable stack. Otherwise the final linking will assume that
+ * the ELF stack should not be restricted at all and set it RWX.
+ */
+.section .note.GNU-stack,"",@progbits
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 73ddaf0..2a6f33c 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -74,6 +74,7 @@
 			if (size >= len)
 				size = len - 1;
 			memcpy(comm, name, size);
+			comm[size] = '\0';
 
 		} else if (memcmp(bf, "Tgid:", 5) == 0) {
 			char *tgids = bf + 5;
@@ -554,7 +555,7 @@
 
 	is_kernel_mmap = memcmp(event->mmap.filename,
 				kmmap_prefix,
-				strlen(kmmap_prefix)) == 0;
+				strlen(kmmap_prefix) - 1) == 0;
 	if (event->mmap.filename[0] == '/' ||
 	    (!is_kernel_mmap && event->mmap.filename[0] == '[')) {
 
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 3f16e08..ea32a06 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -349,6 +349,10 @@
 	hlist_for_each_entry(sid, pos, head, node)
 		if (sid->id == id)
 			return sid->evsel;
+
+	if (!perf_evlist__sample_id_all(evlist))
+		return list_entry(evlist->entries.next, struct perf_evsel, node);
+
 	return NULL;
 }
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 667f3b7..7132ee8 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -463,6 +463,7 @@
 	memset(data, 0, sizeof(*data));
 	data->cpu = data->pid = data->tid = -1;
 	data->stream_id = data->id = data->time = -1ULL;
+	data->period = 1;
 
 	if (event->header.type != PERF_RECORD_SAMPLE) {
 		if (!sample_id_all)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 29cb654..e33554a 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1867,6 +1867,12 @@
 			   tev->point.symbol);
 		ret = -ENOENT;
 		goto error;
+	} else if (tev->point.offset > sym->end - sym->start) {
+		pr_warning("Offset specified is greater than size of %s\n",
+			   tev->point.symbol);
+		ret = -ENOENT;
+		goto error;
+
 	}
 
 	return 1;
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 5d73262..74bd2e6 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -672,7 +672,7 @@
 static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
 				  bool retprobe, struct probe_trace_point *tp)
 {
-	Dwarf_Addr eaddr;
+	Dwarf_Addr eaddr, highaddr;
 	const char *name;
 
 	/* Copy the name of probe point */
@@ -683,6 +683,16 @@
 				   dwarf_diename(sp_die));
 			return -ENOENT;
 		}
+		if (dwarf_highpc(sp_die, &highaddr) != 0) {
+			pr_warning("Failed to get end address of %s\n",
+				   dwarf_diename(sp_die));
+			return -ENOENT;
+		}
+		if (paddr > highaddr) {
+			pr_warning("Offset specified is greater than size of %s\n",
+				   dwarf_diename(sp_die));
+			return -EINVAL;
+		}
 		tp->symbol = strdup(name);
 		if (tp->symbol == NULL)
 			return -ENOMEM;
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 62a134d..9507c4b 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -3244,9 +3244,11 @@
 	$in_bisect = 1;
 
 	my $failed = 0;
-	build "oldconfig";
-	start_monitor_and_boot or $failed = 1;
-	end_monitor;
+	build "oldconfig" or $failed = 1;
+	if (!$failed) {
+		start_monitor_and_boot or $failed = 1;
+		end_monitor;
+	}
 
 	$in_bisect = 0;