Merge "msm: vidc: Fix IOMMU pagefault for long clips"
diff --git a/Documentation/devicetree/bindings/media/video/msm-wfd.txt b/Documentation/devicetree/bindings/media/video/msm-wfd.txt
new file mode 100644
index 0000000..0cd8c9d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/video/msm-wfd.txt
@@ -0,0 +1,11 @@
+* Qualcomm MSM Wifi Display (WFD)
+
+Required properties:
+- compatible :
+	- "qcom,msm-wfd"
+
+Example:
+
+	qcom,wfd {
+		compatible = "qcom,msm-wfd";
+	};
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index 1bf888b..188ee03 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -278,6 +278,7 @@
 CONFIG_FB_MSM_MDP40=y
 CONFIG_FB_MSM_OVERLAY=y
 CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
+CONFIG_FB_MSM_NO_MDP_PIPE_CTRL=y
 CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM=y
 CONFIG_FB_MSM_HDMI_ADV7520_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/arch/arm/mach-msm/acpuclock-7627.c b/arch/arm/mach-msm/acpuclock-7627.c
index 1a2ae48..6788cbe 100644
--- a/arch/arm/mach-msm/acpuclock-7627.c
+++ b/arch/arm/mach-msm/acpuclock-7627.c
@@ -32,13 +32,13 @@
 
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
+#include <mach/clk-provider.h>
 #include <mach/socinfo.h>
 #include <asm/mach-types.h>
 #include <asm/cpu.h>
 
 #include "smd_private.h"
 #include "acpuclock.h"
-#include "clock.h"
 
 #define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100)
 #define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
diff --git a/arch/arm/mach-msm/acpuclock-7x30.c b/arch/arm/mach-msm/acpuclock-7x30.c
index b49613e..5b947e6 100644
--- a/arch/arm/mach-msm/acpuclock-7x30.c
+++ b/arch/arm/mach-msm/acpuclock-7x30.c
@@ -32,7 +32,6 @@
 #include <asm/mach-types.h>
 
 #include "smd_private.h"
-#include "clock.h"
 #include "acpuclock.h"
 #include "spm.h"
 
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 8755f08..07acac6 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -78,6 +78,7 @@
 
 #include "msm_watchdog.h"
 #include "board-8064.h"
+#include "clock.h"
 #include "spm.h"
 #include <mach/mpm.h>
 #include "rpm_resources.h"
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index c845a3a..9545c7a 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -40,6 +40,7 @@
 #include <mach/msm_memtypes.h>
 #include <mach/socinfo.h>
 #include <mach/board.h>
