diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 3dced0a..ef839e7 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -88,4 +88,6 @@ config ARM_EXYNOS5_BUS_DEVFREQ
 	  It reads PPMU counters of memory controllers and adjusts the
 	  operating frequencies and voltages with OPP support.
 
+comment "DEVFREQ Event Drivers"
+
 endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 16138c9..a1ffabe 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_PM_DEVFREQ)	+= devfreq.o
+obj-$(CONFIG_PM_DEVFREQ)		+= devfreq.o devfreq-event.o
 obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)	+= governor_simpleondemand.o
 obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE)	+= governor_performance.o
 obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= governor_powersave.o
@@ -7,3 +7,6 @@ obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
 # DEVFREQ Drivers
 obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos/
 obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos/
+
+# DEVFREQ Event Drivers
+obj-$(CONFIG_PM_DEVFREQ)		+= event/
diff --git a/drivers/devfreq/devfreq-event.c b/drivers/devfreq/devfreq-event.c
new file mode 100644
index 0000000..1629197
--- /dev/null
+++ b/drivers/devfreq/devfreq-event.c
@@ -0,0 +1,251 @@
+/*
+ * devfreq-event: Generic DEVFREQ Event class driver
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ * Chanwoo Choi <cw00.choi@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.
+ *
+ * This driver is based on drivers/devfreq/devfreq.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/pm_opp.h>
+#include <linux/devfreq.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <linux/printk.h>
+#include <linux/hrtimer.h>
+#include <linux/of.h>
+#include "governor.h"
+
+static struct class *devfreq_event_class;
+
+/* The list of all devfreq event list */
+static LIST_HEAD(devfreq_event_list);
+static DEFINE_MUTEX(devfreq_event_list_lock);
+
+#define to_devfreq_event(DEV) container_of(DEV, struct devfreq_event_dev, dev)
+
+struct devfreq_event_dev *devfreq_add_event_device(struct device *dev,
+					struct devfreq_event_desc *desc)
+{
+	struct devfreq_event_dev *edev;
+	static atomic_t event_no = ATOMIC_INIT(0);
+	int ret;
+
+	if (!dev || !desc)
+		return ERR_PTR(-EINVAL);
+
+	if (!desc->name || !desc->ops || !desc->dev)
+		return ERR_PTR(-EINVAL);
+
+	edev = kzalloc(sizeof(struct devfreq_event_dev), GFP_KERNEL);
+	if (!edev)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_lock(&devfreq_event_list_lock);
+
+	mutex_init(&edev->mutex);
+	edev->desc = desc;
+	edev->driver_data = desc->driver_data;
+	edev->owner = desc->owner;
+
+	edev->dev.parent = dev;
+	edev->dev.class = devfreq_event_class;
+
+	dev_set_name(&edev->dev, "event.%d",
+		     atomic_inc_return(&event_no) - 1);
+	ret = device_register(&edev->dev);
+	if (ret != 0) {
+		put_device(&edev->dev);
+		goto err;
+	}
+	dev_set_drvdata(&edev->dev, edev);
+
+	/* Add devfreq event device to devfreq_event_list */
+	INIT_LIST_HEAD(&edev->node);
+	list_add(&edev->node, &devfreq_event_list);
+
+	mutex_unlock(&devfreq_event_list_lock);
+
+	return edev;
+err:
+	kfree(edev);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(devfreq_add_event_device);
+
+struct devfreq_event_dev *devfreq_get_edev(const char *edev_name)
+{
+	struct devfreq_event_dev *edev;
+
+	mutex_lock(&devfreq_event_list_lock);
+	list_for_each_entry(edev, &devfreq_event_list, node) {
+		if (!strcmp(edev->desc->name, edev_name))
+			goto out;
+	}
+	edev = NULL;
+out:
+	mutex_unlock(&devfreq_event_list_lock);
+
+	return edev;
+}
+EXPORT_SYMBOL_GPL(devfreq_get_edev);
+
+struct devfreq_event_dev *devfreq_get_edev_by_phandle(struct device *dev,
+						      int index)
+{
+	struct device_node *node;
+	struct devfreq_event_dev *edev;
+
+	if (!dev->of_node) {
+		dev_err(dev, "device does not have a device node entry\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	node = of_parse_phandle(dev->of_node, "devfreq-events", index);
+	if (!node) {
+		dev_err(dev, "failed to get phandle in %s node\n",
+			dev->of_node->full_name);
+		return ERR_PTR(-ENODEV);
+	}
+
+	edev = devfreq_get_edev(node->name);
+	if (!edev) {
+		dev_err(dev, "unable to get devfreq-event device : %s\n",
+			node->name);
+		return ERR_PTR(-ENODEV);
+	}
+
+	return edev;
+}
+EXPORT_SYMBOL_GPL(devfreq_get_edev_by_phandle);
+
+int devfreq_put_edev(struct devfreq_event_dev *edev)
+{
+	return 0;
+}
+EXPORT_SYMBOL_GPL(devfreq_put_edev);
+
+int devfreq_enable_edev(struct devfreq_event_dev *edev)
+{
+	if (!edev || !edev->desc)
+		return -EINVAL;
+
+	if (edev->desc->ops && edev->desc->ops->enable)
+		return edev->desc->ops->enable(edev);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(devfreq_enable_edev);
+
+int devfreq_disable_edev(struct devfreq_event_dev *edev)
+{
+	if (!edev || !edev->desc)
+		return -EINVAL;
+
+	if (edev->desc->ops && edev->desc->ops->disable)
+		return edev->desc->ops->disable(edev);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(devfreq_disable_edev);
+
+int devfreq_set_event_edev(struct devfreq_event_dev *edev)
+{
+	if (!edev || !edev->desc)
+		return -EINVAL;
+
+	if (edev->desc->ops && edev->desc->ops->set_event)
+		return edev->desc->ops->set_event(edev);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(devfreq_set_event_edev);
+
+int devfreq_get_event_edev(struct devfreq_event_dev *edev)
+{
+	if (!edev || !edev->desc)
+		return -EINVAL;
+
+	if (edev->desc->ops && edev->desc->ops->get_event)
+		return edev->desc->ops->get_event(edev);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(devfreq_get_event_edev);
+
+int devfreq_reset_edev(struct devfreq_event_dev *edev)
+{
+	if (!edev || !edev->desc)
+		return -EINVAL;
+
+	if (edev->desc->ops && edev->desc->ops->reset)
+		return edev->desc->ops->reset(edev);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(devfreq_reset_edev);
+
+void *edev_get_drvdata(struct devfreq_event_dev *edev)
+{
+	return edev->driver_data;
+}
+EXPORT_SYMBOL_GPL(edev_get_drvdata);
+
+/*
+ * Device Attribues for devfreq event class
+ */
+static ssize_t name_show(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct devfreq_event_dev *edev = to_devfreq_event(dev);
+
+	if (!edev || !edev->desc)
+		return -EINVAL;
+
+	return sprintf(buf, "%s\n", edev->desc->name);
+}
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *devfreq_event_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(devfreq_event);
+
+static int __init devfreq_event_init(void)
+{
+	devfreq_event_class = class_create(THIS_MODULE, "devfreq_event");
+	if (IS_ERR(devfreq_event_class)) {
+		pr_err("%s: couldn't create class\n", __FILE__);
+		return PTR_ERR(devfreq_event_class);
+	}
+
+	devfreq_event_class->dev_groups = devfreq_event_groups;
+
+	return 0;
+}
+subsys_initcall(devfreq_event_init);
+
+static void __exit devfreq_event_exit(void)
+{
+	class_destroy(devfreq_event_class);
+}
+module_exit(devfreq_event_exit);
+
+MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
+MODULE_DESCRIPTION("devfreq-event class support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile
new file mode 100644
index 0000000..dc56005
--- /dev/null
+++ b/drivers/devfreq/event/Makefile
@@ -0,0 +1 @@
+# Exynos DEVFREQ Event Drivers
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index f1863dc..a87989b 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -175,6 +175,36 @@ struct devfreq {
 	unsigned long last_stat_updated;
 };
 
+struct devfreq_event_dev {
+	const struct devfreq_event_desc *desc;
+
+	struct list_head node;
+	struct device dev;
+	struct module *owner;
+	struct mutex mutex;
+
+	void *driver_data;
+};
+
+struct devfreq_event_ops {
+	int (*enable)(struct devfreq_event_dev *edev);
+	int (*disable)(struct devfreq_event_dev *edev);
+	int (*set_event)(struct devfreq_event_dev *edev);
+	int (*get_event)(struct devfreq_event_dev *edev);
+	int (*reset)(struct devfreq_event_dev *edev);
+};
+
+struct devfreq_event_desc {
+	const char *name;
+	unsigned int id;
+
+	struct devfreq_event_ops *ops;
+	struct device *dev;
+	struct module *owner;
+
+	void *driver_data;
+};
+
 #if defined(CONFIG_PM_DEVFREQ)
 extern struct devfreq *devfreq_add_device(struct device *dev,
 				  struct devfreq_dev_profile *profile,
@@ -204,6 +234,20 @@ extern int devm_devfreq_register_opp_notifier(struct device *dev,
 extern void devm_devfreq_unregister_opp_notifier(struct device *dev,
 						struct devfreq *devfreq);
 
+/* Functions for devfreq event device */
+extern struct devfreq_event_dev *devfreq_add_event_device(struct device *dev,
+				struct devfreq_event_desc *desc);
+extern struct devfreq_event_dev *devfreq_get_edev(const char *name);
+extern struct devfreq_event_dev *devfreq_get_edev_by_phandle(struct device *dev,
+							     int index);
+extern int devfreq_put_edev(struct devfreq_event_dev *edev);
+extern int devfreq_enable_edev(struct devfreq_event_dev *edev);
+extern int devfreq_disable_edev(struct devfreq_event_dev *edev);
+extern int devfreq_set_event_edev(struct devfreq_event_dev *edev);
+extern int devfreq_get_event_edev(struct devfreq_event_dev *edev);
+extern int devfreq_reset_edev(struct devfreq_event_dev *edev);
+extern void *edev_get_drvdata(struct devfreq_event_dev *edev);
+
 #if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
 /**
  * struct devfreq_simple_ondemand_data - void *data fed to struct devfreq
@@ -233,6 +277,13 @@ static inline struct devfreq *devfreq_add_device(struct device *dev,
 	return ERR_PTR(-ENOSYS);
 }
 
+static inline struct devfreq_event_dev *devfreq_add_event_device(
+					struct device *dev,
+					struct devfreq_event_desc *desc);
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline int devfreq_remove_device(struct devfreq *devfreq)
 {
 	return 0;
@@ -289,6 +340,52 @@ static inline void devm_devfreq_unregister_opp_notifier(struct device *dev,
 							struct devfreq *devfreq)
 {
 }
+
+static inline void *edev_get_drvdata(struct devfreq_event_dev *edev);
+{
+	return ERR_PTR(-EINVAL);
+}
+
+static inline struct devfreq_event_dev *devfreq_get_edev(const char *name)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+struct devfreq_event_dev *devfreq_get_edev_by_phandle(struct device *dev,
+						      int index)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline int devfreq_put_edev(struct devfreq_event_dev *edev)
+{
+	return -EINVAL;
+}
+
+static inline int devfreq_enable_edev(struct devfreq_event_dev *edev)
+{
+	return -EINVAL;
+}
+
+static inline int devfreq_disable_edev(struct devfreq_event_dev *edev)
+{
+	return -EINVAL;
+}
+
+static inline int devfreq_set_event_edev(struct devfreq_event_dev *edev)
+{
+	return -EINVAL;
+}
+
+static inline int devfreq_get_event_edev(struct devfreq_event_dev *edev)
+{
+	return -EINVAL;
+}
+
+static inline int devfreq_reset_edev(struct devfreq_event_dev *edev)
+{
+	return -EINVAL;
+}
 #endif /* CONFIG_PM_DEVFREQ */
 
 #endif /* __LINUX_DEVFREQ_H__ */
