diff --git a/drivers/clk/davinci/davinci-clock.c b/drivers/clk/davinci/davinci-clock.c
new file mode 100644
index 0000000..cbd5201
--- /dev/null
+++ b/drivers/clk/davinci/davinci-clock.c
@@ -0,0 +1,232 @@
+/*
+ * Clock initialization code for DaVinci devices
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * 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/init.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/platform_data/clk-davinci-pll.h>
+#include <linux/platform_data/clk-keystone-pll.h>
+#include <linux/platform_data/clk-davinci-psc.h>
+#include <linux/platform_data/davinci-clock.h>
+
+static DEFINE_SPINLOCK(_lock);
+
+struct clk *davinci_lookup_clk(struct davinci_clk_lookup *clocks,
+				const char *con_id)
+{
+	struct davinci_clk_lookup *c;
+
+	for (c = clocks; c->_clk; c++) {
+		if (c->con_id && !strcmp(c->con_id, con_id))
+			return c->clk;
+	}
+	return NULL;
+}
+
+#ifdef	CONFIG_CLK_DAVINCI_PLL
+static void register_davinci_pll_clk(struct davinci_clk_lookup *c,
+			struct clk_davinci_pll_data *pll_data)
+{
+
+	WARN_ON(!pll_data->phy_pllm);
+	pll_data->pllm = ioremap(pll_data->phy_pllm, 4);
+	WARN_ON(!pll_data->pllm);
+	if (pll_data->phy_prediv) {
+		pll_data->prediv = ioremap(pll_data->phy_prediv, 4);
+		WARN_ON(!pll_data->prediv);
+	}
+	if (pll_data->phy_postdiv) {
+		pll_data->postdiv = ioremap(pll_data->phy_postdiv, 4);
+		WARN_ON(!pll_data->postdiv);
+	}
+	c->clk = clk_register_davinci_pll(NULL,
+			c->_clk->name, c->_clk->parent->name,
+			pll_data);
+}
+#else
+static void register_davinci_pll_clk(struct davinci_clk_lookup *c,
+			struct clk_davinci_pll_data *pll_data)
+{
+	return;
+}
+#endif
+
+#ifdef	CONFIG_CLK_KEYSTONE_PLL
+static void register_keystone_pll_clk(struct davinci_clk_lookup *c,
+			struct clk_keystone_pll_data *pll_data)
+{
+	WARN_ON(!pll_data->phy_pllm);
+	pll_data->pllm = ioremap(pll_data->phy_pllm, 4);
+	WARN_ON(!pll_data->pllm);
+	WARN_ON(!pll_data->phy_main_pll_ctl0);
+	pll_data->main_pll_ctl0 =
+		ioremap(pll_data->phy_main_pll_ctl0, 4);
+	WARN_ON(!pll_data->main_pll_ctl0);
+	c->clk = clk_register_keystone_pll(NULL,
+			c->_clk->name, c->_clk->parent->name,
+			 pll_data);
+}
+#else
+static void register_keystone_pll_clk(struct davinci_clk_lookup *c,
+			struct clk_keystone_pll_data *pll_data)
+{
+	return;
+}
+#endif
+
+int __init davinci_common_clk_init(struct davinci_clk_lookup *clocks,
+				struct davinci_dev_lookup *dev_clk_lookups,
+				u8 num_gpscs, u32 *psc_bases)
+{
+	void __iomem **base = NULL, *reg;
+	struct davinci_clk_lookup *c;
+	struct davinci_clk *_clk;
+	unsigned long rate;
+	int i, skip;
+
+	WARN_ON(!num_gpscs);
+	WARN_ON(psc_bases == NULL);
+
+	base = kzalloc(sizeof(void __iomem *) * num_gpscs, GFP_KERNEL);
+	WARN_ON(!base);
+	for (i = 0; i < num_gpscs; i++) {
+		base[i] = ioremap(psc_bases[i], SZ_4K);
+		WARN_ON(!base[i]);
+	}
+
+	for (c = clocks; c->_clk; c++) {
+		skip = 0;
+		_clk = c->_clk;
+
+		WARN_ON(!_clk->clk_data.data);
+		switch (_clk->type) {
+		case DAVINCI_FIXED_RATE_CLK:
+		{
+			struct clk_fixed_rate_data *data = _clk->clk_data.fixed_rate;
+
+			if (data->recalc)
+				rate = data->recalc(0);
+			else
+				rate = data->rate;
+
+			c->clk = clk_register_fixed_rate(NULL, _clk->name,
+					NULL, data->flags, rate);
+			break;
+		}
+		case KEYSTONE_MAIN_PLL_CLK:
+		{
+			struct clk_keystone_pll_data *data =
+					_clk->clk_data.keystone_pll;
+
+			register_keystone_pll_clk(c, data);
+			break;
+		}
+		case DAVINCI_MAIN_PLL_CLK:
+		{
+			struct clk_davinci_pll_data *data =
+					_clk->clk_data.davinci_pll;
+
+			register_davinci_pll_clk(c, data);
+			break;
+		}
+		case DAVINCI_PRG_DIV_CLK:
+		{
+			struct clk_divider_data *data = _clk->clk_data.pll_div;
+
+			/* This is a PLL derived clock with divider specified by
+			 * div_reg in pll_div_data.
+			 */
+			reg = ioremap(data->div_reg, 4);
+			WARN_ON(!reg);
+			c->clk = clk_register_divider(NULL, _clk->name,
+					_clk->parent->name, data->flags,
+					reg, data->shift, data->width,
+					data->divider_flags, &_lock);
+			break;
+		}
+		case DAVINCI_PSC_CLK:
+		{
+			struct clk_davinci_psc_data *data = _clk->clk_data.psc;
+
+			WARN_ON(!base);
+			WARN_ON(data->gpsc >= num_gpscs);
+			data->base = base[data->gpsc];
+			c->clk = clk_register_davinci_psc(NULL, _clk->name,
+					_clk->parent->name, data, &_lock);
+			break;
+		}
+		case DAVINCI_MUX_CLK:
+		{
+			struct clk_mux_data *data = _clk->clk_data.mux;
+
+			WARN_ON(!data->phys_base);
+			reg = ioremap(data->phys_base, 4);
+			WARN_ON(!reg);
+			c->clk = clk_register_mux(NULL, _clk->name,
+					data->parents, data->num_parents,
+					data->flags, reg, data->shift,
+					data->width, data->mux_flags, &_lock);
+			break;
+		}
+		case DAVINCI_FIXED_FACTOR_CLK:
+		{
+			struct clk_fixed_factor_data *data
+						 = _clk->clk_data.fixed_factor;
+
+			WARN_ON(!data->mult);
+			WARN_ON(!data->div);
+			c->clk = clk_register_fixed_factor(NULL, _clk->name,
+					_clk->parent->name, data->flags,
+					data->mult, data->div);
+			break;
+		}
+		default:
+			skip = 1;
+			pr_warn("Unknown clock - %s\n", _clk->name);
+		}
+
+		if (!skip) {
+			WARN_ON(!c->clk);
+			if (clk_register_clkdev(c->clk,
+					c->con_id, c->dev_id) < 0) {
+				pr_err("Error in registering clkdev, %s\n",
+					_clk->name);
+			}
+			/* Enable ALWAYS_ENABLED clocks */
+			if (_clk->flags & ALWAYS_ENABLED)
+				clk_prepare_enable(c->clk);
+		}
+	}
+
+	if (dev_clk_lookups) {
+		struct davinci_dev_lookup *c;
+		struct clk *clk;
+
+		for (c = dev_clk_lookups; c->con_id; c++) {
+			/* register the clock lookup table */
+			clk = davinci_lookup_clk(clocks, c->con_id);
+			WARN_ON(!clk);
+
+			for (i = 0; i < c->num_devs; i++) {
+				if (clk_register_clkdev(clk,
+					c->lookups[i].con_id,
+					c->lookups[i].dev_id) < 0) {
+					pr_err("Error in registering clkdev" \
+						" for dev_id %s\n",
+						c->lookups[i].dev_id);
+				}
+			}
+		}
+	}
+	return 0;
+}
diff --git a/include/linux/platform_data/davinci-clock.h b/include/linux/platform_data/davinci-clock.h
new file mode 100644
index 0000000..942547e
--- /dev/null
+++ b/include/linux/platform_data/davinci-clock.h
@@ -0,0 +1,145 @@
+/*
+ * TI DaVinci Clock definitions -  Contains Macros and Types used for
+ * defining various clocks on a DaVinci SoC
+ *
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DAVINCI_CLOCK_H
+#define __DAVINCI_CLOCK_H
+
+#include <linux/types.h>
+
+struct clk;
+
+#define CLK(dev, con, ck)	\
+	{			\
+		.dev_id = dev,	\
+		.con_id = con,	\
+		._clk = ck,	\
+	}			\
+
+/* general flags: */
+#define ALWAYS_ENABLED		BIT(0)
+
+/* configuration data for clk mux */
+struct clk_mux_data {
+	u32			flags;
+	u8			mux_flags;
+	u8			shift;
+	u8			width;
+	u8			num_parents;
+	const char		**parents;
+	u32			phys_base;
+};
+
+/* configuration data for PLL divider clock */
+struct clk_divider_data {
+	u32			flags;
+	u8			divider_flags;
+	u32                     div_reg;
+	/* H/W supported max rate */
+	unsigned long		maxrate;
+	/* Width and shift for divider clock register mask */
+	u8			shift;
+	u8			width;
+};
+
+/* configuration data for fixed factor clocks. Some clocks in DaVinci are just
+ * duplicate clock pins that can be represented by this using a factor of 1
+ * for multiplier and divider
+ */
+struct clk_fixed_factor_data {
+	u32			flags;
+	u32			mult;
+	u32			div;
+};
+
+/* configuration data for fixed ref clock */
+struct clk_fixed_rate_data {
+	u32			flags;
+	unsigned long		rate;
+	/* where a register has input clock rate settings this function
+	 * is used to read that value from SoC specific code
+	 */
+	unsigned long		(*recalc)(unsigned long parent_rate);
+};
+
+/* forward declaration for other clock drivers */
+struct clk_davinci_pll_data;
+struct clk_keystone_pll_data;
+struct clk_psc_data;
+
+enum davinci_clk_type {
+	DAVINCI_MAIN_PLL_CLK,
+	KEYSTONE_MAIN_PLL_CLK,
+	DAVINCI_FIXED_RATE_CLK,
+	/* Use programmable divider */
+	DAVINCI_PRG_DIV_CLK,
+	/* Use fixed divider and multiplier */
+	DAVINCI_FIXED_FACTOR_CLK,
+	DAVINCI_PSC_CLK,
+	DAVINCI_MUX_CLK,
+};
+
+/* struct for defining DaVinci clocks for a SoC. Only one of the data ptr
+ * to be valid (non NULL). davinci_clk_init() in drivers/clk/davinci/clock.c
+ * check these ptr values to determine what clock register function to call
+ * to register a particular clock.
+ */
+struct davinci_clk {
+	const char			*name;
+	/* General flag for all drivers */
+	u32				flags;
+	struct davinci_clk		*parent;
+	enum davinci_clk_type		type;
+	/* one of these will be present in each SoC */
+	union {
+		/* root ref clock data */
+		struct clk_fixed_rate_data	*fixed_rate;
+		struct clk_davinci_pll_data	*davinci_pll;
+		struct clk_keystone_pll_data	*keystone_pll;
+		struct clk_divider_data		*pll_div;
+		struct clk_davinci_psc_data	*psc;
+		struct clk_mux_data		*mux;
+		struct clk_fixed_factor_data	*fixed_factor;
+		void				*data;
+	} clk_data;
+};
+
+/* struct for the DaVinci clock tables. */
+struct davinci_clk_lookup {
+	const char		*dev_id;
+	const char		*con_id;
+	struct davinci_clk      *_clk;
+	/* This saves the opaque clk ptr returned by clk_register() and is
+	 * saved to use later to register clkdevs for a specific clk node.
+	 */
+	struct clk		*clk;
+};
+
+/* struct for the DaVinci clkdev lookups. When several drivers uses the same
+ * clock, this structure is used to define a dev look up table that maps
+ * clkdevs to a clks node.
+ */
+struct davinci_dev_lookup {
+	const char		*con_id;
+	unsigned short		num_devs;
+	struct clk_lookup	*lookups;
+};
+
+/* clock init function for a DaVinci SoC (defined in drivers/clk/clock.c).
+ * This can also be used on other TI SoCs that has similar clock hardware.
+ */
+extern int davinci_common_clk_init(struct davinci_clk_lookup *clocks,
+				struct davinci_dev_lookup *dev_lookups,
+				u8 num_gpscs, u32 *psc_bases);
+#endif