+#include <mach/clk-provider.h>
 #include "clock.h"
 
 static struct clk_lookup msm_clocks_dummy[] = {
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index aad0f3d..ab35948 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -96,6 +96,7 @@
 #include <mach/cpuidle.h>
 #include "rpm_resources.h"
 #include <mach/mpm.h>
+#include "clock.h"
 #include "smd_private.h"
 #include "pm-boot.h"
 #include "msm_watchdog.h"
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 06efc03..8ed9666 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -98,6 +98,7 @@
 #include <mach/cpuidle.h>
 #include "rpm_resources.h"
 #include <mach/mpm.h>
+#include "clock.h"
 #include "smd_private.h"
 #include "pm-boot.h"
 #include "msm_watchdog.h"
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 4523cf7..ca95b62 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -50,6 +50,7 @@
 #include "devices.h"
 #include "board-9615.h"
 #include "pm.h"
+#include "clock.h"
 #include "pm-boot.h"
 #include <mach/gpiomux.h>
 #include "ci13xxx_udc.h"
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index e7ef1a9..99b9f16 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -29,6 +29,7 @@
 #include <mach/socinfo.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
+#include <mach/clk-provider.h>
 #include "clock.h"
 
 #define L2CC_AUX_CTRL	((0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) | \
diff --git a/arch/arm/mach-msm/board-fsm9xxx.c b/arch/arm/mach-msm/board-fsm9xxx.c
index 24d54e4..b4f6968 100644
--- a/arch/arm/mach-msm/board-fsm9xxx.c
+++ b/arch/arm/mach-msm/board-fsm9xxx.c
@@ -38,6 +38,7 @@
 #include <mach/socinfo.h>
 #include "devices.h"
 #include "timer.h"
+#include "clock.h"
 #include "pm.h"
 #include "spm.h"
 #include <linux/regulator/consumer.h>
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index b3ce01c..205db58 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -82,6 +82,7 @@
 #include "pm-boot.h"
 #include "spm.h"
 #include "acpuclock.h"
+#include "clock.h"
 #include <mach/dal_axi.h>
 #include <mach/msm_serial_hs.h>
 #include <mach/qdsp5v2/mi2s.h>
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 281d055..a889d39 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -100,6 +100,7 @@
 #include "peripheral-loader.h"
 #include <linux/platform_data/qcom_crypto_device.h>
 #include "rpm_resources.h"
+#include "clock.h"
 #include "pm-boot.h"
 #include "board-storage-common-a.h"
 
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 4df4266..146c8a8 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -55,6 +55,7 @@
 #include "timer.h"
 #include "msm-keypad-devices.h"
 #include "acpuclock.h"
+#include "clock.h"
 #include "pm.h"
 #include "irq.h"
 #include "pm-boot.h"
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index 8cce34b..e42fe65 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -24,7 +24,6 @@
 #include <linux/string.h>
 
 #include <mach/msm_iomap.h>
-#include <mach/clk.h>
 #include <mach/proc_comm.h>
 
 #include "clock.h"
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index f6b1332..9ff039f0 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -24,10 +24,10 @@
 #include <asm/mach-types.h>
 
 #include <mach/msm_iomap.h>
-#include <mach/clk.h>
 #include <mach/rpm-regulator.h>
 #include <mach/socinfo.h>
 
+#include "clock.h"
 #include "clock-local.h"
 #include "clock-rpm.h"
 #include "clock-voter.h"
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 62e8f0f..ca0dd20 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -20,7 +20,6 @@
 #include <linux/clk.h>
 #include <linux/iopoll.h>
 
-#include <mach/clk.h>
 #include <mach/rpm-regulator-smd.h>
 #include <mach/socinfo.h>
 #include <mach/rpm-smd.h>
@@ -30,6 +29,7 @@
 #include "clock-rpm.h"
 #include "clock-voter.h"
 #include "clock-mdss-8974.h"
+#include "clock.h"
 
 enum {
 	GCC_BASE,
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 24c06c9..6ae66fe 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -23,11 +23,11 @@
 #include <linux/clkdev.h>
 
 #include <mach/msm_iomap.h>
-#include <mach/clk.h>
 #include <mach/scm-io.h>
 #include <mach/rpm.h>
 #include <mach/rpm-regulator.h>
 
+#include "clock.h"
 #include "clock-local.h"
 #include "clock-rpm.h"
 #include "clock-voter.h"
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 15eaa4b..fee8445 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -24,10 +24,10 @@
 #include <asm/mach-types.h>
 
 #include <mach/msm_iomap.h>
-#include <mach/clk.h>
 #include <mach/rpm-9615.h>
 #include <mach/rpm-regulator.h>
 
+#include "clock.h"
 #include "clock-local.h"
 #include "clock-voter.h"
 #include "clock-rpm.h"
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index c996ff4..e942173 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/list.h>
 #include <linux/clkdev.h>
+#include <mach/clk-provider.h>
 
 #include "clock.h"
 
@@ -145,74 +146,39 @@
 DEFINE_SIMPLE_ATTRIBUTE(clock_hwcg_fops, clock_debug_hwcg_get,
 			NULL, "%llu\n");
 
-static struct dentry *debugfs_base;
-static u32 debug_suspend;
-static struct clk_lookup *msm_clocks;
-static size_t num_msm_clocks;
-
-int __init clock_debug_init(struct clock_init_data *data)
+static int fmax_rates_show(struct seq_file *m, void *unused)
 {
-	debugfs_base = debugfs_create_dir("clk", NULL);
-	if (!debugfs_base)
-		return -ENOMEM;
-	if (!debugfs_create_u32("debug_suspend", S_IRUGO | S_IWUSR,
-				debugfs_base, &debug_suspend)) {
-		debugfs_remove_recursive(debugfs_base);
-		return -ENOMEM;
-	}
-	msm_clocks = data->table;
-	num_msm_clocks = data->size;
+	struct clk *clock = m->private;
+	int level = 0;
 
-	measure = clk_get_sys("debug", "measure");
-	if (IS_ERR(measure))
-		measure = NULL;
+	int vdd_level = find_vdd_level(clock, clock->rate);
+	if (vdd_level < 0) {
+		seq_printf(m, "could not find_vdd_level for %s, %ld\n",
+			   clock->dbg_name, clock->rate);
+		return 0;
+	}
+	for (level = 0; level < ARRAY_SIZE(clock->fmax); level++) {
+		if (vdd_level == level)
+			seq_printf(m, "[%lu] ", clock->fmax[level]);
+		else
+			seq_printf(m, "%lu ", clock->fmax[level]);
+	}
+	seq_printf(m, "\n");
 
 	return 0;
 }
 
-
-static int clock_debug_print_clock(struct clk *c)
+static int fmax_rates_open(struct inode *inode, struct file *file)
 {
-	char *start = "";
-
-	if (!c || !c->prepare_count)
-		return 0;
-
-	pr_info("\t");
-	do {
-		if (c->vdd_class)
-			pr_cont("%s%s:%u:%u [%ld, %lu]", start, c->dbg_name,
-				c->prepare_count, c->count, c->rate,
-				c->vdd_class->cur_level);
-		else
-			pr_cont("%s%s:%u:%u [%ld]", start, c->dbg_name,
-				c->prepare_count, c->count, c->rate);
-		start = " -> ";
-	} while ((c = clk_get_parent(c)));
-
-	pr_cont("\n");
-
-	return 1;
+	return single_open(file, fmax_rates_show, inode->i_private);
 }
 
-void clock_debug_print_enabled(void)
-{
-	unsigned i;
-	int cnt = 0;
-
-	if (likely(!debug_suspend))
-		return;
-
-	pr_info("Enabled clocks:\n");
-	for (i = 0; i < num_msm_clocks; i++)
-		cnt += clock_debug_print_clock(msm_clocks[i].clk);
-
-	if (cnt)
-		pr_info("Enabled clock count: %d\n", cnt);
-	else
-		pr_info("No clocks enabled.\n");
-
-}
+static const struct file_operations fmax_rates_fops = {
+	.open		= fmax_rates_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
 
 static int list_rates_show(struct seq_file *m, void *unused)
 {
@@ -252,41 +218,16 @@
 	.release	= seq_release,
 };
 
-static int fmax_rates_show(struct seq_file *m, void *unused)
-{
-	struct clk *clock = m->private;
-	int level = 0;
+static struct dentry *debugfs_base;
+static u32 debug_suspend;
 
-	int vdd_level = find_vdd_level(clock, clock->rate);
-	if (vdd_level < 0) {
-		seq_printf(m, "could not find_vdd_level for %s, %ld\n",
-			clock->dbg_name, clock->rate);
-		return 0;
-	}
-	for (level = 0; level < ARRAY_SIZE(clock->fmax); level++) {
-		if (vdd_level == level)
-			seq_printf(m, "[%lu] ", clock->fmax[level]);
-		else
-			seq_printf(m, "%lu ", clock->fmax[level]);
-	}
-	seq_printf(m, "\n");
-
-	return 0;
-}
-
-static int fmax_rates_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, fmax_rates_show, inode->i_private);
-}
-
-static const struct file_operations fmax_rates_fops = {
-	.open		= fmax_rates_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= seq_release,
+struct clk_table {
+	struct list_head node;
+	struct clk_lookup *clocks;
+	size_t num_clocks;
 };
 
-int __init clock_debug_add(struct clk *clock)
+static int clock_debug_add(struct clk *clock)
 {
 	char temp[50], *ptr;
 	struct dentry *clk_dir;
@@ -333,9 +274,118 @@
 				S_IRUGO, clk_dir, clock, &fmax_rates_fops))
 			goto error;
 
-
 	return 0;
 error:
 	debugfs_remove_recursive(clk_dir);
 	return -ENOMEM;
 }
