diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index a64caef..4b5109c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -71,6 +71,13 @@ config COMMON_CLK_AXI_CLKGEN
 	  Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
 	  FPGAs. It is commonly used in Analog Devices' reference designs.
 
+config CLK_LP8788
+	tristate "Clock driver for TI LP8788 PMU"
+	depends on MFD_LP8788
+	---help---
+	  Supports the clock subsystem of TI LP8788. It generates the 32KHz
+	  clock output.
+
 endmenu
 
 source "drivers/clk/mvebu/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 79e98e4..98f3883 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -37,3 +37,4 @@ obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
 obj-$(CONFIG_CLK_TWL6040)	+= clk-twl6040.o
+obj-$(CONFIG_CLK_LP8788)	+= clk-lp8788.o
diff --git a/drivers/clk/clk-lp8788.c b/drivers/clk/clk-lp8788.c
new file mode 100644
index 0000000..c636fd7
--- /dev/null
+++ b/drivers/clk/clk-lp8788.c
@@ -0,0 +1,160 @@
+/*
+ * TI LP8788 Clock Driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.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/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+/* Registers */
+#define LP8788_REG_STATUS		0x06
+#define LP8788_OSC_WORKING		0x10
+
+#define LP8788_REG_CLKCTRL		0xA2
+#define LP8788_CLKMODE_MASK		0x02
+#define LP8788_CLKMODE_AUTO		0X02
+
+#define CLKOUT_32KHZ			32768
+
+struct lp8788_clk {
+	struct lp8788 *lp;
+	struct clk *clk;
+	struct clk_hw hw;
+	struct clk_lookup *lookup;
+};
+
+static int lp8788_clk_prepare(struct clk_hw *hw)
+{
+	struct lp8788_clk *pclk = container_of(hw, struct lp8788_clk, hw);
+
+	/* Automatic oscillator source selection */
+	return lp8788_update_bits(pclk->lp, LP8788_REG_CLKCTRL,
+				LP8788_CLKMODE_MASK, LP8788_CLKMODE_AUTO);
+}
+
+static void lp8788_clk_unprepare(struct clk_hw *hw)
+{
+	/* Do nothing */
+	return;
+}
+
+static unsigned long lp8788_clk_recalc_rate(struct clk_hw *hw,
+					unsigned long unused)
+{
+	return CLKOUT_32KHZ;
+}
+
+static const struct clk_ops lp8788_clk_ops = {
+	.prepare = lp8788_clk_prepare,
+	.unprepare = lp8788_clk_unprepare,
+	.recalc_rate = lp8788_clk_recalc_rate,
+};
+
+static struct clk_init_data lp8788_clk_cfg = {
+	.name = "32k_clk",
+	.ops = &lp8788_clk_ops,
+	.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
+};
+
+static int lp8788_clk_register(struct device *dev, struct lp8788_clk *pclk)
+{
+	struct clk_lookup *lookup;
+
+	pclk->hw.init = &lp8788_clk_cfg;
+	pclk->clk = devm_clk_register(dev, &pclk->hw);
+	if (IS_ERR(pclk->clk)) {
+		dev_err(dev, "clk register err\n");
+		return PTR_ERR(pclk->clk);
+	}
+
+	lookup = clkdev_alloc(pclk->clk, lp8788_clk_cfg.name, NULL);
+	if (!lookup) {
+		dev_err(dev, "clkdev_alloc err\n");
+		return -ENOMEM;
+	}
+	pclk->lookup = lookup;
+
+	clkdev_add(lookup);
+
+	return 0;
+}
+
+static void lp8788_clk_unregister(struct lp8788_clk *pclk)
+{
+	if (pclk->lookup)
+		clkdev_drop(pclk->lookup);
+}
+
+static bool lp8788_is_clk_device_ready(struct lp8788_clk *pclk)
+{
+	u8 val = 0;
+
+	lp8788_read_byte(pclk->lp, LP8788_REG_STATUS, &val);
+
+	return val & LP8788_OSC_WORKING;
+}
+
+static int lp8788_clk_probe(struct platform_device *pdev)
+{
+	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
+	struct lp8788_clk *pclk;
+
+	pclk = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_clk), GFP_KERNEL);
+	if (!pclk)
+		return -ENOMEM;
+
+	pclk->lp = lp;
+	platform_set_drvdata(pdev, pclk);
+
+	if (!lp8788_is_clk_device_ready(pclk))
+		return -ENODEV;
+
+	return lp8788_clk_register(&pdev->dev, pclk);
+}
+
+static int lp8788_clk_remove(struct platform_device *pdev)
+{
+	struct lp8788_clk *pclk = platform_get_drvdata(pdev);
+
+	lp8788_clk_unregister(pclk);
+	return 0;
+}
+
+static struct platform_driver lp8788_clk_driver = {
+	.probe = lp8788_clk_probe,
+	.remove = lp8788_clk_remove,
+	.driver		= {
+		.name	= LP8788_DEV_CLK,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init lp8788_clk_init(void)
+{
+	return platform_driver_register(&lp8788_clk_driver);
+}
+subsys_initcall(lp8788_clk_init);
+
+static void __exit lp8788_clk_exit(void)
+{
+	platform_driver_unregister(&lp8788_clk_driver);
+}
+module_exit(lp8788_clk_exit);
+
+MODULE_DESCRIPTION("TI LP8788 Clock Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lp8788-clk");
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
index c3d3c9b..9f5596e 100644
--- a/drivers/mfd/lp8788.c
+++ b/drivers/mfd/lp8788.c
@@ -72,6 +72,8 @@ static struct resource rtc_irqs[] = {
 };
 
 static struct mfd_cell lp8788_devs[] = {
+	MFD_DEV_SIMPLE(CLK),
+
 	/* 4 bucks */
 	MFD_DEV_WITH_ID(BUCK, 1),
 	MFD_DEV_WITH_ID(BUCK, 2),
diff --git a/include/linux/mfd/lp8788.h b/include/linux/mfd/lp8788.h
index 786bf66..5f33be8 100644
--- a/include/linux/mfd/lp8788.h
+++ b/include/linux/mfd/lp8788.h
@@ -28,6 +28,7 @@
 #define LP8788_DEV_VIBRATOR	"lp8788-vibrator"
 #define LP8788_DEV_KEYLED	"lp8788-keyled"
 #define LP8788_DEV_ADC		"lp8788-adc"
+#define LP8788_DEV_CLK		"lp8788-clk"
 
 #define LP8788_NUM_BUCKS	4
 #define LP8788_NUM_DLDOS	12