+static LIST_HEAD(clk_list);
+static DEFINE_SPINLOCK(clk_list_lock);
+
+/**
+ * clock_debug_register() - Add additional clocks to clock debugfs hierarchy
+ * @table: Table of clocks to create debugfs nodes for
+ * @size: Size of @table
+ *
+ * Use this function to register additional clocks in debugfs. The clock debugfs
+ * hierarchy must have already been initialized with clock_debug_init() prior to
+ * calling this function. Unlike clock_debug_init(), this may be called multiple
+ * times with different clock lists and can be used after the kernel has
+ * finished booting.
+ */
+int clock_debug_register(struct clk_lookup *table, size_t size)
+{
+	struct clk_table *clk_table;
+	unsigned long flags;
+	int i;
+
+	clk_table = kmalloc(sizeof(*clk_table), GFP_KERNEL);
+	if (!clk_table)
+		return -ENOMEM;
+
+	clk_table->clocks = table;
+	clk_table->num_clocks = size;
+
+	spin_lock_irqsave(&clk_list_lock, flags);
+	list_add_tail(&clk_table->node, &clk_list);
+	spin_unlock_irqrestore(&clk_list_lock, flags);
+
+	for (i = 0; i < size; i++)
+		clock_debug_add(table[i].clk);
+
+	return 0;
+}
+
+/**
+ * clock_debug_init() - Initialize clock debugfs
+ */
+int __init clock_debug_init(void)
+{
+	debugfs_base = debugfs_create_dir("clk", NULL);
+	if (!debugfs_base)
+		return -ENOMEM;
+	if (!debugfs_create_u32("debug_suspend", S_IRUGO | S_IWUSR,
+				debugfs_base, &debug_suspend)) {
+		debugfs_remove_recursive(debugfs_base);
+		return -ENOMEM;
+	}
+
+	measure = clk_get_sys("debug", "measure");
+	if (IS_ERR(measure))
+		measure = NULL;
+
+	return 0;
+}
+
+static int clock_debug_print_clock(struct clk *c)
+{
+	char *start = "";
+
+	if (!c || !c->prepare_count)
+		return 0;
+
+	pr_info("\t");
+	do {
+		if (c->vdd_class)
+			pr_cont("%s%s:%u:%u [%ld, %lu]", start, c->dbg_name,
+				c->prepare_count, c->count, c->rate,
+				c->vdd_class->cur_level);
+		else
+			pr_cont("%s%s:%u:%u [%ld]", start, c->dbg_name,
+				c->prepare_count, c->count, c->rate);
+		start = " -> ";
+	} while ((c = clk_get_parent(c)));
+
+	pr_cont("\n");
+
+	return 1;
+}
+
+/**
+ * clock_debug_print_enabled() - Print names of enabled clocks for suspend debug
+ *
+ * Print the names of enabled clocks and their parents if debug_suspend is set
+ */
+void clock_debug_print_enabled(void)
+{
+	struct clk_table *table;
+	unsigned long flags;
+	int i, cnt = 0;
+
+	if (likely(!debug_suspend))
+		return;
+
+	pr_info("Enabled clocks:\n");
+	spin_lock_irqsave(&clk_list_lock, flags);
+	list_for_each_entry(table, &clk_list, node) {
+		for (i = 0; i < table->num_clocks; i++)
+			cnt += clock_debug_print_clock(table->clocks[i].clk);
+	}
+	spin_unlock_irqrestore(&clk_list_lock, flags);
+
+	if (cnt)
+		pr_info("Enabled clock count: %d\n", cnt);
+	else
+		pr_info("No clocks enabled.\n");
+
+}
diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c
index 54c9de8..fda7a92 100644
--- a/arch/arm/mach-msm/clock-dummy.c
+++ b/arch/arm/mach-msm/clock-dummy.c
@@ -10,7 +10,7 @@
  * GNU General Public License for more details.
  */
 
-#include "clock.h"
+#include <mach/clk-provider.h>
 
 static int dummy_clk_reset(struct clk *clk, enum clk_reset_action action)
 {
diff --git a/arch/arm/mach-msm/clock-fsm9xxx.c b/arch/arm/mach-msm/clock-fsm9xxx.c
index c188ba6..2900d45 100644
--- a/arch/arm/mach-msm/clock-fsm9xxx.c
+++ b/arch/arm/mach-msm/clock-fsm9xxx.c
@@ -12,9 +12,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/clk.h>
-
-#include <mach/clk.h>
-
+#include <mach/clk-provider.h>
 #include "clock.h"
 
 /*
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index b952f2f..ca031ad 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -24,10 +24,10 @@
 #include <linux/clk.h>
 
 #include <mach/msm_iomap.h>
+#include <mach/clk-provider.h>
 #include <mach/clk.h>
 #include <mach/scm-io.h>
 
-#include "clock.h"
 #include "clock-local.h"
 
 #ifdef CONFIG_MSM_SECURE_IO
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 81085ef..1873343 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -15,7 +15,7 @@
 #define __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_H
 
 #include <linux/spinlock.h>
-#include "clock.h"
+#include <mach/clk-provider.h>
 
 #define MN_MODE_DUAL_EDGE 0x2
 
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index 2beb990..b9c3036 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -24,8 +24,8 @@
 #include <linux/clk.h>
 
 #include <mach/clk.h>
+#include <mach/clk-provider.h>
 
-#include "clock.h"
 #include "clock-local2.h"
 
 /*
diff --git a/arch/arm/mach-msm/clock-local2.h b/arch/arm/mach-msm/clock-local2.h
index 46e9e0c..101dc2d 100644
--- a/arch/arm/mach-msm/clock-local2.h
+++ b/arch/arm/mach-msm/clock-local2.h
@@ -15,7 +15,8 @@
 #define __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_2_H
 
 #include <linux/spinlock.h>
-#include "clock.h"
+#include <mach/clk-provider.h>
+#include <mach/clk.h>
 
 /*
  * Generic frequency-definition structs and macros
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 14e1185..1603c93 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -20,8 +20,8 @@
 
 #include <asm/processor.h>
 #include <mach/msm_iomap.h>
+#include <mach/clk-provider.h>
 
-#include "clock.h"
 #include "clock-mdss-8974.h"
 
 #define REG_R(addr)		readl_relaxed(addr)
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
index 428423a..801b40a 100644
--- a/arch/arm/mach-msm/clock-pcom.c
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 
 #include <mach/clk.h>
+#include <mach/clk-provider.h>
 #include <mach/socinfo.h>
 #include <mach/proc_comm.h>
 
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
index 723c53c..82a90ab 100644
--- a/arch/arm/mach-msm/clock-pcom.h
+++ b/arch/arm/mach-msm/clock-pcom.h
@@ -13,6 +13,8 @@
 #ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
 #define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
 
+#include <mach/clk-provider.h>
+
 /* clock IDs used by the modem processor */
 
 #define P_ACPU_CLK	0   /* Applications processor clock */
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index 30f595b..5c7c304 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -15,6 +15,8 @@
 #ifndef __ARCH_ARM_MACH_MSM_CLOCK_PLL_H
 #define __ARCH_ARM_MACH_MSM_CLOCK_PLL_H
 
+#include <mach/clk-provider.h>
+
 /**
  * enum - For PLL IDs
  */
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index 149a0511..e06eb4b 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -12,10 +12,9 @@
  */
 
 #include <linux/err.h>
-#include <mach/clk.h>
+#include <mach/clk-provider.h>
 
 #include "rpm_resources.h"
-#include "clock.h"
 #include "clock-rpm.h"
 
 #define __clk_rpmrs_set_rate(r, value, ctx, noirq) \
diff --git a/arch/arm/mach-msm/clock-rpm.h b/arch/arm/mach-msm/clock-rpm.h
index 7952a33..2f0b729 100644
--- a/arch/arm/mach-msm/clock-rpm.h
+++ b/arch/arm/mach-msm/clock-rpm.h
@@ -16,6 +16,7 @@
 
 #include <mach/rpm.h>
 #include <mach/rpm-smd.h>
+#include <mach/clk-provider.h>
 
 #define RPM_SMD_KEY_RATE	0x007A484B
 #define RPM_SMD_KEY_ENABLE	0x62616E45
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index 3e1cbb9..fa170bf4 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -14,8 +14,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
-
-#include "clock.h"
+#include <mach/clk-provider.h>
 #include "clock-voter.h"
 
 static DEFINE_MUTEX(voter_clk_lock);
diff --git a/arch/arm/mach-msm/clock-voter.h b/arch/arm/mach-msm/clock-voter.h
index 407aac6..82c071b 100644
--- a/arch/arm/mach-msm/clock-voter.h
+++ b/arch/arm/mach-msm/clock-voter.h
@@ -14,6 +14,8 @@
 #ifndef __ARCH_ARM_MACH_MSM_CLOCK_VOTER_H
 #define __ARCH_ARM_MACH_MSM_CLOCK_VOTER_H
 
+#include <mach/clk-provider.h>
+
 struct clk_ops;
 extern struct clk_ops clk_ops_voter;
 
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 27f2405..1ea18f4 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -23,7 +23,7 @@
 #include <linux/clkdev.h>
 #include <linux/list.h>
 #include <trace/events/power.h>
-
+#include <mach/clk-provider.h>
 #include "clock.h"
 
 struct handoff_clk {
@@ -412,7 +412,32 @@
 }
 EXPORT_SYMBOL(clk_set_flags);
 
-static struct clock_init_data __initdata *clk_init_data;
+static struct clock_init_data *clk_init_data;
+
+/**
+ * msm_clock_register() - Register additional clock tables
+ * @table: Table of clocks
+ * @size: Size of @table
+ *
+ * Upon return, clock APIs may be used to control clocks registered using this
+ * function. This API may only be used after msm_clock_init() has completed.
+ * Unlike msm_clock_init(), this function may be called multiple times with
+ * different clock lists and used after the kernel has finished booting.
+ */
+int msm_clock_register(struct clk_lookup *table, size_t size)
+{
+	if (!clk_init_data)
+		return -ENODEV;
+
+	if (!table)
+		return -EINVAL;
+
+	clkdev_add_table(table, size);
+	clock_debug_register(table, size);
+
+	return 0;
+}
+EXPORT_SYMBOL(msm_clock_register);
 
 static enum handoff __init __handoff_clk(struct clk *clk)
 {
@@ -466,13 +491,23 @@
 	return ret;
 }
 
-void __init msm_clock_init(struct clock_init_data *data)
+/**
+ * msm_clock_init() - Register and initialize a clock driver
+ * @data: Driver-specific clock initialization data
+ *
+ * Upon return from this call, clock APIs may be used to control
+ * clocks registered with this API.
+ */
+int __init msm_clock_init(struct clock_init_data *data)
 {
 	unsigned n;
 	struct clk_lookup *clock_tbl;
 	size_t num_clocks;
 	struct clk *clk;
 
+	if (!data)
+		return -EINVAL;
+
 	clk_init_data = data;
 	if (clk_init_data->pre_init)
 		clk_init_data->pre_init();
@@ -499,16 +534,17 @@
 
 	if (clk_init_data->post_init)
 		clk_init_data->post_init();
+
+	clock_debug_init();
+	clock_debug_register(clock_tbl, num_clocks);
+
+	return 0;
 }
 
 static int __init clock_late_init(void)
 {
 	struct handoff_clk *h, *h_temp;
-	int n, ret = 0;
-
-	clock_debug_init(clk_init_data);
-	for (n = 0; n < clk_init_data->size; n++)
-		clock_debug_add(clk_init_data->table[n].clk);
+	int ret = 0;
 
 	pr_info("%s: Removing enables held for handed-off clocks\n", __func__);
 	list_for_each_entry_safe(h, h_temp, &handoff_list, list) {
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 45d2f71..48f897b 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -1,7 +1,5 @@
-/* arch/arm/mach-msm/clock.h
- *
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -17,127 +15,7 @@
 #ifndef __ARCH_ARM_MACH_MSM_CLOCK_H
 #define __ARCH_ARM_MACH_MSM_CLOCK_H
 
-#include <linux/types.h>
-#include <linux/list.h>
 #include <linux/clkdev.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-
-#include <mach/clk.h>
-
-#define CLKFLAG_INVERT			0x00000001
-#define CLKFLAG_NOINVERT		0x00000002
-#define CLKFLAG_NONEST			0x00000004
-#define CLKFLAG_NORESET			0x00000008
-#define CLKFLAG_RETAIN			0x00000040
-#define CLKFLAG_NORETAIN		0x00000080
-#define CLKFLAG_SKIP_HANDOFF		0x00000100
-#define CLKFLAG_MIN			0x00000400
-#define CLKFLAG_MAX			0x00000800
-
-/*
- * Bit manipulation macros
- */
-#define BM(msb, lsb)	(((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb)
-#define BVAL(msb, lsb, val)	(((val) << lsb) & BM(msb, lsb))
-
-/*
- * Halt/Status Checking Mode Macros
- */
-#define HALT		0	/* Bit pol: 1 = halted */
-#define NOCHECK		1	/* No bit to check, do nothing */
-#define HALT_VOTED	2	/* Bit pol: 1 = halted; delay on disable */
-#define ENABLE		3	/* Bit pol: 1 = running */
-#define ENABLE_VOTED	4	/* Bit pol: 1 = running; delay on disable */
-#define DELAY		5	/* No bit to check, just delay */
-
-#define MAX_VDD_LEVELS			4
-
-/**
- * struct clk_vdd_class - Voltage scaling class
- * @class_name: name of the class
- * @set_vdd: function to call when applying a new voltage setting
- * @level_votes: array of votes for each level
- * @cur_level: the currently set voltage level
- * @lock: lock to protect this struct
- */
-struct clk_vdd_class {
-	const char *class_name;
-	int (*set_vdd)(struct clk_vdd_class *v_class, int level);
-	int level_votes[MAX_VDD_LEVELS];
-	unsigned long cur_level;
-	spinlock_t lock;
-};
-
-#define DEFINE_VDD_CLASS(_name, _set_vdd) \
-	struct clk_vdd_class _name = { \
-		.class_name = #_name, \
-		.set_vdd = _set_vdd, \
-		.cur_level = ARRAY_SIZE(_name.level_votes), \
-		.lock = __SPIN_LOCK_UNLOCKED(lock) \
-	}
-
-enum handoff {
-	HANDOFF_ENABLED_CLK,
-	HANDOFF_DISABLED_CLK,
-	HANDOFF_UNKNOWN_RATE,
-};
-
-struct clk_ops {
-	int (*prepare)(struct clk *clk);
-	int (*enable)(struct clk *clk);
-	void (*disable)(struct clk *clk);
-	void (*unprepare)(struct clk *clk);
-	void (*enable_hwcg)(struct clk *clk);
-	void (*disable_hwcg)(struct clk *clk);
-	int (*in_hwcg_mode)(struct clk *clk);
-	enum handoff (*handoff)(struct clk *clk);
-	int (*reset)(struct clk *clk, enum clk_reset_action action);
-	int (*set_rate)(struct clk *clk, unsigned long rate);
-	int (*set_max_rate)(struct clk *clk, unsigned long rate);
-	int (*set_flags)(struct clk *clk, unsigned flags);
-	unsigned long (*get_rate)(struct clk *clk);
-	int (*list_rate)(struct clk *clk, unsigned n);
-	int (*is_enabled)(struct clk *clk);
-	long (*round_rate)(struct clk *clk, unsigned long rate);
-	int (*set_parent)(struct clk *clk, struct clk *parent);
-	struct clk *(*get_parent)(struct clk *clk);
-	bool (*is_local)(struct clk *clk);
-};
-
-/**
- * struct clk
- * @prepare_count: prepare refcount
- * @prepare_lock: protects clk_prepare()/clk_unprepare() path and @prepare_count
- * @count: enable refcount
- * @lock: protects clk_enable()/clk_disable() path and @count
- * @depends: non-direct parent of clock to enable when this clock is enabled
- * @vdd_class: voltage scaling requirement class
- * @fmax: maximum frequency in Hz supported at each voltage level
- */
-struct clk {
-	uint32_t flags;
-	struct clk_ops *ops;
-	const char *dbg_name;
-	struct clk *depends;
-	struct clk_vdd_class *vdd_class;
-	unsigned long fmax[MAX_VDD_LEVELS];
-	unsigned long rate;
-
-	struct list_head children;
-	struct list_head siblings;
-
-	unsigned count;
-	spinlock_t lock;
-	unsigned prepare_count;
-	struct mutex prepare_lock;
-};
-
-#define CLK_INIT(name) \
-	.lock = __SPIN_LOCK_UNLOCKED((name).lock), \
-	.prepare_lock = __MUTEX_INITIALIZER((name).prepare_lock), \
-	.children = LIST_HEAD_INIT((name).children), \
-	.siblings = LIST_HEAD_INIT((name).siblings)
 
 /**
  * struct clock_init_data - SoC specific clock initialization data
@@ -171,30 +49,20 @@
 extern struct clock_init_data msm8974_clock_init_data;
 extern struct clock_init_data msm8974_rumi_clock_init_data;
 
-void msm_clock_init(struct clock_init_data *data);
-int vote_vdd_level(struct clk_vdd_class *vdd_class, int level);
-int unvote_vdd_level(struct clk_vdd_class *vdd_class, int level);
+int msm_clock_init(struct clock_init_data *data);
 int find_vdd_level(struct clk *clk, unsigned long rate);
 
 #ifdef CONFIG_DEBUG_FS
-int clock_debug_init(struct clock_init_data *data);
-int clock_debug_add(struct clk *clock);
+int clock_debug_init(void);
+int clock_debug_register(struct clk_lookup *t, size_t s);
 void clock_debug_print_enabled(void);
 #else
-static inline int clock_debug_init(struct clock_init_data *data) { return 0; }
-static inline int clock_debug_add(struct clk *clock) { return 0; }
+static inline int clock_debug_init(void) { return 0; }
+static inline int clock_debug_register(struct clk_lookup *t, size_t s)
+{
+	return 0;
+}
 static inline void clock_debug_print_enabled(void) { return; }
 #endif
 
-extern struct clk dummy_clk;
-
-#define CLK_DUMMY(clk_name, clk_id, clk_dev, flags) { \
-	.con_id = clk_name, \
-	.dev_id = clk_dev, \
-	.clk = &dummy_clk, \
-	}
-
-#define CLK_LOOKUP(con, c, dev) { .con_id = con, .clk = &c, .dev_id = dev }
-
 #endif
-
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 0f106f5..e66881b 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -26,6 +26,7 @@
 #include <mach/msm_sps.h>
 #include <mach/dma.h>
 #include <mach/msm_dsps.h>
+#include <mach/clk-provider.h>
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
 #include <mach/msm_tsif.h>
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index b6926a2..64b901f 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -35,6 +35,7 @@
 #include <mach/msm_dcvs.h>
 #include <mach/msm_rtb.h>
 #include <mach/msm_cache_dump.h>
+#include <mach/clk-provider.h>
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
 #include <mach/msm_tsif.h>
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index c877ba9..343ea76 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -30,6 +30,7 @@
 #include <asm/cacheflush.h>
 #include <mach/rpc_hsusb.h>
 #include <mach/socinfo.h>
+#include <mach/clk-provider.h>
 
 #include "devices.h"
 #include "devices-msm7x2xa.h"
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 84735aa..a7b26c1 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -24,7 +24,7 @@
 #include <mach/msm_iomap.h>
 #include <mach/msm_bus.h>
 #include <mach/scm-io.h>
-#include "clock.h"
+#include <mach/clk.h>
 #include "footswitch.h"
 
 #ifdef CONFIG_MSM_SECURE_IO
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
new file mode 100644
index 0000000..0da0b33
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
+ *
+ * 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 __MACH_CLK_PROVIDER_H
+#define __MACH_CLK_PROVIDER_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/clkdev.h>
+#include <linux/spinlock.h>
+#include <mach/clk.h>
+
+/*
+ * Bit manipulation macros
+ */
+#define BM(msb, lsb)	(((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb)
+#define BVAL(msb, lsb, val)	(((val) << lsb) & BM(msb, lsb))
+
+/*
+ * Halt/Status Checking Mode Macros
+ */
+#define HALT		0	/* Bit pol: 1 = halted */
+#define NOCHECK		1	/* No bit to check, do nothing */
+#define HALT_VOTED	2	/* Bit pol: 1 = halted; delay on disable */
+#define ENABLE		3	/* Bit pol: 1 = running */
+#define ENABLE_VOTED	4	/* Bit pol: 1 = running; delay on disable */
+#define DELAY		5	/* No bit to check, just delay */
+
+#define MAX_VDD_LEVELS			4
+
+/**
+ * struct clk_vdd_class - Voltage scaling class
+ * @class_name: name of the class
+ * @set_vdd: function to call when applying a new voltage setting
+ * @level_votes: array of votes for each level
+ * @cur_level: the currently set voltage level
+ * @lock: lock to protect this struct
+ */
+struct clk_vdd_class {
+	const char *class_name;
+	int (*set_vdd)(struct clk_vdd_class *v_class, int level);
+	int level_votes[MAX_VDD_LEVELS];
+	unsigned long cur_level;
+	spinlock_t lock;
+};
+
+#define DEFINE_VDD_CLASS(_name, _set_vdd) \
+	struct clk_vdd_class _name = { \
+		.class_name = #_name, \
+		.set_vdd = _set_vdd, \
+		.cur_level = ARRAY_SIZE(_name.level_votes), \
+		.lock = __SPIN_LOCK_UNLOCKED(lock) \
+	}
+
+enum handoff {
+	HANDOFF_ENABLED_CLK,
+	HANDOFF_DISABLED_CLK,
+	HANDOFF_UNKNOWN_RATE,
+};
+
+struct clk_ops {
+	int (*prepare)(struct clk *clk);
+	int (*enable)(struct clk *clk);
+	void (*disable)(struct clk *clk);
+	void (*unprepare)(struct clk *clk);
+	void (*enable_hwcg)(struct clk *clk);
+	void (*disable_hwcg)(struct clk *clk);
+	int (*in_hwcg_mode)(struct clk *clk);
+	enum handoff (*handoff)(struct clk *clk);
+	int (*reset)(struct clk *clk, enum clk_reset_action action);
+	int (*set_rate)(struct clk *clk, unsigned long rate);
+	int (*set_max_rate)(struct clk *clk, unsigned long rate);
+	int (*set_flags)(struct clk *clk, unsigned flags);
+	unsigned long (*get_rate)(struct clk *clk);
+	int (*list_rate)(struct clk *clk, unsigned n);
+	int (*is_enabled)(struct clk *clk);
+	long (*round_rate)(struct clk *clk, unsigned long rate);
+	int (*set_parent)(struct clk *clk, struct clk *parent);
+	struct clk *(*get_parent)(struct clk *clk);
+	bool (*is_local)(struct clk *clk);
+};
+
+/**
+ * struct clk
+ * @prepare_count: prepare refcount
+ * @prepare_lock: protects clk_prepare()/clk_unprepare() path and @prepare_count
+ * @count: enable refcount
+ * @lock: protects clk_enable()/clk_disable() path and @count
+ * @depends: non-direct parent of clock to enable when this clock is enabled
+ * @vdd_class: voltage scaling requirement class
+ * @fmax: maximum frequency in Hz supported at each voltage level
+ */
+struct clk {
+	uint32_t flags;
+	struct clk_ops *ops;
+	const char *dbg_name;
+	struct clk *depends;
+	struct clk_vdd_class *vdd_class;
+	unsigned long fmax[MAX_VDD_LEVELS];
+	unsigned long rate;
+
+	struct list_head children;
+	struct list_head siblings;
+
+	unsigned count;
+	spinlock_t lock;
+	unsigned prepare_count;
+	struct mutex prepare_lock;
+};
+
+#define CLK_INIT(name) \
+	.lock = __SPIN_LOCK_UNLOCKED((name).lock), \
+	.prepare_lock = __MUTEX_INITIALIZER((name).prepare_lock), \
+	.children = LIST_HEAD_INIT((name).children), \
+	.siblings = LIST_HEAD_INIT((name).siblings)
+
+int vote_vdd_level(struct clk_vdd_class *vdd_class, int level);
+int unvote_vdd_level(struct clk_vdd_class *vdd_class, int level);
+
+/* Register clocks with the MSM clock driver */
+int msm_clock_register(struct clk_lookup *table, size_t size);
+
+extern struct clk dummy_clk;
+
+#define CLK_DUMMY(clk_name, clk_id, clk_dev, flags) { \
+	.con_id = clk_name, \
+	.dev_id = clk_dev, \
+	.clk = &dummy_clk, \
+	}
+
+#define CLK_LOOKUP(con, c, dev) { .con_id = con, .clk = &c, .dev_id = dev }
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
index 8c0ebfa..d69b372 100644
--- a/arch/arm/mach-msm/include/mach/clk.h
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2012 Code Aurora Forum. 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 version 2 and
@@ -12,19 +12,24 @@
 #ifndef __MACH_CLK_H
 #define __MACH_CLK_H
 
-/* Magic rate value for use with PM QOS to request the board's maximum
- * supported AXI rate. PM QOS will only pass positive s32 rate values
- * through to the clock driver, so INT_MAX is used.
- */
-#define MSM_AXI_MAX_FREQ	LONG_MAX
+#define CLKFLAG_INVERT			0x00000001
+#define CLKFLAG_NOINVERT		0x00000002
+#define CLKFLAG_NONEST			0x00000004
+#define CLKFLAG_NORESET			0x00000008
+#define CLKFLAG_RETAIN			0x00000040
+#define CLKFLAG_NORETAIN		0x00000080
+#define CLKFLAG_SKIP_HANDOFF		0x00000100
+#define CLKFLAG_MIN			0x00000400
+#define CLKFLAG_MAX			0x00000800
+
+struct clk_lookup;
+struct clk;
 
 enum clk_reset_action {
 	CLK_RESET_DEASSERT	= 0,
 	CLK_RESET_ASSERT	= 1
 };
 
-struct clk;
-
 /* Rate is maximum clock rate in Hz */
 int clk_set_max_rate(struct clk *clk, unsigned long rate);
 
diff --git a/arch/arm/mach-msm/mdm.c b/arch/arm/mach-msm/mdm.c
index 4280fb4..02978cf 100644
--- a/arch/arm/mach-msm/mdm.c
+++ b/arch/arm/mach-msm/mdm.c
@@ -28,7 +28,6 @@
 #include <linux/debugfs.h>
 #include <linux/completion.h>
 #include <linux/workqueue.h>
-#include <linux/clk.h>
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
 #include <linux/mfd/pm8xxx/misc.h>
@@ -39,7 +38,6 @@
 #include <linux/msm_charm.h>
 #include "msm_watchdog.h"
 #include "devices.h"
-#include "clock.h"
 
 #define CHARM_MODEM_TIMEOUT	6000
 #define CHARM_HOLD_TIME		4000
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index 43c85bb..f548417 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -28,7 +28,6 @@
 #include <linux/debugfs.h>
 #include <linux/completion.h>
 #include <linux/workqueue.h>
-#include <linux/clk.h>
 #include <linux/mfd/pmic8058.h>
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
@@ -39,7 +38,6 @@
 #include <linux/msm_charm.h>
 #include "msm_watchdog.h"
 #include "devices.h"
-#include "clock.h"
 #include "mdm_private.h"
 #define MDM_PBLRDY_CNT		20
 
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index 2e4b756..84a79cd 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1057,8 +1057,14 @@
 	switch (cmd) {
 	case AUDIO_GET_STATS: {
 		struct msm_audio_stats stats;
+		uint64_t timestamp;
 		stats.byte_count = atomic_read(&audio->in_bytes);
 		stats.sample_count = atomic_read(&audio->in_samples);
+		timestamp = q6asm_get_session_time(audio->ac);
+		if (timestamp >= 0)
+			memcpy(&stats.unused[0], &timestamp, sizeof(timestamp));
+		else
+			pr_debug("Error while getting timestamp\n");
 		if (copy_to_user((void *)arg, &stats, sizeof(stats)))
 			rc = -EFAULT;
 		break;
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 70ad81c..7cbc7a8 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -226,7 +226,8 @@
 		adreno_drawctxt_switch(adreno_dev, NULL, 0);
 	}
 
-	adreno_idle(device);
+	if (device->state != KGSL_STATE_HUNG)
+		adreno_idle(device);
 
 	kgsl_sharedmem_free(&drawctxt->gpustate);
 	kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow);
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 482e569..3b678c4 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -267,6 +267,11 @@
 			core, ioctl, VIDIOC_MSM_SENSOR_CFG, argp);
 			break;
 
+	case MSM_CAM_IOCTL_OEM:
+	 rc = v4l2_subdev_call(p_mctl->sensor_sdev,
+		 core, ioctl, VIDIOC_MSM_SENSOR_CFG, argp);
+		 break;
+
 	case MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL: {
 			struct v4l2_control v4l2_ctrl;
 			CDBG("subdev call\n");
diff --git a/drivers/media/video/msm/sensors/imx091.h b/drivers/media/video/msm/sensors/imx091.h
index 3618b4c..411b90c 100644
--- a/drivers/media/video/msm/sensors/imx091.h
+++ b/drivers/media/video/msm/sensors/imx091.h
@@ -82,6 +82,7 @@
 	.sensor_power_up = msm_sensor_bayer_power_up,
 	.sensor_power_down = msm_sensor_bayer_power_down,
 	.sensor_get_csi_params = msm_sensor_bayer_get_csi_params,
+	.sensor_read_eeprom = msm_sensor_bayer_eeprom_read,
 };
 
 static struct msm_sensor_ctrl_t imx091_s_ctrl = {
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.c b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
index c867867..31313d2 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_bayer.c
+++ b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
@@ -332,7 +332,7 @@
 	}
 	case CFG_GET_EEPROM_DATA: {
 		if (copy_to_user((void *)cdata.cfg.eeprom_data.eeprom_data,
-			&s_ctrl->eeprom_data, s_ctrl->eeprom_data.length)) {
+			&s_ctrl->eeprom_data.data, s_ctrl->eeprom_data.length)){
 			pr_err("%s:%d failed\n", __func__, __LINE__);
 			rc = -EFAULT;
 		}
@@ -658,7 +658,7 @@
 	return rc;
 }
 
-static int32_t msm_sensor_bayer_eeprom_read(struct msm_sensor_ctrl_t *s_ctrl)
+int32_t msm_sensor_bayer_eeprom_read(struct msm_sensor_ctrl_t *s_ctrl)
 {
 	uint32_t reg_addr = 0;
 	uint8_t *data = s_ctrl->eeprom_data.data;
@@ -749,7 +749,10 @@
 	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
 	s_ctrl->sensor_v4l2_subdev.entity.revision =
 		s_ctrl->sensor_v4l2_subdev.devnode->num;
-	msm_sensor_bayer_eeprom_read(s_ctrl);
+	if (s_ctrl->func_tbl->sensor_read_eeprom != NULL)
+		s_ctrl->func_tbl->sensor_read_eeprom(s_ctrl);
+	else
+		msm_sensor_bayer_eeprom_read(s_ctrl);
 	goto power_down;
 probe_fail:
 	pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.h b/drivers/media/video/msm/sensors/msm_sensor_bayer.h
index d12244b..34e654b 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_bayer.h
+++ b/drivers/media/video/msm/sensors/msm_sensor_bayer.h
@@ -65,6 +65,8 @@
 int32_t msm_sensor_bayer_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
 		struct csi_lane_params_t *sensor_output_info);
 
+int32_t msm_sensor_bayer_eeprom_read(struct msm_sensor_ctrl_t *s_ctrl);
+
 #define VIDIOC_MSM_SENSOR_CFG \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, void __user *)
 
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.h b/drivers/media/video/msm/sensors/msm_sensor_common.h
index 79fe52e..1f34a0f 100644
--- a/drivers/media/video/msm/sensors/msm_sensor_common.h
+++ b/drivers/media/video/msm/sensors/msm_sensor_common.h
@@ -156,6 +156,7 @@
 	void (*sensor_adjust_frame_lines) (struct msm_sensor_ctrl_t *s_ctrl);
 	int32_t (*sensor_get_csi_params)(struct msm_sensor_ctrl_t *,
 		struct csi_lane_params_t *);
+	int32_t (*sensor_read_eeprom)(struct msm_sensor_ctrl_t *);
 };
 
 struct msm_sensor_csi_info {
diff --git a/drivers/media/video/msm_wfd/wfd-ioctl.c b/drivers/media/video/msm_wfd/wfd-ioctl.c
index 23af7e9..d3c5936 100644
--- a/drivers/media/video/msm_wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm_wfd/wfd-ioctl.c
@@ -1596,12 +1596,21 @@
 	kfree(wfd_dev);
 	return 0;
 }
+
+static const struct of_device_id msm_wfd_dt_match[] = {
+	{.compatible = "qcom,msm-wfd"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
+
 static struct platform_driver wfd_driver = {
 	.probe =  __wfd_probe,
 	.remove = __wfd_remove,
 	.driver = {
 		.name = "msm_wfd",
 		.owner = THIS_MODULE,
+		.of_match_table = msm_wfd_dt_match,
 	}
 };
 
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 7da4657..47b36ae 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -577,6 +577,8 @@
 	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:			return "MPEG4 Level";
 	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:			return "MPEG4 Profile";
 	case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:			return "Quarter Pixel Search Enable";
+	case V4L2_CID_QCOM_VIDEO_SYNC_FRAME_SEQ_HDR:
+		return "CodecConfig with sync frame";
 	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:		return "Maximum Bytes in a Slice";
 	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:		return "Number of MBs in a Slice";
 	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:		return "Slice Partitioning Method";
@@ -795,6 +797,11 @@
 		*type = V4L2_CTRL_TYPE_INTEGER64;
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE;
 		break;
+	case V4L2_CID_QCOM_VIDEO_SYNC_FRAME_SEQ_HDR:
+		*type = V4L2_CTRL_TYPE_BOOLEAN;
+		*min = 0;
+		*max = *step = 1;
+		break;
 	default:
 		*type = V4L2_CTRL_TYPE_INTEGER;
 		break;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 8d967cd..adbf217 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -94,7 +94,7 @@
  */
 #define	EHCI_TUNE_FLS		1	/* (medium) 512-frame schedule */
 
-#define EHCI_IAA_MSECS		10		/* arbitrary */
+#define EHCI_IAA_MSECS		100		/* arbitrary */
 #define EHCI_IO_JIFFIES		(HZ/10)		/* io watchdog > irq_thresh */
 #define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */
 #define EHCI_SHRINK_JIFFIES	(DIV_ROUND_UP(HZ, 200) + 1)
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 596c86f..931c1c8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1859,6 +1859,7 @@
 	struct vcd_buffer_requirement *input_buf_req;
 	struct vcd_buffer_requirement *output_buf_req;
 	u32  min_dpb, y_cb_cr_size;
+	u32  frame_height_actual = 0;
 
 	if (!decoder->codec.codec)
 		return false;
@@ -1882,6 +1883,7 @@
 		if ((decoder->buf_format.buffer_format ==
 			VCD_BUFFER_FORMAT_TILE_4x2) &&
 			(frame_size->height < MDP_MIN_TILE_HEIGHT)) {
+			frame_height_actual = frame_size->height;
 			frame_size->height = MDP_MIN_TILE_HEIGHT;
 			ddl_calculate_stride(frame_size,
 				!decoder->progressive_only);
@@ -1920,6 +1922,10 @@
 	input_buf_req->sz = (1024 * 1024 * 2);
 	input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
 	decoder->min_input_buf_req = *input_buf_req;
+	if (frame_height_actual) {
+		frame_size->height = frame_height_actual;
+		ddl_calculate_stride(frame_size, !decoder->progressive_only);
+	}
 	return true;
 }
 
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 7b5aa0b..b265eb9 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1618,6 +1618,7 @@
 	V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY	= 4,
 };
 #define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL		(V4L2_CID_MPEG_BASE+407)
+#define V4L2_CID_QCOM_VIDEO_SYNC_FRAME_SEQ_HDR		(V4L2_CID_MPEG_BASE+408)
 
 /*  MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
 #define V4L2_CID_MPEG_CX2341X_BASE 				(V4L2_CTRL_CLASS_MPEG | 0x1000)