All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <4AF9721B.4070203@st.com>

diff --git a/a/1.1.hdr b/a/1.1.hdr
deleted file mode 100644
index 094af2c..0000000
--- a/a/1.1.hdr
+++ /dev/null
@@ -1,2 +0,0 @@
-Content-Type: text/plain; charset=ISO-8859-1; format=flowed
-Content-Transfer-Encoding: 7bit
diff --git a/a/1.2.bin b/a/1.2.bin
deleted file mode 100644
index 57bd2c0..0000000
--- a/a/1.2.bin
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-
-<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-</head>
-<body text="#000000" bgcolor="#ffffff">
-<big><big><tt>Hi all<br>
-<br>
-I'm Francesco and I work in STMicroelectronics<br>
-<br>
-In the last ELC-E_2009 I spoke on a generic clock framework I'm working
-on<br>
-&nbsp;(see
-<a class="moz-txt-link-freetext" href="http://tree.celinuxforum.org/CelfPubWiki/ELCEurope2009Presentations?action=AttachFile&amp;do=view&amp;target=ELC_E_2009_Generic_Clock_Framework.pdf">http://tree.celinuxforum.org/CelfPubWiki/ELCEurope2009Presentations?action=AttachFile&amp;do=view&amp;target=ELC_E_2009_Generic_Clock_Framework.pdf</a>).<br>
-<br>
-</tt><tt>I wrote the gcf to manage both clocks the platform_devices
-during a clock operation.<br>
-<br>
-</tt><tt>The main features are:<br>
-&nbsp;- it's integrated in the LDM<br>
-</tt></big></big><big><big><tt>&nbsp;- it tracks the clock-to-clock
-relationship<br>
-&nbsp;- it tracks the clock-to-device relationship<br>
-<br>
-</tt></big></big><big><big><tt>&nbsp;- it has sysfs interface<br>
-&nbsp;- - the user can navigate the clock tree under /sys/clocks/...<br>
-<br>
-&nbsp;- it uses the linux API (&lt;linux/clk.h&gt;) with some extra
-functions (to register/unregister a clock<br>
-&nbsp;&nbsp; and other utility functions as clk_for_each())<br>
-<br>
-&nbsp;- it involves the platform_device and the platform_driver in the clock
-propagation.<br>
-&nbsp;- - basically each clock operation is managed as a transaction which
-evolves step by step.<br>
-&nbsp;- - </tt><tt>all the clock rates are evaluated (before the clk
-operation is actually done)<br>
-</tt><tt>&nbsp;- - each platform_device can check (</tt><tt>before the clk
-operation is </tt></big></big><big><big><tt>actually</tt></big></big><big><big><tt>
-done</tt><tt>) the clk environment<br>
-&nbsp;&nbsp;&nbsp;&nbsp; it will have at the end of clock operation and if required it can
-reject the operation.<br>
-&nbsp;- - each clock operation is </tt></big></big><big><big><tt>actually</tt></big></big><big><big><tt>
-executed only if all the </tt><tt>platform_</tt><tt>devices accept the
-operation it-self<br>
-<br>
-<br>
-Moreover a common clock framework could be used to avoid a lot of
-duplicated and/or similar code<br>
-&nbsp;just a grep of 'EXPORT_SYMBOL\(clk_enable' under arch/arm finds 22
-entries.<br>
-<br>
-The patch is based on a 2.6.30 kernel also if it has a preliminary
-integration with the PM_RUNTIME<br>
-&nbsp;support.<br>
-<br>
-It works on our st40 (an sh4 cpu based system) no test/porting was done
-on any ARM platform.<br>
-<br>
-It would be mainly a starting point for a discussion and I'm available
-to extend/fix/share it.<br>
-<br>
-Regards<br>
-&nbsp;Francesco</tt></big></big><br>
-</body>
-</html>
diff --git a/a/1.2.hdr b/a/1.2.hdr
deleted file mode 100644
index e403a18..0000000
--- a/a/1.2.hdr
+++ /dev/null
@@ -1,2 +0,0 @@
-Content-Type: text/html; charset=ISO-8859-1
-Content-Transfer-Encoding: 7bit
diff --git a/a/1.1.txt b/N1/1.txt
similarity index 80%
rename from a/1.1.txt
rename to N1/1.txt
index 1d61c6b..a08e6c7 100644
--- a/a/1.1.txt
+++ b/N1/1.txt
@@ -52,3 +52,10 @@ to extend/fix/share it.
 
 Regards
   Francesco
+-------------- next part --------------
+An HTML attachment was scrubbed...
+URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20091110/a197b928/attachment-0001.htm>
+-------------- next part --------------
+An embedded and charset-unspecified text was scrubbed...
+Name: 0001-generic-clock-framework.patch
+URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20091110/a197b928/attachment-0001.el>
diff --git a/a/2.hdr b/a/2.hdr
deleted file mode 100644
index f9dadb5..0000000
--- a/a/2.hdr
+++ /dev/null
@@ -1,5 +0,0 @@
-Content-Type: text/plain;
- name="0001-generic-clock-framework.patch"
-Content-Transfer-Encoding: 7bit
-Content-Disposition: attachment;
- filename="0001-generic-clock-framework.patch"
diff --git a/a/2.txt b/a/2.txt
deleted file mode 100644
index 2756354..0000000
--- a/a/2.txt
+++ /dev/null
@@ -1,3071 +0,0 @@
-From 4e065fb9247ec511bfdc88001f0713977d3f4e89 Mon Sep 17 00:00:00 2001
-From: Francesco Virlinzi <francesco.virlinzi@st.com>
-Date: Fri, 23 Oct 2009 15:26:42 +0200
-Subject: [PATCH] generic clock framework
-
-version: 0.6.2
-
-Signed-off-by: Francesco Virlinzi <francesco.virlinzi@st.com>
----
- drivers/base/Makefile           |    4 +
- drivers/base/base.h             |    5 +
- drivers/base/clk.c              | 1606 +++++++++++++++++++++++++++++++++++++++
- drivers/base/clk.h              |  319 ++++++++
- drivers/base/clk_pm.c           |  197 +++++
- drivers/base/clk_utils.c        |  456 +++++++++++
- drivers/base/init.c             |    1 +
- drivers/base/platform.c         |   27 +
- include/linux/clk.h             |  251 ++++++
- include/linux/platform_device.h |    9 +
- init/Kconfig                    |   23 +
- 11 files changed, 2898 insertions(+), 0 deletions(-)
- create mode 100644 drivers/base/clk.c
- create mode 100644 drivers/base/clk.h
- create mode 100644 drivers/base/clk_pm.c
- create mode 100644 drivers/base/clk_utils.c
-
-diff --git a/drivers/base/Makefile b/drivers/base/Makefile
-index b5b8ba5..b78a2bf 100644
---- a/drivers/base/Makefile
-+++ b/drivers/base/Makefile
-@@ -16,6 +16,10 @@ ifeq ($(CONFIG_SYSFS),y)
- obj-$(CONFIG_MODULES)	+= module.o
- endif
- obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
-+ifdef CONFIG_GENERIC_CLK_FM
-+obj-y			+= clk.o clk_utils.o
-+obj-$(CONFIG_PM)	+= clk_pm.o
-+endif
- 
- ifeq ($(CONFIG_DEBUG_DRIVER),y)
- EXTRA_CFLAGS += -DDEBUG
-diff --git a/drivers/base/base.h b/drivers/base/base.h
-index b528145..bc5b9e8 100644
---- a/drivers/base/base.h
-+++ b/drivers/base/base.h
-@@ -94,6 +94,11 @@ extern int devices_init(void);
- extern int buses_init(void);
- extern int classes_init(void);
- extern int firmware_init(void);
-+#ifdef CONFIG_GENERIC_CLK_FM
-+extern int clock_init(void);
-+#else
-+static inline int clock_init(void){ return 0; }
-+#endif
- #ifdef CONFIG_SYS_HYPERVISOR
- extern int hypervisor_init(void);
- #else
-diff --git a/drivers/base/clk.c b/drivers/base/clk.c
-new file mode 100644
-index 0000000..7feae61
---- /dev/null
-+++ b/drivers/base/clk.c
-@@ -0,0 +1,1606 @@
-+/*
-+ * -------------------------------------------------------------------------
-+ * clk.c
-+ * -------------------------------------------------------------------------
-+ * (C) STMicroelectronics 2008
-+ * (C) STMicroelectronics 2009
-+ * Author: Francesco M. Virlinzi <francesco.virlinzi@st.com>
-+ * -------------------------------------------------------------------------
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License v.2 ONLY.  See linux/COPYING for more information.
-+ *
-+ * -------------------------------------------------------------------------
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <linux/clk.h>
-+#include <linux/klist.h>
-+#include <linux/sysdev.h>
-+#include <linux/kref.h>
-+#include <linux/kobject.h>
-+#include <linux/err.h>
-+#include <linux/spinlock.h>
-+#include <asm/atomic.h>
-+#include "clk.h"
-+#include "base.h"
-+
-+#define CLK_NAME		"Generic Clk Framework"
-+#define CLK_VERSION		"0.6.2"
-+
-+/* #define CLK_SAFE_CODE */
-+
-+klist_entry_support(clock, clk, node)
-+klist_entry_support(child_clock, clk, child_node)
-+klist_entry_support(dev_info, pdev_clk_info, node)
-+
-+#define to_clk(ptr)	container_of(ptr, struct clk, kobj)
-+#define to_tnode(ptr)	container_of(ptr, struct clk_tnode, pnode)
-+
-+static int sysfs_clk_attr_show(struct kobject *kobj,
-+				struct attribute *attr, char *buf)
-+{
-+	ssize_t ret = -EIO;
-+	struct kobj_attribute *kattr
-+	    = container_of(attr, struct kobj_attribute, attr);
-+	if (kattr->show)
-+		ret = kattr->show(kobj, kattr, buf);
-+	return ret;
-+}
-+
-+static ssize_t
-+sysfs_clk_attr_store(struct kobject *kobj, struct attribute *attr,
-+			const char *buf, size_t count)
-+{
-+	ssize_t ret = -EIO;
-+	struct kobj_attribute *kattr
-+	    = container_of(attr, struct kobj_attribute, attr);
-+	if (kattr->store)
-+		ret = kattr->store(kobj, kattr, buf, count);
-+	return ret;
-+}
-+
-+static struct sysfs_ops clk_sysfs_ops = {
-+	.show = sysfs_clk_attr_show,
-+	.store = sysfs_clk_attr_store,
-+};
-+
-+static struct kobj_type ktype_clk = {
-+	.sysfs_ops = &clk_sysfs_ops,
-+};
-+
-+static struct clk *check_clk(struct clk *);
-+
-+static struct kobject *clk_kobj;
-+static DEFINE_MUTEX(clk_list_sem);
-+static atomic_t transaction_counter = ATOMIC_INIT(0);
-+struct klist clk_list = KLIST_INIT(clk_list, NULL, NULL);
-+
-+klist_function_support(child, clk, child_node, kobj)
-+klist_function_support(device, pdev_clk_info, node, pdev->dev.kobj)
-+
-+/*
-+ * The ___clk_xxx operations doesn't raise propagation
-+ * they are used to operate on the real clock
-+ */
-+static int
-+__clk_operations(struct clk *clk, unsigned long rate,
-+	enum clk_ops_id const id_ops)
-+{
-+	int ret = 0;
-+	unsigned long *ops_fns = (unsigned long *)clk->ops;
-+	if (likely(ops_fns && ops_fns[id_ops])) {
-+		int (*fns)(struct clk *clk, unsigned long rate)
-+			= (void *)ops_fns[id_ops];
-+		unsigned long flags;
-+		spin_lock_irqsave(&clk->lock, flags);
-+		ret = fns(clk, rate);
-+		spin_unlock_irqrestore(&clk->lock, flags);
-+	}
-+	return ret;
-+}
-+
-+static inline int __clk_init(struct clk *clk)
-+{
-+	pr_debug(": %s\n", clk->name);
-+	return __clk_operations(clk, 0, __CLK_INIT);
-+}
-+static inline int __clk_enable(struct clk *clk)
-+{
-+	pr_debug(": %s\n", clk->name);
-+	return __clk_operations(clk, 0, __CLK_ENABLE);
-+}
-+static inline int __clk_disable(struct clk *clk)
-+{
-+	pr_debug(": %s\n", clk->name);
-+	return __clk_operations(clk, 0, __CLK_DISABLE);
-+}
-+static inline int __clk_set_rate(struct clk *clk, unsigned long rate)
-+{
-+	pr_debug(": %s\n", clk->name);
-+	return __clk_operations(clk, rate, __CLK_SET_RATE);
-+}
-+static inline int __clk_set_parent(struct clk *clk, struct clk *parent)
-+{
-+	pr_debug(": %s\n", clk->name);
-+	return __clk_operations(clk, (unsigned long)parent, __CLK_SET_PARENT);
-+}
-+static inline int __clk_recalc_rate(struct clk *clk)
-+{
-+	pr_debug(": %s\n", clk->name);
-+	return __clk_operations(clk, 0, __CLK_RECALC);
-+}
-+static inline int __clk_round(struct clk *clk, unsigned long value)
-+{
-+	pr_debug(": %s\n", clk->name);
-+	return __clk_operations(clk, value, __CLK_ROUND);
-+}
-+
-+static inline int __clk_eval(struct clk *clk, unsigned long prate)
-+{
-+#ifndef CONFIG_CLK_FORCE_GENERIC_EVALUATE
-+	pr_debug(": %s\n", clk->name);
-+	return	__clk_operations(clk, prate, __CLK_EVAL);
-+#else
-+	unsigned long rate, flags;
-+	pr_debug(": %s\n", clk->name);
-+	if (likely(clk->ops && clk->ops->eval)) {
-+		spin_lock_irqsave(&clk->lock, flags);
-+		rate = clk->ops->eval(clk, prate);
-+		spin_unlock_irqrestore(&clk->lock, flags);
-+	} else
-+		rate = clk_generic_evaluate_rate(clk, prate);
-+	return rate;
-+#endif
-+}
-+
-+#ifdef CONFIG_PM_RUNTIME
-+static int
-+clk_pm_runtime_devinfo(enum rpm_status code, struct pdev_clk_info *info)
-+{
-+	struct platform_device *pdev = info->pdev;
-+
-+	pr_debug("\n");
-+
-+	switch (code) {
-+	case RPM_ACTIVE:
-+		return clk_notify_child_event(CHILD_DEVICE_ENABLED, info->clk);
-+	case RPM_SUSPENDED:
-+		return clk_notify_child_event(CHILD_DEVICE_DISABLED, info->clk);
-+	}
-+	return -EINVAL;
-+}
-+
-+int clk_pm_runtime_device(enum rpm_status code, struct platform_device *dev)
-+{
-+	int idx;
-+	int ret = 0;
-+	struct pdev_clk_info *info;
-+
-+	if (!dev)
-+		return -EFAULT;
-+
-+	if (!dev->clks || !pdevice_num_clocks(dev))
-+		return 0;
-+
-+	pr_debug("\n");
-+/*
-+ *	Check if the device is under a transaction.
-+ * 	If so the GCFdoesn't raise a 'clk_pm_runtime_devinfo'
-+ *	all the device change will be notified on 'tnode_transaction_complete'
-+ *	if required....
-+ */
-+	if (atomic_read((atomic_t *)&dev->clk_flags)) {
-+		pr_debug("%s.%d under transaction\n", dev->name, dev->id);
-+		return ret;
-+	}
-+	for (idx = 0, info = dev->clks; idx < pdevice_num_clocks(dev); ++idx)
-+		ret |= clk_pm_runtime_devinfo(&info[idx], state, 0);
-+
-+	return ret;
-+}
-+#else
-+#define clk_pm_runtime_devinfo(x, y)
-+#define clk_pm_runtime_device(x, y)
-+#endif
-+
-+/**
-+ * tnode_malloc
-+ *
-+ * Allocs the memory for both the transaction and the
-+ * clk_event objects
-+ */
-+static struct clk_tnode *tnode_malloc(struct clk_tnode *parent,
-+	unsigned long nevent)
-+{
-+	struct clk_event *evt;
-+	struct clk_tnode *node;
-+
-+	if (nevent > 32)
-+		return NULL;
-+
-+	node = kmalloc(sizeof(*node) + nevent *	sizeof(*evt), GFP_KERNEL);
-+
-+	if (!node)
-+		return NULL;
-+
-+	evt = (struct clk_event *)(sizeof(struct clk_tnode) + (long)node);
-+
-+	node->tid    = atomic_inc_return(&transaction_counter);
-+	node->parent = parent;
-+	node->size   = nevent;
-+	node->events = evt;
-+	node->events_map = 0;
-+	INIT_LIST_HEAD(&node->childs);
-+
-+	return node;
-+}
-+
-+/**
-+ * tnode_free
-+ *
-+ * Free the tnode memory
-+ */
-+static void tnode_free(struct clk_tnode *node)
-+{
-+	if (tnode_get_parent(node)) {
-+		list_del(&node->pnode);
-+		kfree(node);
-+	}
-+}
-+
-+/**
-+ *  tnode_check_clock -
-+ *
-+ *  @node: the tnode object
-+ *  @clk:  the clock object
-+ *
-+ *  returns a boolean value
-+ *  it checks if the clock (clk) is managed by the
-+ *  tnode (node) or any parent node
-+ */
-+static int __must_check
-+tnode_check_clock(struct clk_tnode *node, struct clk *clk)
-+{
-+	int j;
-+	for (; node; node = tnode_get_parent(node))
-+		/* scans all the event */
-+		tnode_for_each_valid_events(node, j)
-+			if (tnode_get_clock(node, j) == clk)
-+					return 1; /* FOUND!!! */
-+	return 0;
-+}
-+
-+/**
-+  * tnode_lock_clocks -
-+  *
-+  * @node: the tnode object
-+  *
-+  * marks all the clocks under transaction to be sure there is no more
-+  * than one transaction for each clock
-+  */
-+static int __must_check
-+tnode_lock_clocks(struct clk_tnode *node)
-+{
-+	int i;
-+	pr_debug("\n");
-+
-+	/* 1. try to mark all the clocks in transaction */
-+	for (i = 0; i < tnode_get_size(node); ++i)
-+		if (clk_set_towner(tnode_get_clock(node, i), node)) {
-+			struct clk *clkp = tnode_get_clock(node, i);
-+			/* this clock is already locked */
-+			/* we accept that __only__ if it is locked by a
-+			 * parent tnode!!!
-+			 */
-+			if (!tnode_get_parent(node)) {
-+				pr_debug("Error clk %s locked but "
-+					  "there is no parent!\n", clkp->name);
-+				goto err_0;
-+			}
-+			pr_debug("clk %s already locked\n", clkp->name);
-+			if (tnode_check_clock(tnode_get_parent(node), clkp)) {
-+				pr_debug("ok clk %s locked "
-+					  "by a parent\n", clkp->name);
-+				continue;
-+			} else
-+				goto err_0;
-+		} else
-+			/* set the event as valid in the bitmap*/
-+			tnode_set_map_id(node, i);
-+
-+/*
-+ * all the clocks are marked succesfully or all the clock on
-+ * this tnode are already managed by parent
-+ */
-+	if (!tnode_get_map(node)) { /* check if the bitamp is not zero */
-+		if (tnode_get_parent(node))
-+			kfree(node);
-+		return 1;
-+	}
-+
-+ /*
-+ * all the clocks are marked succesfully _and_ there is at least
-+ * one clock marked.
-+ * Add the tnode to its parent! and return
-+ */
-+	if (tnode_get_parent(node))
-+		list_add_tail(&node->pnode, &tnode_get_parent(node)->childs);
-+
-+	return 0;
-+
-+err_0:
-+	pr_debug("Error on clock locking...\n");
-+	for (--i; i >= 0; --i)
-+		if (tnode_check_map_id(node, i))
-+			clk_clean_towner(tnode_get_clock(node, i));
-+
-+	if (tnode_get_parent(node))
-+		kfree(node);
-+
-+	return -EINVAL;
-+}
-+
-+/**
-+ * tnode_transaction_complete -
-+ *
-+ * checks the devices status when the transaction is complete.
-+ */
-+static void tnode_transaction_complete(struct clk_tnode *node)
-+{
-+	struct klist_iter i;
-+	struct pdev_clk_info *dev_info;
-+	int j;
-+
-+	pr_debug("tid: %d\n", (int)tnode_get_id(node));
-+	tnode_for_each_valid_events(node, j) {
-+	klist_iter_init(&tnode_get_clock(node, j)->devices, &i);
-+	while ((dev_info = next_dev_info(&i))) {
-+		/* update the device state */
-+		struct platform_device *dev = dev_info->pdev;
-+		switch (dev->clk_state & (DEV_SUSPENDED_ON_TRANSACTION |
-+					  DEV_RESUMED_ON_TRANSACTION)) {
-+		case 0: /* this device doesn't care on the clock transaction */
-+			atomic_clear_mask(DEV_ON_TRANSACTION,
-+				(atomic_t *)&dev->clk_state);
-+			break;
-+
-+		case (DEV_SUSPENDED_ON_TRANSACTION |
-+			DEV_RESUMED_ON_TRANSACTION):
-+			/* this device was suspended and
-+			 * resumed therefore no real change
-+			 */
-+			pr_debug("dev: %s.%d "
-+				"Suspended&Resumed (no child event)\n",
-+				dev->name, dev->id);
-+			atomic_clear_mask(DEV_ON_TRANSACTION |
-+					  DEV_SUSPENDED_ON_TRANSACTION |
-+					  DEV_RESUMED_ON_TRANSACTION,
-+					  (atomic_t *)&dev->clk_state);
-+			break;
-+		case DEV_SUSPENDED_ON_TRANSACTION:
-+			atomic_clear_mask(DEV_ON_TRANSACTION |
-+				DEV_SUSPENDED_ON_TRANSACTION,
-+				(atomic_t *)&dev->clk_state);
-+			pr_debug("dev: %s.%d Suspended\n",
-+				dev->name, dev->id);
-+			clk_pm_runtime_device(RPM_SUSPENDED, dev);
-+			break;
-+		case DEV_RESUMED_ON_TRANSACTION:
-+			atomic_clear_mask(DEV_ON_TRANSACTION |
-+				DEV_RESUMED_ON_TRANSACTION,
-+				(atomic_t *)&dev->clk_state);
-+			pr_debug("dev: %s.%d Resumed\n",
-+				dev->name, dev->id);
-+			clk_pm_runtime_device(RPM_ACTIVE, dev);
-+			break;
-+
-+		default:
-+			printk(KERN_ERR "%s: device %s,%d clk_flags _not_ valid %u\n",
-+				__func__, dev->name, dev->id,
-+				(unsigned int)dev->clk_state);
-+		}
-+	}
-+	klist_iter_exit(&i);
-+	clk_clean_towner(tnode_get_clock(node, j));
-+	}
-+	pr_debug("tid: %d exit\n", (int)tnode_get_id(node));
-+	return;
-+}
-+
-+/*
-+ * Check if the clk is registered
-+ */
-+#ifdef CLK_SAFE_CODE
-+static struct clk *check_clk(struct clk *clk)
-+{
-+	struct clk *clkp;
-+	struct clk *result = NULL;
-+	struct klist_iter i;
-+
-+	pr_debug("\n");
-+
-+	klist_iter_init(&clk_list, &i);
-+	while ((clkp = next_clock(&i)))
-+		if (clk == clkp) {
-+			result = clk;
-+			break;
-+		}
-+	klist_iter_exit(&i);
-+	return result;
-+}
-+#else
-+static inline struct clk *check_clk(struct clk *clk)
-+{
-+	return clk;
-+}
-+#endif
-+
-+enum child_event_e {
-+	CHILD_CLOCK_ENABLED = 1,
-+	CHILD_CLOCK_DISABLED,
-+	CHILD_DEVICE_ENABLED,
-+	CHILD_DEVICE_DISABLED,
-+};
-+
-+static int
-+clk_notify_child_event(enum child_event_e const code, struct clk *clk)
-+{
-+	if (!clk)
-+		return 0;
-+
-+	switch (code) {
-+	case CHILD_CLOCK_ENABLED:
-+		++clk->nr_active_clocks;
-+		break;
-+	case CHILD_CLOCK_DISABLED:
-+		--clk->nr_active_clocks;
-+		break;
-+	case CHILD_DEVICE_ENABLED:
-+		++clk->nr_active_devices;
-+		break;
-+	case CHILD_DEVICE_DISABLED:
-+		--clk->nr_active_devices;
-+		break;
-+	}
-+
-+	if (clk_is_auto_switching(clk)) {
-+		/*
-+		 * Check if there are still users
-+		 */
-+		if (!clk->nr_active_devices && !clk->nr_active_clocks)
-+			clk_disable(clk);
-+		else if (!clk_get_rate(clk)) /* if off.. turn-on */
-+			clk_enable(clk);
-+	}
-+
-+	return 0;
-+}
-+
-+/**
-+ * clk_dev_events_malloc -
-+ *
-+ * builds a struct clk_event array (dev_event).
-+ * the array size (how many elements) is based on device_num_clocks(dev)
-+ * the contenets of each element is equal to:
-+ * - the events array (if the idx-clock is under transaction)
-+ * - the current clock setting if the idx-clock isn't under transaction
-+ */
-+static struct clk_event * __must_check
-+clk_dev_events_malloc(struct platform_device const *dev)
-+{
-+	struct clk_event *dev_events;
-+	struct clk_tnode *node;
-+	int i, j;
-+	pr_debug("\n");
-+/*
-+ * 1.  simple case:
-+ *	- device_num_clocks(dev) = 1
-+ */
-+	if (pdevice_num_clocks(dev) == 1) {
-+		node = (struct clk_tnode *)pdevice_clock(dev, 0)->towner;
-+		for (i = 0; i < tnode_get_size(node); ++i)
-+			if (tnode_get_clock(node, i) == pdevice_clock(dev, 0))
-+				return tnode_get_event(node, i);
-+	}
-+/*
-+ * 2. - device_num_clocks(dev) > 1
-+ *	GCF has to build a dedicated device events (devents) array
-+ *	for this device! sorted as the device registered it-self!
-+ */
-+	dev_events = kmalloc(sizeof(*dev_events) * pdevice_num_clocks(dev),
-+			GFP_KERNEL);
-+	if (!dev_events)
-+		return NULL;
-+
-+	for (i = 0; i < pdevice_num_clocks(dev); ++i) {
-+		node = (struct clk_tnode *)pdevice_clock(dev, i)->towner;
-+		dev_events[i].clk = pdevice_clock(dev, i);
-+		if (!node) {/* this means this clocs isn't under transaction */
-+		     dev_events[i].old_rate =
-+				clk_get_rate(pdevice_clock(dev, i));
-+		     dev_events[i].new_rate =
-+				clk_get_rate(pdevice_clock(dev, i));
-+		     continue;
-+		}
-+		/* search the right clk_event */
-+		for (j = 0; tnode_get_clock(node, j) != pdevice_clock(dev, i);
-+		     ++j);
-+
-+		dev_events[i].old_rate = tnode_get_event(node, j)->old_rate;
-+		dev_events[i].new_rate = tnode_get_event(node, j)->new_rate;
-+	}
-+	return dev_events;
-+}
-+
-+/**
-+ * clk_devents_free -
-+ * free the devent allocated on the device dev.
-+ */
-+static inline void
-+clk_dev_events_free(struct clk_event *dev_events, struct platform_device *dev)
-+{
-+	if (pdevice_num_clocks(dev) == 1)
-+		return ;
-+	kfree(dev_events);
-+}
-+
-+/**
-+ * clk_trnsc_fsm -
-+ *
-+ * propagate the transaction to all the childs
-+ * each transaction has the following life-time:
-+ *
-+ *	+---------------+
-+ *	|    ENTER_CLK	|   The ENTER state only for clocks
-+ *	+---------------+     - acquires all the clock of the transaction
-+ *		|	       - builds the transaction graph
-+ *		|	      - for each clock generates a child transaction
-+ *		|
-+ *   +---------------------+
-+ *   |	+---------------+  |
-+ *   |	|    ENTER_DEV 	|  |  The ENTER state only for devices
-+ *   |  +---------------+  |  - >> NOTIFY_CLK_ENTERCHANGE << notified
-+ *   |		|	   |  - - the device could refuse the operation
-+ *   |		|	   |
-+ *   |	+---------------+  |
-+ *   |	|    PRE_DEV	|  |  The PRE state only devices
-+ *   |	+---------------+  |  - >> NOTIFY_CLK_PRECHANGE << notified
-+ *   |		|	   |  - - the device could be suspended
-+ *   +---------------------+
-+ *		|
-+ *	+---------------+
-+ * 	|   CHANGE_CLK	|    The CHANGE state only for clocks
-+ *	+---------------+     - updates all the physical clocks
-+ *		|	        and relative clk_event_s according to
-+ *		|	        the hw value.
-+ *   +---------------------+
-+ *   |		|	   |
-+ *   |	+---------------+  |
-+ *   |	|   POST_DEV	|  |  The POST state only for devices
-+ *   |  +---------------+  |  - >> NOTIFY_CLK_POSTCHANGE << notified
-+ *   |		|	   |  - - the devices could be resumed
-+ *   |		|	   |
-+ *   |	+---------------+  |
-+ *   |	|  EXIT_DEV	|  |   The EXIT state only for devices
-+ *   |  +---------------+  |   - >> NOTIFY_CLK_EXITCHANGE << notified
-+ *   |		|	   |   - - the devices is aware all the other
-+ *   +---------------------+	   devices are resumed.
-+ *		|
-+ *	+---------------+
-+ *	|  EXIT_CLK	|      The EXIT state only for clocks
-+ *	+---------------+      (to free all the memory)
-+ *				- Free all the allocated memory
-+ *
-+ */
-+
-+static enum notify_ret_e
-+clk_trnsc_fsm(enum clk_fsm_e const code, struct clk_tnode *node)
-+{
-+	struct pdev_clk_info *dev_info;
-+	struct clk_tnode *tchild;
-+	struct klist_iter i;
-+	int j;
-+	enum notify_ret_e tmp, ret_notifier = NOTIFY_EVENT_HANDLED;
-+
-+#ifdef CONFIG_CLK_DEBUG
-+	switch (code) {
-+	case TRNSC_ENTER_CLOCK:
-+	case TRNSC_ENTER_DEVICE:
-+		printk(KERN_INFO "ENTER_%s ",
-+			(code == TRNSC_ENTER_CLOCK ? "CLK" : "DEV"));
-+		break;
-+	case TRNSC_PRE_DEVICE:
-+		printk(KERN_INFO "PRE_DEV ");
-+		break;
-+	case TRNSC_CHANGE_CLOCK:
-+		printk(KERN_INFO "CHANGE_CLK ");
-+		break;
-+	case TRNSC_POST_DEVICE:
-+		printk(KERN_INFO "POST_DEV ");
-+		break;
-+	case TRNSC_EXIT_DEVICE:
-+	case TRNSC_EXIT_CLOCK:
-+		printk(KERN_INFO "EXIT_%s ",
-+			(code == TRNSC_EXIT_DEVICE ? "DEV" : "CLK"));
-+			break;
-+	}
-+	printk(KERN_INFO"tid:%u ", (unsigned int)tnode_get_id(node));
-+	if (tnode_get_parent(node))
-+		printk(KERN_INFO " (tpid: %d)",
-+			(int)tnode_get_id(tnode_get_parent(node)));
-+	printk(KERN_INFO " (0x%x/0x%x) ", (unsigned int)tnode_get_size(node),
-+			(unsigned int)tnode_get_map(node));
-+	for (j = 0; j < tnode_get_size(node); ++j) {
-+		if (tnode_check_map_id(node, j))
-+			/* print only the valid event... */
-+			printk(KERN_INFO"- %s ",
-+				tnode_get_clock(node, j)->name);
-+		else if (code == TRNSC_ENTER_CLOCK)
-+			printk(KERN_INFO"- %s ",
-+				tnode_get_clock(node, j)->name);
-+	}
-+	printk(KERN_INFO"\n");
-+#endif
-+
-+	/* 
-+	 * Clk ENTER state
-+	 */
-+	if (code == TRNSC_ENTER_CLOCK) {
-+		unsigned long idx;
-+		enum clk_event_e sub_code;
-+		struct clk *clkp;
-+		struct clk_event *sub_event = NULL;
-+
-+		/* first of all the GCF tries to lock the clock of this tnode
-+		 * and links the tnode to its parent (if any)
-+		 */
-+		switch (tnode_lock_clocks(node)) {
-+		case 0:
-+			break;
-+		case -EINVAL:
-+			return NOTIFY_EVENT_NOTHANDLED;
-+		case 1:
-+			return NOTIFY_EVENT_HANDLED;
-+		}
-+
-+		pr_debug("clocks acquired\n");
-+		/* Propagates the events to the sub clks */
-+		tnode_for_each_valid_events(node, j) {
-+
-+		if (!clk_allow_propagation(tnode_get_clock(node, j))) {
-+			pr_debug("clk: %s doesn't want propagation\n",
-+				tnode_get_clock(node, j)->name);
-+			continue;
-+		}
-+		if (!(tnode_get_clock(node, j)->nr_clocks))
-+			continue;
-+
-+		tchild = tnode_malloc(node,
-+			tnode_get_clock(node, j)->nr_clocks);
-+		if (!tchild) {
-+			printk(KERN_ERR "No enough memory during a clk "
-+					"transaction\n");
-+			ret_notifier |= NOTIFY_EVENT_NOTHANDLED;;
-+			return ret_notifier;
-+		}
-+
-+		pr_debug("memory for child transaction acquired\n");
-+		idx = 0;
-+		sub_code = clk_event_decode(tnode_get_event(node, j));
-+		klist_iter_init(&tnode_get_clock(node, j)->childs, &i);
-+		while ((clkp = next_child_clock(&i))) {
-+			sub_event = tnode_get_event(tchild, idx);
-+			clk_event_init(sub_event, clkp, clk_get_rate(clkp),
-+				clk_get_rate(clkp));
-+			switch (sub_code) {/* prepare the sub event fields */
-+			case _CLK_CHANGE:
-+			case _CLK_ENABLE:
-+				sub_event->new_rate = clk_evaluate_rate(clkp,
-+					tnode_get_event(node, j)->new_rate);
-+				break;
-+			case _CLK_DISABLE:
-+				sub_event->new_rate = 0;
-+				break;
-+			case _CLK_NOCHANGE:
-+				break;
-+			}
-+			++idx;
-+			}
-+		klist_iter_exit(&i);
-+		/* now GCF can araiese the sub transaction */
-+		ret_notifier |=
-+			clk_trnsc_fsm(code, tchild);
-+		}
-+		return ret_notifier;
-+	}
-+
-+	/*
-+	 * Clk CHANGE state
-+	 */
-+	if (code == TRNSC_CHANGE_CLOCK) {
-+		/* the clocks on the root node are managed directly in the
-+		 * clk_set_rate/clk_enable/... functions ...
-+		 * while all the other clocks have to managed here!
-+		 */
-+		if (node->parent)
-+			tnode_for_each_valid_events(node, j) {
-+				struct clk_event *event;
-+				long code;
-+				event = tnode_get_event(node, j);
-+				code = clk_event_decode(event);
-+				switch (code) {
-+				case _CLK_CHANGE:
-+					__clk_recalc_rate(event->clk);
-+					event->new_rate =
-+						clk_get_rate(event->clk);
-+					break;
-+				case _CLK_ENABLE:
-+					if (clk_follow_parent(event->clk)) {
-+						__clk_enable(event->clk);
-+						event->new_rate =
-+						clk_get_rate(event->clk);
-+					}
-+					break;
-+				case _CLK_DISABLE:
-+					if (clk_is_enabled(event->clk))
-+						__clk_disable(event->clk);
-+					break;
-+				}
-+			}
-+
-+		list_for_each_entry(tchild, &node->childs, pnode)
-+			ret_notifier |= clk_trnsc_fsm(code, tchild);
-+
-+		return ret_notifier;
-+	}
-+
-+	/*
-+	 * Clk EXIT state
-+	 */
-+	if (code == TRNSC_EXIT_CLOCK) {
-+		struct list_head *ptr, *next;
-+		/* scans all the transaction childs */
-+		list_for_each_safe(ptr, next, &node->childs)
-+			clk_trnsc_fsm(code, to_tnode(ptr));
-+
-+		/* update the devices/clocks state */
-+		tnode_transaction_complete(node);
-+
-+		tnode_free(node);
-+		pr_debug("EXIT_CLK complete\n");
-+
-+		return ret_notifier;
-+	}
-+
-+	/*
-+	 * Here the devices management
-+	 */
-+	tnode_for_each_valid_events(node, j) {
-+		if (!clk_allow_propagation(tnode_get_clock(node, j)))
-+			continue;
-+	klist_iter_init(&tnode_get_clock(node, j)->devices, &i);
-+	while ((dev_info = next_dev_info(&i))) {
-+		struct platform_device *pdev = dev_info->pdev;
-+		struct platform_driver *pdrv = 	container_of(
-+			pdev->dev.driver, struct platform_driver, driver);
-+
-+		struct clk_event *dev_events;
-+
-+		if (!pdrv || !pdrv->notify) {
-+			pr_debug(
-+			"device %s.%d registered with no notify function\n",
-+				pdev->name, pdev->id);
-+			continue;
-+		}
-+		/* check if it already had a 'code' event */
-+		if (pdev_transaction_move_on(pdev, code))
-+			continue;
-+
-+		dev_events = clk_dev_events_malloc(pdev);
-+		if (!dev_events) {
-+			printk(KERN_ERR"%s: No Memory during a clk "
-+				"transaction\n", __func__);
-+			continue;
-+		}
-+
-+		/* GCF can use 'code' directly in the .notify function
-+		 * just because external 'NOTIFY_CLK_xxxCHANGE' code
-+		 * matchs with the internal 'device' code
-+		 */
-+		tmp = pdrv->notify(code, pdev, dev_events);
-+		clk_dev_events_free(dev_events, pdev);
-+		ret_notifier |= tmp;
-+#ifdef CONFIG_PM_RUNTIME
-+		if (code == TRNSC_PRE_DEVICE && tmp == NOTIFY_EVENT_HANDLED) {
-+			printk(KERN_INFO "clk %s on code %u suspends "
-+				"device %s.%d\n",
-+				transaction_get_clock(node, j)->name,
-+				(unsigned int)code, pdev->name, pdev->id);
-+			pm_runtime_suspend(&pdev->dev);
-+		} else
-+		if (code == TRNSC_POST_DEVICE && tmp == NOTIFY_EVENT_HANDLED) {
-+			printk(KERN_INFO "clk %s on code %u resumes "
-+				"device %s.%d\n",
-+				transaction_get_clock(node, j)->name,
-+				(unsigned int)code, pdev->name, pdev->id);
-+			pm_runtime_resume(&pdev->dev);
-+		};
-+#endif
-+	} /* while closed */
-+	klist_iter_exit(&i);
-+	} /* for closed */
-+
-+	/*
-+	 *and propagate down...
-+	 */
-+	list_for_each_entry(tchild, &node->childs, pnode)
-+			ret_notifier |= clk_trnsc_fsm(code, tchild);
-+
-+	return ret_notifier;
-+}
-+
-+static void clk_initialize(struct clk *clk)
-+{
-+	kobject_init(&clk->kobj, &ktype_clk);
-+	kobject_set_name(&clk->kobj, "%s", clk->name);
-+	kobject_get(&clk->kobj);
-+
-+	clk->nr_clocks = 0;
-+	clk->nr_active_clocks = 0;
-+	clk->nr_active_devices = 0;
-+	clk->towner = NULL;
-+
-+	klist_init(&clk->childs, klist_get_child, klist_put_child);
-+	klist_init(&clk->devices, klist_get_device, klist_put_device);
-+
-+}
-+
-+/**
-+  * clk_register -
-+  *
-+  * registers a new clk in the system.
-+  * returns zero if success
-+  */
-+int clk_register(struct clk *clk)
-+{
-+	int ret = 0;
-+	if (!clk)
-+		return -EFAULT;
-+	pr_debug("%s\n", clk->name);
-+
-+	clk_initialize(clk);
-+
-+	/* Initialize ... */
-+	__clk_init(clk);
-+
-+	if (clk->parent) {
-+#ifdef CLK_SAFE_CODE
-+		/* 1. the parent has to be registered */
-+		if (!check_clk(clk->parent))
-+			return -ENODEV;
-+		/* 2. an always enabled child has to sit on a always
-+		 *    enabled parent!
-+		 */
-+		if (clk->flags & CLK_ALWAYS_ENABLED &&
-+			!(clk->parent->flags & CLK_ALWAYS_ENABLED))
-+			return -EFAULT;
-+		/* 3. a fixed child has to sit on a fixed parent */
-+		if (clk_is_readonly(clk) && !clk_is_readonly(clk->parent))
-+			return -EFAULT;
-+#endif
-+		klist_add_tail(&clk->child_node, &clk->parent->childs);
-+		clk->parent->nr_clocks++;
-+	}
-+
-+	ret = kobject_add(&clk->kobj,
-+		(clk->parent ? &clk->parent->kobj : clk_kobj), clk->name);
-+	if (ret)
-+		goto err_0;
-+
-+	clk->kdevices =	kobject_create_and_add("devices", &clk->kobj);
-+	if (!clk->kdevices)
-+		goto err_1;
-+
-+	klist_add_tail(&clk->node, &clk_list);
-+	if (clk->flags & CLK_ALWAYS_ENABLED) {
-+		__clk_enable(clk);
-+		clk_notify_child_event(CHILD_CLOCK_ENABLED, clk->parent);
-+	}
-+	return ret;
-+
-+err_1:
-+	/* subsystem_remove_file... removed in the common code... ??? */
-+	kobject_del(&clk->kobj);
-+err_0:
-+	return ret;
-+}
-+EXPORT_SYMBOL(clk_register);
-+
-+/**
-+  * clk_unregister -
-+  * unregisters the clock from system
-+  */
-+int clk_unregister(struct clk *clk)
-+{
-+	pr_debug("\n");
-+
-+	if (!clk)
-+		return -EFAULT;
-+
-+	if (!list_empty(&clk->devices.k_list))
-+		return -EFAULT; /* somebody is still using this clock */
-+
-+	kobject_del(clk->kdevices);
-+	kfree(clk->kdevices);
-+	/* subsystem_remove_file... removed in the common code... ??? */
-+	kobject_del(&clk->kobj);
-+	klist_del(&clk->node);
-+	if (clk->parent) {
-+		klist_del(&clk->child_node);
-+		clk->parent->nr_clocks--;
-+	}
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL(clk_unregister);
-+
-+static int clk_add_devinfo(struct pdev_clk_info *info)
-+{
-+	int ret = 0;
-+	pr_debug("\n");
-+
-+#ifdef CLK_SAFE_CODE
-+	if (!info || !info->clk || !check_clk(info->clk))
-+		return -EFAULT;
-+#endif
-+	ret = sysfs_create_link(info->clk->kdevices, &info->pdev->dev.kobj,
-+		dev_name(&info->pdev->dev));
-+	if (ret) {
-+		pr_debug(" Error %d\n", ret);
-+		return ret;
-+	}
-+	klist_add_tail(&info->node, &info->clk->devices);
-+
-+	return 0;
-+}
-+
-+static int clk_del_devinfo(struct pdev_clk_info *info)
-+{
-+	pr_debug("\n");
-+
-+#ifdef CLK_SAFE_CODE
-+	if (!info || !info->clk || !check_clk(info->clk))
-+		return -EFAULT;
-+#endif
-+	sysfs_remove_link(info->clk->kdevices, dev_name(&info->pdev->dev));
-+	klist_del(&info->node);
-+
-+#ifndef CONFIG_PM_RUNTIME
-+	/*
-+	 * Without PM_RUNTIME the GCF assumes the device is
-+	 * 'not active' when it's removed
-+	 */
-+	clk_notify_child_event(CHILD_DEVICE_DISABLED, info->clk);
-+#endif
-+	return 0;
-+}
-+
-+int clk_probe_device(struct platform_device *dev, enum pdev_probe_state state)
-+{
-+	int idx;
-+	switch (state) {
-+	case PDEV_PROBEING:
-+		/* before the .probe function is called the GCF
-+		 * has to turn-on _all_ the clocks the device uses
-+		 * to garantee a safe .probe
-+		 */
-+		for (idx = 0; idx < pdevice_num_clocks(dev); ++idx)
-+			if (pdevice_clock(dev, idx))
-+				clk_enable(pdevice_clock(dev, idx));
-+		return 0;
-+	case PDEV_PROBED:
-+#ifdef CONFIG_PM_RUNTIME
-+	/*
-+	 * Here the GCF should check the device's pm_runtime state
-+	 * And if the device is suspended the clk_frmwk can turn-off the clocks
-+	 */
-+#else
-+	/*
-+	 * Without PM_RUNTIME the GCF assumes the device is active
-+	 */
-+	for (idx = 0; idx < pdevice_num_clocks(dev); ++idx)
-+		clk_notify_child_event(CHILD_DEVICE_ENABLED,
-+			pdevice_clock(dev, idx));
-+#endif
-+	break;
-+	case PDEV_PROBE_FAILED:
-+	/*
-+	 * TO DO something...
-+	 */
-+		break;
-+	}
-+	return 0;
-+}
-+
-+int clk_add_device(struct platform_device *dev, enum pdev_add_state state)
-+{
-+	int idx;
-+	int ret;
-+
-+	if (!dev)
-+		return -EFAULT;
-+
-+	switch (state) {
-+	case PDEV_ADDING:
-+	case PDEV_ADD_FAILED:
-+		/*
-+		 * TO DO something
-+		 */
-+		return 0;
-+	case PDEV_ADDED:
-+		break;
-+	}
-+	/* case PDEV_ADDED ... */
-+	if (!dev->clks || !pdevice_num_clocks(dev))
-+		return 0;	/* this device will not use
-+				   the clk framework */
-+
-+	pr_debug("%s.%d with %u clocks\n", dev->name, dev->id,
-+		(unsigned int)pdevice_num_clocks(dev));
-+
-+	dev->clk_state = 0;
-+	for (idx = 0; idx < pdevice_num_clocks(dev); ++idx) {
-+		if (!pdevice_clock(dev, idx)) {	/* clk can not be NULL... */
-+			pr_debug("Error clock NULL\n");
-+			continue;
-+		}
-+		pr_debug("->under %s\n", dev->clks[idx].clk->name);
-+		dev->clks[idx].pdev = dev;
-+		ret = clk_add_devinfo(&dev->clks[idx]);
-+		if (ret)
-+			goto err_0;
-+	}
-+
-+	return 0;
-+err_0:
-+	for (--idx; idx >= 0; --idx)
-+		clk_del_devinfo(&dev->clks[idx]);
-+
-+	return -EINVAL;
-+}
-+
-+int clk_del_device(struct platform_device *dev)
-+{
-+	int idx;
-+	if (!dev)
-+		return -EFAULT;
-+
-+	for (idx = 0; idx < pdevice_num_clocks(dev); ++idx)
-+		clk_del_devinfo(&dev->clks[idx]);
-+
-+	return 0;
-+}
-+
-+void clk_put(struct clk *clk)
-+{
-+	if (clk && !IS_ERR(clk))
-+		kobject_put(&clk->kobj);
-+}
-+
-+static int clk_is_parent(struct clk const *child, struct clk const *parent)
-+{
-+	if (!child || !parent)
-+		return 0;
-+	if (!child->parent)
-+		return 0;
-+	if (child->parent == parent)
-+		return 1;
-+	else
-+		return clk_is_parent(child->parent, parent);
-+}
-+
-+int clk_enable(struct clk *clk)
-+{
-+	int ret;
-+	struct clk_tnode transaction;
-+	struct clk_event event;
-+
-+	event = EVENT(clk, 0, CLK_UNDEFINED_RATE);
-+	transaction = TRANSACTION_ROOT(1, &event);
-+
-+	pr_debug("%s\n", clk->name);
-+
-+
-+	if (clk->flags & CLK_ALWAYS_ENABLED || clk_is_enabled(clk))
-+		return 0;
-+
-+	if (clk->parent) {
-+		/* turn-on the parent if the parent is 'auto_switch' */
-+		clk_notify_child_event(CHILD_CLOCK_ENABLED, clk->parent);
-+
-+		if (!clk_is_enabled(clk->parent)) {
-+			/* the parent is still disabled... */
-+			clk_notify_child_event(CHILD_CLOCK_DISABLED,
-+				clk->parent);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);
-+	if (ret) {
-+		ret = -EPERM;
-+		goto err_0;
-+	}
-+
-+	/* if not zero somebody doens't agree the clock update */
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);
-+	if (ret) {
-+		ret = -EPERM;
-+		goto err_1;
-+		}
-+
-+	clk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);
-+
-+	ret = __clk_enable(clk);
-+
-+	event.new_rate = clk_get_rate(clk);
-+
-+	clk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);
-+
-+	clk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);
-+
-+err_1:
-+	clk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);
-+
-+err_0:
-+	clk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);
-+
-+	if (ret)
-+		clk_notify_child_event(CHILD_CLOCK_DISABLED, clk->parent);
-+
-+	return ret;
-+}
-+EXPORT_SYMBOL(clk_enable);
-+
-+/**
-+ * clk_disable -
-+ * disables the clock
-+ * Is isn't really good that it's a 'void' function...
-+ * but this is common interface
-+ */
-+void clk_disable(struct clk *clk)
-+{
-+	struct clk_tnode transaction;
-+	struct clk_event event;
-+	int ret;
-+
-+	event = EVENT(clk, clk_get_rate(clk), 0);
-+	transaction = TRANSACTION_ROOT(1, &event);
-+
-+	pr_debug("\n");
-+
-+	if (clk->flags & CLK_ALWAYS_ENABLED || !clk_is_enabled(clk))
-+		return;
-+
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);
-+	if (ret)
-+		goto err_0;
-+
-+	/* if not zero somebody doens't agree the clock update */
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);
-+	if (ret)
-+		goto err_1;
-+
-+	clk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);
-+
-+	__clk_disable(clk);
-+
-+	clk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);
-+
-+	clk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);
-+
-+err_0:
-+	clk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);
-+err_1:
-+	clk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);
-+
-+	clk_notify_child_event(CHILD_CLOCK_DISABLED, clk->parent);
-+
-+	return ;
-+}
-+EXPORT_SYMBOL(clk_disable);
-+
-+unsigned long clk_get_rate(struct clk *clk)
-+{
-+	return clk->rate;
-+}
-+EXPORT_SYMBOL(clk_get_rate);
-+
-+struct clk *clk_get_parent(struct clk *clk)
-+{
-+	return clk->parent;
-+}
-+EXPORT_SYMBOL(clk_get_parent);
-+
-+int clk_set_parent(struct clk *clk, struct clk *parent)
-+{
-+	int ret = -EOPNOTSUPP;
-+	struct clk *old_parent = clk->parent;
-+	struct clk_event event;
-+	struct clk_tnode transaction;
-+	int clk_was_enabled = clk_is_enabled(clk);
-+
-+	event = EVENT(clk, clk_get_rate(clk), CLK_UNDEFINED_RATE);
-+	transaction = TRANSACTION_ROOT(1, &event);
-+
-+	if (!clk || !parent)
-+		return -EINVAL;
-+
-+	if (clk->parent == parent)
-+		return 0;
-+
-+	pr_debug("\n");
-+
-+	if (clk_was_enabled && !clk_is_enabled(parent))
-+		/* turn-on parent if possible */
-+		clk_notify_child_event(CHILD_CLOCK_ENABLED, parent);
-+
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);
-+	if (ret) {
-+		ret = -EPERM;
-+		goto err_0;
-+	}
-+
-+	/* if not zero somebody doens't agree the clock updated */
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);
-+	if (ret) {
-+		ret = -EPERM;
-+		goto err_1;
-+	}
-+
-+	clk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);
-+
-+	/* Now we updated the hw */
-+	ret = __clk_set_parent(clk, parent);
-+	if (ret) {
-+		/* there was a problem...
-+		 * therefore clk is still on the old parent
-+		 */
-+		clk->parent = old_parent; /* to be safe ! */
-+		goto err_2;
-+	}
-+
-+	klist_del(&clk->child_node);
-+
-+	clk->parent = parent;
-+
-+	ret = kobject_move(&clk->kobj, &clk->parent->kobj);
-+	if (ret)
-+		;
-+
-+	klist_add_tail(&clk->child_node, &clk->parent->childs);
-+
-+	clk->parent->nr_clocks++;
-+	old_parent->nr_clocks--;
-+
-+err_2:
-+	event.new_rate = clk_get_rate(clk);
-+
-+	clk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);
-+
-+	clk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);
-+
-+err_1:
-+	clk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);
-+err_0:
-+	clk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);
-+
-+	if (clk_was_enabled && !ret) {
-+		/* 5. to decrease the old_parent nchild counter */
-+		clk_notify_child_event(CHILD_CLOCK_DISABLED, old_parent);
-+		/* 5. increase the new_parent nchild counter */
-+		clk_notify_child_event(CHILD_CLOCK_ENABLED, clk->parent);
-+		/* 6. to decrease the old_parent nchild counter */
-+		clk_notify_child_event(CHILD_CLOCK_DISABLED, old_parent);
-+		}
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL(clk_set_parent);
-+
-+int clk_set_rate(struct clk *clk, unsigned long rate)
-+{
-+	int ret = -EOPNOTSUPP;
-+	struct clk_event event;
-+	struct clk_tnode transaction;
-+
-+	event = EVENT(clk, clk_get_rate(clk), clk_round_rate(clk, rate));
-+	transaction = TRANSACTION_ROOT(1, &event);
-+
-+	pr_debug("\n");
-+
-+	if (clk_is_readonly(clk))
-+		/* read only clock doesn't have to be "touched" !!!! */
-+		return -EPERM;
-+
-+	if (event.new_rate == clk_get_rate(clk))
-+		return 0;
-+
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);
-+	if (ret) {
-+		ret = -EPERM;
-+		goto err_0;
-+	}
-+
-+	/* if not zero somebody doens't agree the clock updated */
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);
-+	if (ret) {
-+		ret = -EPERM;
-+		goto err_1;
-+	}
-+
-+	clk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);
-+
-+	__clk_set_rate(clk, event.new_rate);
-+	/* reload new_rate to avoid hw rounding... */
-+	event.new_rate = clk_get_rate(clk);
-+
-+	clk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);
-+	clk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);
-+
-+err_1:
-+	clk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);
-+err_0:
-+	clk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);
-+
-+	return ret;
-+}
-+EXPORT_SYMBOL(clk_set_rate);
-+
-+long clk_round_rate(struct clk *clk, unsigned long rate)
-+{
-+	pr_debug("\n");
-+
-+	if (likely(clk->ops && clk->ops->round))
-+		return clk->ops->round(clk, rate);
-+	return rate;
-+}
-+EXPORT_SYMBOL(clk_round_rate);
-+
-+unsigned long clk_evaluate_rate(struct clk *clk, unsigned long prate)
-+{
-+	pr_debug("\n");
-+	if (!clk->parent)/* without parent this function has no meaning */
-+		return CLK_UNDEFINED_RATE;
-+
-+	if (!prate)/* on parent disabled than disable the child */
-+		return 0;
-+
-+	if (likely(clk->ops && clk->ops->eval))
-+		return clk->ops->eval(clk, prate);
-+
-+	return CLK_UNDEFINED_RATE;
-+}
-+EXPORT_SYMBOL(clk_evaluate_rate);
-+
-+int clk_set_rates(struct clk **clks, unsigned long *rates, unsigned long nclks)
-+{
-+	int i, ret = 0;
-+	struct clk_event *evt;
-+	struct clk_tnode transaction = TRANSACTION_ROOT(nclks, NULL)
-+
-+	pr_debug("\n");
-+
-+	if (!clks || !rates || !nclks)
-+		return -EINVAL;
-+	evt = kmalloc(sizeof(*evt) *
-+		tnode_get_size(&transaction), GFP_KERNEL);
-+
-+	if (!evt)
-+		return -ENOMEM;
-+
-+	tnode_set_events(&transaction, evt);
-+
-+	for (i = 0; i < tnode_get_size(&transaction); ++i) {
-+		tnode_set_clock(&transaction, i, clks[i]);
-+		tnode_get_event(&transaction, i)->old_rate =
-+			clk_get_rate(clks[i]);
-+		tnode_get_event(&transaction, i)->new_rate =
-+			clk_round_rate(clks[i], rates[i]);
-+	}
-+
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);
-+	if (ret) {
-+		ret = -EPERM;
-+		goto err_0;
-+	}
-+
-+	/* if not zero somebody doens't agree the clock updated */
-+	ret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);
-+	if (ret) {
-+		ret = -EPERM;
-+		goto err_1;
-+	}
-+
-+	clk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);
-+
-+	for (i = 0; i < tnode_get_size(&transaction); ++i) {
-+		if (!clk_is_enabled(clks[i]) && rates[i])
-+			ret |= __clk_enable(clks[i]);
-+		else if (clk_is_enabled(clks[i]) && !rates[i])
-+			ret |= __clk_disable(clks[i]);
-+		else
-+			ret |= __clk_set_rate(clks[i], rates[i]);
-+
-+		/* reload new_rate to avoid hw rounding... */
-+		tnode_get_event(&transaction, i)->new_rate =
-+			clk_get_rate(clks[i]);
-+	}
-+
-+	clk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);
-+
-+	clk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);
-+
-+err_1:
-+	clk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);
-+
-+err_0:
-+	clk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);
-+
-+	kfree(evt);
-+	return ret;
-+}
-+EXPORT_SYMBOL(clk_set_rates);
-+
-+struct clk *clk_get(struct device *dev, const char *id)
-+{
-+	struct clk *clk = NULL;
-+	struct clk *clkp;
-+	struct klist_iter i;
-+	int found = 0, idno;
-+
-+	mutex_lock(&clk_list_sem);
-+#if 0
-+	if (dev == NULL || dev->bus != &platform_bus_type)
-+		idno = -1;
-+	else
-+		idno = to_platform_device(dev)->id;
-+
-+	klist_iter_init(&clk_list, &i);
-+	while ((clkp = next_clock(&i)) && !found)
-+		if (clk->id == idno && strcmp(id, clk->name) == 0 &&
-+			try_module_get(clk->owner)) {
-+				clk = clkp;
-+				found = 1;
-+		}
-+	klist_iter_exit(&i);
-+
-+	if (found)
-+		goto _found;
-+#endif
-+	klist_iter_init(&clk_list, &i);
-+	while ((clkp = next_clock(&i)))
-+		if (strcmp(id, clkp->name) == 0
-+		    && try_module_get(clkp->owner)) {
-+			clk = clkp;
-+			break;
-+		}
-+	klist_iter_exit(&i);
-+_found:
-+	mutex_unlock(&clk_list_sem);
-+	return clk;
-+}
-+EXPORT_SYMBOL(clk_get);
-+
-+int clk_for_each(int (*fn) (struct clk *clk, void *data), void *data)
-+{
-+	struct clk *clkp;
-+	struct klist_iter i;
-+	int result = 0;
-+
-+	if (!fn)
-+		return -EFAULT;
-+
-+	pr_debug("\n");
-+	mutex_lock(&clk_list_sem);
-+	klist_iter_init(&clk_list, &i);
-+
-+	while ((clkp = next_clock(&i)))
-+		result |= fn(clkp, data);
-+
-+	klist_iter_exit(&i);
-+	mutex_unlock(&clk_list_sem);
-+	return result;
-+}
-+EXPORT_SYMBOL(clk_for_each);
-+
-+int clk_for_each_child(struct clk *clk,
-+	int (*fn) (struct clk *clk, void *data), void *data)
-+{
-+	struct clk *clkp;
-+	struct klist_iter i;
-+	int result = 0;
-+
-+	if (!clk || !fn)
-+		return -EFAULT;
-+
-+	klist_iter_init(&clk->childs, &i);
-+
-+	while ((clkp = next_child_clock(&i)))
-+		result |= fn(clkp, data);
-+
-+	klist_iter_exit(&i);
-+
-+	return result;
-+}
-+EXPORT_SYMBOL(clk_for_each_child);
-+
-+static int __init early_clk_complete(struct clk *clk, void *data)
-+{
-+	int ret;
-+
-+	ret = kobject_add(&clk->kobj,
-+		(clk->parent ? &clk->parent->kobj : clk_kobj),
-+		clk->name);
-+	if (ret)
-+		return ret;
-+
-+	clk->kdevices = kobject_create_and_add("devices", &clk->kobj);
-+	if (!clk->kdevices)
-+		return -EINVAL;
-+
-+	return 0;
-+}
-+
-+int __init early_clk_register(struct clk *clk)
-+{
-+	int retval = 0;
-+	if (!clk)
-+		return -EFAULT;
-+	pr_debug("%s\n", clk->name);
-+
-+	clk_initialize(clk);
-+
-+	/* Initialize ... */
-+	__clk_init(clk);
-+
-+	if (clk->parent) {
-+#ifdef CLK_SAFE_CODE
-+		/* 1. the parent has to be registered */
-+		if (!check_clk(clk->parent))
-+			return -ENODEV;
-+		/* 2. an always enabled child has to sit on a always
-+		 *    enabled parent!
-+		 */
-+		if (clk->flags & CLK_ALWAYS_ENABLED &&
-+			!(clk->parent->flags & CLK_ALWAYS_ENABLED))
-+			return -EFAULT;
-+		/* 3. a fixed child has to sit on a fixed parent */
-+		if (clk_is_readonly(clk) && !clk_is_readonly(clk->parent))
-+			return -EFAULT;
-+#endif
-+		klist_add_tail(&clk->child_node, &clk->parent->childs);
-+		clk->parent->nr_clocks++;
-+	}
-+
-+	klist_add_tail(&clk->node, &clk_list);
-+	if (clk->flags & CLK_ALWAYS_ENABLED) {
-+		__clk_enable(clk);
-+		clk_notify_child_event(CHILD_CLOCK_ENABLED, clk->parent);
-+	}
-+	return retval;
-+}
-+
-+int __init clock_init(void)
-+{
-+	clk_kobj = kobject_create_and_add("clocks", NULL);
-+	if (!clk_kobj)
-+		return -EINVAL ;
-+
-+	clk_for_each(early_clk_complete, NULL);
-+
-+	printk(KERN_INFO CLK_NAME " " CLK_VERSION "\n");
-+
-+	return 0;
-+}
-+
-diff --git a/drivers/base/clk.h b/drivers/base/clk.h
-new file mode 100644
-index 0000000..61672ef
---- /dev/null
-+++ b/drivers/base/clk.h
-@@ -0,0 +1,319 @@
-+/*
-+   -------------------------------------------------------------------------
-+   clk.h
-+   -------------------------------------------------------------------------
-+   (C) STMicroelectronics 2008
-+   (C) STMicroelectronics 2009
-+   Author: Francesco M. Virlinzi <francesco.virlinzi@st.com>
-+   ----------------------------------------------------------------------------
-+   May be copied or modified under the terms of the GNU General Public
-+   License v.2 ONLY.  See linux/COPYING for more information.
-+
-+   ------------------------------------------------------------------------- */
-+
-+#ifdef CONFIG_GENERIC_CLK_FM
-+
-+#include <linux/clk.h>
-+#include <linux/platform_device.h>
-+#include <linux/kobject.h>
-+#include <linux/klist.h>
-+#include <linux/list.h>
-+#include <linux/notifier.h>
-+#include <asm/atomic.h>
-+
-+enum clk_ops_id {
-+	__CLK_INIT = 0,
-+	__CLK_ENABLE,
-+	__CLK_DISABLE,
-+	__CLK_SET_RATE,
-+	__CLK_SET_PARENT,
-+	__CLK_RECALC,
-+	__CLK_ROUND,
-+	__CLK_EVAL,
-+};
-+
-+extern struct klist clk_list;
-+/**
-+  * clk_tnode
-+  *      it's the internal strucure used to track each node
-+  *      in the transaction graph.
-+  *      _NO_ api is showed to the other modules
-+  */
-+struct clk_tnode {
-+	/** @tid: the tnode id */
-+	unsigned long tid;
-+	/** @size: how may clock are involved in this tnode */
-+	unsigned long size;
-+	/** @parent: the parent tnode */
-+	struct clk_tnode *parent;
-+	/* @events_map: a bitmap to declare the
-+	 * valid events in this tnode
-+	 */
-+	unsigned long events_map;
-+	/** @events: the event array of this tnode */
-+	struct clk_event *events;
-+	/** @child: links the childres tnode */
-+	struct list_head childs;
-+	/** @pnode: links the tnode to the parent */
-+	struct list_head pnode;
-+};
-+
-+/*
-+ *  tnode_get_size -
-+ *  returns the number of events in the transaction
-+ */
-+static inline unsigned long
-+tnode_get_size(struct clk_tnode *tnode)
-+{
-+	return tnode->size;
-+}
-+
-+static inline unsigned long
-+tnode_get_map(struct clk_tnode *tnode)
-+{
-+	return tnode->events_map;
-+}
-+
-+static inline unsigned long
-+tnode_check_map_id(struct clk_tnode *node, int id)
-+{
-+	return node->events_map & (1 << id);
-+}
-+
-+static inline void
-+tnode_set_map_id(struct clk_tnode *node, int id)
-+{
-+	node->events_map |= (1 << id);
-+}
-+
-+static inline unsigned long
-+tnode_get_id(struct clk_tnode *node)
-+{
-+	return node->tid;
-+}
-+
-+static inline struct clk_event*
-+tnode_get_event(struct clk_tnode *node, int id)
-+{
-+	return &(node->events[id]);
-+}
-+
-+static inline struct clk_event *tnode_get_events(struct clk_tnode *node)
-+{
-+	return tnode_get_event(node, 0);
-+}
-+
-+static inline void
-+tnode_set_events(struct clk_tnode *node, struct clk_event *events)
-+{
-+	node->events = events;
-+}
-+
-+static inline struct clk*
-+tnode_get_clock(struct clk_tnode *node, int id)
-+{
-+	return tnode_get_event(node, id)->clk;
-+}
-+
-+static inline void
-+tnode_set_clock(struct clk_tnode *node, int id, struct clk *clk)
-+{
-+	node->events[id].clk = clk;
-+}
-+
-+static inline struct clk_tnode *tnode_get_parent(struct clk_tnode *node)
-+{
-+	return node->parent;
-+}
-+
-+#define tnode_for_each_valid_events(node, _j)			\
-+	for ((_j) = (ffs(tnode_get_map(node)) - 1);		\
-+	     (_j) < tnode_get_size((node)); ++(_j))		\
-+			if (tnode_check_map_id((node), (_j)))
-+
-+#define EVENT(_clk,  _oldrate, _newrate)		\
-+	(struct clk_event)				\
-+	{						\
-+		.clk = (struct clk *)(_clk),		\
-+		.old_rate = (unsigned long)(_oldrate),	\
-+		.new_rate = (unsigned long)(_newrate),	\
-+	};
-+
-+#define TRANSACTION_ROOT(_num, _event)					\
-+	(struct clk_tnode) {						\
-+		.tid    = atomic_inc_return(&transaction_counter),	\
-+		.size   = (_num),					\
-+		.events = (struct clk_event *)(_event),			\
-+		.parent = NULL,						\
-+		.childs = LIST_HEAD_INIT(transaction.childs),		\
-+		.events_map = 0,					\
-+		};
-+
-+#define klist_function_support(_name, _type, _field, _kobj)		\
-+static void klist_get_##_name(struct klist_node *n)			\
-+{									\
-+	struct _type *entry = container_of(n, struct _type, _field);	\
-+	kobject_get(&entry->_kobj);					\
-+}									\
-+static void klist_put_##_name(struct klist_node *n)			\
-+{									\
-+	struct _type *entry = container_of(n, struct _type, _field);	\
-+	kobject_put(&entry->_kobj);					\
-+}
-+
-+#define klist_entry_support(name, type, field)				\
-+static struct type *next_##name(struct klist_iter *i)			\
-+{	struct klist_node *n = klist_next(i);				\
-+	return n ? container_of(n, struct type, field) : NULL;		\
-+}
-+
-+static inline void
-+clk_event_init(struct clk_event *evt, struct clk *clk,
-+		unsigned long oldrate, unsigned long newrate)
-+{
-+	evt->clk      = clk;
-+	evt->old_rate = oldrate;
-+	evt->new_rate = newrate;
-+}
-+
-+enum clk_fsm_e {
-+	TRNSC_ENTER_CLOCK	= 0x10,
-+	TRNSC_ENTER_DEVICE	= NOTIFY_CLK_ENTERCHANGE,	/* 0x1 */
-+	TRNSC_PRE_DEVICE	= NOTIFY_CLK_PRECHANGE,		/* 0x2 */
-+	TRNSC_CHANGE_CLOCK	= 0x20,
-+	TRNSC_POST_DEVICE	= NOTIFY_CLK_POSTCHANGE,	/* 0x4 */
-+	TRNSC_EXIT_DEVICE	= NOTIFY_CLK_EXITCHANGE,	/* 0x8 */
-+	TRNSC_EXIT_CLOCK	= 0x40
-+};
-+
-+#define DEV_SUSPENDED_ON_TRANSACTION	(0x10)
-+#define DEV_RESUMED_ON_TRANSACTION	(0x20)
-+#define DEV_ON_TRANSACTION	(TRNSC_ENTER_DEVICE	|	\
-+				TRNSC_PRE_DEVICE	|	\
-+				TRNSC_POST_DEVICE	|	\
-+				TRNSC_EXIT_DEVICE)
-+
-+static inline int
-+pdev_transaction_move_on(struct platform_device *dev, unsigned int value)
-+{
-+	int ret = -EINVAL;
-+	unsigned long flag;
-+#ifdef CONFIG_CLK_DEBUG
-+	static const char *dev_state[] = {
-+		"dev_enter",
-+		"dev_pre",
-+		"dev_post",
-+		"dev_exit"
-+	};
-+
-+	unsigned long old = dev->clk_state & DEV_ON_TRANSACTION;
-+	int was = 0, is = 0;
-+	if (
-+	   (old == 0 && value == TRNSC_ENTER_DEVICE) ||
-+	   (old == TRNSC_ENTER_DEVICE && value == TRNSC_EXIT_DEVICE) ||
-+	   (old == TRNSC_ENTER_DEVICE && value == TRNSC_PRE_DEVICE) ||
-+	   (old == TRNSC_PRE_DEVICE && value == TRNSC_POST_DEVICE) ||
-+	   (old == TRNSC_POST_DEVICE && value == TRNSC_EXIT_DEVICE))
-+		goto ok;
-+	switch (old) {
-+	case TRNSC_ENTER_DEVICE:
-+		was = 0;
-+		break;
-+	case TRNSC_PRE_DEVICE:
-+		was = 1;
-+		break;
-+	case TRNSC_POST_DEVICE:
-+		was = 2;
-+		break;
-+	case TRNSC_EXIT_DEVICE:
-+		was = 3;
-+		break;
-+	}
-+	switch (value) {
-+	case TRNSC_ENTER_DEVICE:
-+		is = 0;
-+		break;
-+	case TRNSC_PRE_DEVICE:
-+		is = 1;
-+		break;
-+	case TRNSC_POST_DEVICE:
-+		is = 2;
-+		break;
-+	case TRNSC_EXIT_DEVICE:
-+		is = 3;
-+		break;
-+	}
-+	printk(KERN_ERR "The device %s.%d shows a wrong evolution during "
-+		"a clock transaction\nDev state was %s and moved on %s\n",
-+		dev->name, dev->id, dev_state[was], dev_state[is]);
-+ok:
-+#endif
-+	local_irq_save(flag);
-+	if ((dev->clk_state & DEV_ON_TRANSACTION) != value) {
-+		dev->clk_state &= ~DEV_ON_TRANSACTION;
-+		dev->clk_state |= value;
-+		ret = 0;
-+	}
-+	local_irq_restore(flag);
-+	return ret;
-+}
-+
-+static inline int
-+clk_set_towner(struct clk *clk, struct clk_tnode *node)
-+{
-+	return atomic_cmpxchg((atomic_t *)&clk->towner, 0, (int)node);
-+}
-+
-+static inline void
-+clk_clean_towner(struct clk *clk)
-+{
-+	atomic_set((atomic_t *)(&clk->towner), 0);
-+}
-+
-+static inline int
-+clk_is_enabled(struct clk *clk)
-+{
-+	return clk->rate != 0;
-+}
-+
-+static inline int
-+clk_is_readonly(struct clk *clk)
-+{
-+	return !clk->ops || !clk->ops->set_rate;
-+}
-+
-+static inline int
-+clk_allow_propagation(struct clk *clk)
-+{
-+	return !!(clk->flags & CLK_EVENT_PROPAGATES);
-+}
-+
-+static inline int
-+clk_is_auto_switching(struct clk *clk)
-+{
-+	return !!(clk->flags & CLK_AUTO_SWITCHING);
-+}
-+
-+static inline int
-+clk_follow_parent(struct clk *clk)
-+{
-+	return !!(clk->flags & CLK_FOLLOW_PARENT);
-+}
-+
-+enum pdev_add_state {
-+	PDEV_ADDING,
-+	PDEV_ADDED,
-+	PDEV_ADD_FAILED,
-+};
-+
-+enum pdev_probe_state {
-+	PDEV_PROBEING,
-+	PDEV_PROBED,
-+	PDEV_PROBE_FAILED,
-+};
-+
-+int clk_add_device(struct platform_device *dev, enum pdev_add_state state);
-+int clk_probe_device(struct platform_device *dev, enum pdev_probe_state state);
-+int clk_del_device(struct platform_device *dev);
-+
-+#endif
-diff --git a/drivers/base/clk_pm.c b/drivers/base/clk_pm.c
-new file mode 100644
-index 0000000..56c1760
---- /dev/null
-+++ b/drivers/base/clk_pm.c
-@@ -0,0 +1,197 @@
-+/*
-+ * -------------------------------------------------------------------------
-+ * clk_pm.c
-+ * -------------------------------------------------------------------------
-+ * (C) STMicroelectronics 2008
-+ * (C) STMicroelectronics 2009
-+ * Author: Francesco M. Virlinzi <francesco.virlinzi@st.com>
-+ * -------------------------------------------------------------------------
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License v.2 ONLY.  See linux/COPYING for more information.
-+ *
-+ * -------------------------------------------------------------------------
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/klist.h>
-+#include <linux/list.h>
-+#include <linux/sysdev.h>
-+#include <linux/device.h>
-+#include <linux/kref.h>
-+#include <linux/kobject.h>
-+#include <linux/err.h>
-+#include <linux/spinlock.h>
-+#include <linux/proc_fs.h>
-+#include "power/power.h"
-+#include "clk.h"
-+#include "base.h"
-+
-+static int
-+__clk_operations(struct clk *clk, unsigned long rate, enum clk_ops_id id_ops)
-+{
-+	int ret = -EINVAL;
-+	unsigned long *ops_fns = (unsigned long *)clk->ops;
-+	if (likely(ops_fns && ops_fns[id_ops])) {
-+		int (*fns)(struct clk *clk, unsigned long rate)
-+			= (void *)ops_fns[id_ops];
-+		unsigned long flags;
-+		spin_lock_irqsave(&clk->lock, flags);
-+		ret = fns(clk, rate);
-+		spin_unlock_irqrestore(&clk->lock, flags);
-+	}
-+	return ret;
-+}
-+
-+static inline int __clk_init(struct clk *clk)
-+{
-+	return __clk_operations(clk, 0, __CLK_INIT);
-+}
-+
-+static inline int __clk_enable(struct clk *clk)
-+{
-+	return __clk_operations(clk, 0, __CLK_ENABLE);
-+}
-+
-+static inline int __clk_disable(struct clk *clk)
-+{
-+	return __clk_operations(clk, 0, __CLK_DISABLE);
-+}
-+
-+static inline int __clk_set_rate(struct clk *clk, unsigned long rate)
-+{
-+	return __clk_operations(clk, rate, __CLK_SET_RATE);
-+}
-+
-+static inline int __clk_set_parent(struct clk *clk, struct clk *parent)
-+{
-+	return __clk_operations(clk, (unsigned long)parent, __CLK_SET_PARENT);
-+}
-+
-+static inline int __clk_recalc_rate(struct clk *clk)
-+{
-+	return __clk_operations(clk, 0, __CLK_RECALC);
-+}
-+
-+static inline int pm_clk_ratio(struct clk *clk)
-+{
-+	register unsigned int val, exp;
-+
-+	val = ((clk->flags >> CLK_PM_RATIO_SHIFT) &
-+		((1 << CLK_PM_RATIO_NRBITS) - 1)) + 1;
-+	exp = ((clk->flags >> CLK_PM_EXP_SHIFT) &
-+		((1 << CLK_PM_EXP_NRBITS) - 1));
-+
-+	return val << exp;
-+}
-+
-+static inline int pm_clk_is_off(struct clk *clk)
-+{
-+	return ((clk->flags & CLK_PM_TURNOFF) == CLK_PM_TURNOFF);
-+}
-+
-+static inline void pm_clk_set(struct clk *clk, int edited)
-+{
-+#define CLK_PM_EDITED (1 << CLK_PM_EDIT_SHIFT)
-+	clk->flags &= ~CLK_PM_EDITED;
-+	clk->flags |= (edited ? CLK_PM_EDITED : 0);
-+}
-+
-+static inline int pm_clk_is_modified(struct clk *clk)
-+{
-+	return ((clk->flags & CLK_PM_EDITED) != 0);
-+}
-+
-+static int clk_resume_from_standby(struct clk *clk, void *data)
-+{
-+	pr_debug("\n");
-+	if (!likely(clk->ops))
-+		return 0;
-+	/* check if the pm modified the clock */
-+	if (!pm_clk_is_modified(clk))
-+		return 0;;
-+	pm_clk_set(clk, 0);
-+	if (pm_clk_is_off(clk))
-+		__clk_enable(clk);
-+	else
-+		__clk_set_rate(clk, clk->rate * pm_clk_ratio(clk));
-+	return 0;
-+}
-+
-+static int clk_on_standby(struct clk *clk, void *data)
-+{
-+	pr_debug("\n");
-+
-+	if (!clk->ops)
-+		return 0;
-+	if (!clk->rate) /* already disabled */
-+		return 0;
-+
-+	pm_clk_set(clk, 1);	/* set as modified */
-+	if (pm_clk_is_off(clk))		/* turn-off */
-+		__clk_disable(clk);
-+	else    /* reduce */
-+		__clk_set_rate(clk, clk->rate / pm_clk_ratio(clk));
-+	return 0;
-+}
-+
-+static int clk_resume_from_hibernation(struct clk *clk, void *data)
-+{
-+	unsigned long rate = clk->rate;
-+	pr_debug("\n");
-+	__clk_set_parent(clk, clk->parent);
-+	__clk_set_rate(clk, rate);
-+	__clk_recalc_rate(clk);
-+	return 0;
-+}
-+
-+static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
-+{
-+	static pm_message_t prev_state;
-+
-+	switch (state.event) {
-+	case PM_EVENT_ON:
-+		switch (prev_state.event) {
-+		case PM_EVENT_FREEZE: /* Resumeing from hibernation */
-+			clk_for_each(clk_resume_from_hibernation, NULL);
-+			break;
-+		case PM_EVENT_SUSPEND:
-+			clk_for_each(clk_resume_from_standby, NULL);
-+			break;
-+		}
-+	case PM_EVENT_SUSPEND:
-+		clk_for_each(clk_on_standby, NULL);
-+		break;
-+	case PM_EVENT_FREEZE:
-+		break;
-+	}
-+	prev_state = state;
-+	return 0;
-+}
-+
-+static int clks_sysdev_resume(struct sys_device *dev)
-+{
-+	return clks_sysdev_suspend(dev, PMSG_ON);
-+}
-+
-+static struct sysdev_class clk_sysdev_class = {
-+	.name = "clks",
-+};
-+
-+static struct sysdev_driver clks_sysdev_driver = {
-+	.suspend = clks_sysdev_suspend,
-+	.resume = clks_sysdev_resume,
-+};
-+
-+static struct sys_device clks_sysdev_dev = {
-+	.cls = &clk_sysdev_class,
-+};
-+
-+static int __init clk_sysdev_init(void)
-+{
-+	sysdev_class_register(&clk_sysdev_class);
-+	sysdev_driver_register(&clk_sysdev_class, &clks_sysdev_driver);
-+	sysdev_register(&clks_sysdev_dev);
-+	return 0;
-+}
-+
-+subsys_initcall(clk_sysdev_init);
-diff --git a/drivers/base/clk_utils.c b/drivers/base/clk_utils.c
-new file mode 100644
-index 0000000..a222aa7
---- /dev/null
-+++ b/drivers/base/clk_utils.c
-@@ -0,0 +1,456 @@
-+/*
-+ * -------------------------------------------------------------------------
-+ * clk_utils.c
-+ * -------------------------------------------------------------------------
-+ * (C) STMicroelectronics 2008
-+ * (C) STMicroelectronics 2009
-+ * Author: Francesco M. Virlinzi <francesco.virlinzi@st.com>
-+ * -------------------------------------------------------------------------
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License v.2 ONLY.  See linux/COPYING for more information.
-+ *
-+ * -------------------------------------------------------------------------
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <linux/clk.h>
-+#include <linux/klist.h>
-+#include <linux/list.h>
-+#include <linux/delay.h>
-+#include <linux/sysdev.h>
-+#include <linux/kref.h>
-+#include <linux/kobject.h>
-+#include <linux/err.h>
-+#include <linux/spinlock.h>
-+#include <asm/atomic.h>
-+#include "power/power.h"
-+#include "clk.h"
-+#include "base.h"
-+
-+int clk_generic_notify(unsigned long code,
-+	struct platform_device *pdev, void *data)
-+{
-+	struct clk_event *event = (struct clk_event *)data;
-+	unsigned long event_decode = clk_event_decode(event);
-+
-+	switch (code) {
-+	case NOTIFY_CLK_ENTERCHANGE:
-+		return NOTIFY_EVENT_HANDLED;	/* to accept */
-+
-+	case NOTIFY_CLK_PRECHANGE:
-+		/* without clock (not still enabled) the device can not work */
-+		if (event_decode == _CLK_ENABLE)
-+			return NOTIFY_EVENT_NOTHANDLED;
-+		return NOTIFY_EVENT_HANDLED;	/* to suspend */
-+
-+	case NOTIFY_CLK_POSTCHANGE:
-+		/* without clock (just disabled) the device can not work */
-+		if (event_decode == _CLK_DISABLE)
-+			return NOTIFY_EVENT_NOTHANDLED;
-+		return NOTIFY_EVENT_HANDLED;	/* to resume */
-+
-+	case NOTIFY_CLK_EXITCHANGE:
-+		return NOTIFY_EVENT_HANDLED;
-+	}
-+
-+	return NOTIFY_EVENT_HANDLED;
-+}
-+EXPORT_SYMBOL(clk_generic_notify);
-+
-+unsigned long clk_generic_evaluate_rate(struct clk *clk, unsigned long prate)
-+{
-+	unsigned long current_prate;
-+
-+	if (!clk->parent)
-+		return -EINVAL;
-+
-+	if (!prate)	/* if zero return zero (on disable: disable!) */
-+		return 0;
-+
-+	if (prate == CLK_UNDEFINED_RATE) /* on undefined: undefined */
-+		return CLK_UNDEFINED_RATE;
-+
-+	current_prate = clk_get_rate(clk->parent);
-+	if (current_prate == prate)
-+		return clk_get_rate(clk);
-+
-+	if (current_prate > prate) /* down scale */
-+		return (clk_get_rate(clk) * prate) / current_prate;
-+	else
-+		return (clk_get_rate(clk) / current_prate) * prate;
-+}
-+EXPORT_SYMBOL(clk_generic_evaluate_rate);
-+
-+#ifdef CONFIG_PROC_FS
-+/*
-+ * The "clocks" file is created under /proc
-+ * to list all the clocks registered in the system
-+ */
-+#include <linux/proc_fs.h>
-+#include <linux/seq_file.h>
-+static void *clk_seq_next(struct seq_file *s, void *v, loff_t *pos)
-+{
-+	struct list_head *tmp;
-+	union {
-+		loff_t value;
-+		long parts[2];
-+	} ltmp;
-+
-+	ltmp.value = *pos;
-+	tmp = (struct list_head *)ltmp.parts[0];
-+	tmp = tmp->next;
-+	ltmp.parts[0] = (long)tmp;
-+
-+	*pos = ltmp.value;
-+
-+	if (tmp == &clk_list.k_list)
-+		return NULL; /* No more to read */
-+
-+	return pos;
-+}
-+
-+static void *clk_seq_start(struct seq_file *s, loff_t *pos)
-+{
-+	if (!*pos) { /* first call! */
-+		union {
-+			loff_t value;
-+			long parts[2];
-+		} ltmp;
-+		ltmp.parts[0] = (long) clk_list.k_list.next;
-+		*pos = ltmp. value;
-+		return pos;
-+	}
-+	--(*pos); /* to realign *pos value! */
-+
-+	return clk_seq_next(s, NULL, pos);
-+}
-+
-+static int clk_seq_show(struct seq_file *s, void *v)
-+{
-+	unsigned long *l = (unsigned long *)v;
-+	struct list_head *node = (struct list_head *)(*l);
-+	struct clk *clk = container_of(node, struct clk, node.n_node);
-+	unsigned long rate = clk_get_rate(clk);
-+
-+	if (unlikely(!rate && !clk->parent))
-+		return 0;
-+
-+	seq_printf(s, "%-12s\t: %ld.%02ldMHz - ", clk->name,
-+	       rate / 1000000, (rate % 1000000) / 10000);
-+	seq_printf(s, "[0x%p]", clk);
-+	if (clk_is_enabled(clk))
-+		seq_printf(s, " - enabled");
-+
-+	if (clk->parent)
-+		seq_printf(s, " - [%s]", clk->parent->name);
-+	seq_printf(s, "\n");
-+
-+	return 0;
-+}
-+
-+static void clk_seq_stop(struct seq_file *s, void *v)
-+{
-+}
-+
-+static const struct seq_operations clk_seq_ops = {
-+	.start = clk_seq_start,
-+	.next = clk_seq_next,
-+	.stop = clk_seq_stop,
-+	.show = clk_seq_show,
-+};
-+
-+static int clk_proc_open(struct inode *inode, struct file *file)
-+{
-+	return seq_open(file, &clk_seq_ops);
-+}
-+
-+static const struct file_operations clk_proc_ops = {
-+	.owner = THIS_MODULE,
-+	.open = clk_proc_open,
-+	.read = seq_read,
-+	.llseek = seq_lseek,
-+	.release = seq_release,
-+};
-+
-+static int __init clk_proc_init(void)
-+{
-+	struct proc_dir_entry *p;
-+
-+	p = create_proc_entry("clocks", S_IRUGO, NULL);
-+
-+	if (unlikely(!p))
-+		return -EINVAL;
-+
-+	p->proc_fops = &clk_proc_ops;
-+
-+	return 0;
-+}
-+
-+subsys_initcall(clk_proc_init);
-+#endif
-+
-+#ifdef CONFIG_SYSFS
-+static ssize_t clk_rate_show(struct kobject *kobj,
-+		struct kobj_attribute *attr, char *buf)
-+{
-+	struct clk *clk = container_of(kobj, struct clk, kobj);
-+
-+	return sprintf(buf, "%u\n", (unsigned int)clk_get_rate(clk));
-+}
-+
-+static ssize_t clk_rate_store(struct kobject *kobj,
-+		struct kobj_attribute *attr, const char *buf, size_t count)
-+{
-+	unsigned long rate = simple_strtoul(buf, NULL, 10);
-+	struct clk *clk = container_of(kobj, struct clk, kobj);
-+
-+	if (rate) {
-+		if (!clk_is_enabled(clk))
-+			clk_enable(clk);
-+		if (clk_set_rate(clk, rate) < 0)
-+			return -EINVAL;
-+	} else
-+		clk_disable(clk);
-+	return count;
-+}
-+
-+static const char *clk_ctrl_token[] = {
-+	"auto_switching",
-+	"no_auto_switching",
-+	"allow_propagation",
-+	"no_allow_propagation",
-+	"follow_parent",
-+	"no_follow_parent",
-+};
-+static ssize_t clk_state_show(struct kobject *kobj,
-+		struct kobj_attribute *attr, char *buf)
-+{
-+	struct clk *clk = container_of(kobj, struct clk, kobj);
-+	ssize_t ret;
-+
-+
-+	ret = sprintf(buf, "clock name: %s\n", clk->name);
-+	if (clk_is_enabled(clk))
-+		ret += sprintf(buf + ret, " + enabled\n");
-+	else
-+		ret += sprintf(buf + ret, " + disabled\n");
-+	if (clk_is_readonly(clk))
-+		ret += sprintf(buf + ret, " + rate read only\n");
-+	else
-+		ret += sprintf(buf + ret, " + rate writable\n");
-+	ret +=
-+	    sprintf(buf + ret, " + %s\n",
-+		    clk_ctrl_token[(clk_allow_propagation(clk) ? 2 : 3)]);
-+	ret +=
-+	    sprintf(buf + ret, " + %s\n",
-+		    clk_ctrl_token[(clk_is_auto_switching(clk) ? 0 : 1)]);
-+	ret +=
-+	    sprintf(buf + ret, " + %s\n",
-+		    clk_ctrl_token[(clk_follow_parent(clk) ? 4 : 5)]);
-+	ret +=
-+	    sprintf(buf + ret, " + nr_clocks:  %u\n", clk->nr_clocks);
-+	ret +=
-+	    sprintf(buf + ret, " + nr_active_clocks:  %u\n",
-+		clk->nr_active_clocks);
-+	ret +=
-+	    sprintf(buf + ret, " + nr_active_devices:  %u\n",
-+		clk->nr_active_devices);
-+	ret +=
-+	    sprintf(buf + ret, " + rate: %u\n",
-+		    (unsigned int)clk_get_rate(clk));
-+	return ret;
-+}
-+
-+static ssize_t clk_ctrl_show(struct kobject *kobj,
-+		struct kobj_attribute *attr, char *buf)
-+{
-+	int idx, ret = 0;
-+
-+	ret += sprintf(buf + ret, "Allowed command:\n");
-+
-+	for (idx = 0; idx < ARRAY_SIZE(clk_ctrl_token); ++idx)
-+		ret += sprintf(buf + ret, " + %s\n", clk_ctrl_token[idx]);
-+
-+	return ret;
-+}
-+static ssize_t clk_ctrl_store(struct kobject *kobj,
-+		struct kobj_attribute *attr, const char *buf, size_t count)
-+{
-+	int i, idx_token, ret = -EINVAL;
-+	struct clk *clk = container_of(kobj, struct clk, kobj);
-+
-+	if (!count)
-+		return ret;
-+
-+	for (i = 0, idx_token = -1; i < ARRAY_SIZE(clk_ctrl_token); ++i)
-+		if (!strcmp(buf, clk_ctrl_token[i]))
-+			idx_token = i;
-+
-+	if (idx_token == -EINVAL)
-+		return ret;     /* token not valid... */
-+
-+	switch (idx_token) {
-+	case 0:
-+		clk->flags |= CLK_EVENT_PROPAGATES;
-+		break;
-+	case 1:
-+		clk->flags &= ~CLK_EVENT_PROPAGATES;
-+		break;
-+	case 2:
-+		clk->flags |= CLK_AUTO_SWITCHING;
-+		if (!clk->nr_active_clocks && !clk->nr_active_devices)
-+			clk_disable(clk);
-+		else if (clk->nr_active_clocks || clk->nr_active_devices)
-+			clk_enable(clk);
-+		break;
-+	case 3:
-+		clk->flags &= ~CLK_AUTO_SWITCHING;
-+		break;
-+	case 4:
-+		clk->flags |= CLK_FOLLOW_PARENT;
-+		break;
-+	case 5:
-+		clk->flags &= ~CLK_FOLLOW_PARENT;
-+		break;
-+	}
-+
-+	return count;
-+}
-+
-+static ssize_t clk_parent_store(struct kobject *kobj,
-+		struct kobj_attribute *attr, const char *buf, size_t count)
-+{
-+	struct clk *clk = container_of(kobj, struct clk, kobj);
-+	struct clk *parent = clk_get(NULL, buf);
-+
-+	if (!parent)
-+		return -EINVAL;
-+
-+	clk_put(parent);
-+	clk_set_parent(clk, parent);
-+
-+	return count;
-+}
-+
-+static struct kobj_attribute attributes[] = {
-+__ATTR(state, S_IRUSR, clk_state_show, NULL),
-+__ATTR(rate, S_IRUSR | S_IWUSR, clk_rate_show, clk_rate_store),
-+__ATTR(control, S_IRUSR | S_IWUSR, clk_ctrl_show, clk_ctrl_store),
-+__ATTR(parent, S_IWUSR, NULL, clk_parent_store)
-+};
-+
-+static struct attribute *clk_attrs[] = {
-+	&attributes[0].attr,
-+	&attributes[1].attr,
-+	&attributes[2].attr,
-+	&attributes[3].attr,
-+	NULL
-+};
-+
-+static struct attribute_group clk_attr_group = {
-+	.attrs = clk_attrs,
-+	.name = "attributes"
-+};
-+
-+#if 0
-+static inline char *_strsep(char **s, const char *d)
-+{
-+	int i, len = strlen(d);
-+retry:
-+	if (!(*s) || !(**s))
-+		return NULL;
-+	for (i = 0; i < len; ++i) {
-+		if (**s != *(d+i))
-+			continue;
-+		++(*s);
-+		goto retry;
-+	}
-+	return strsep(s, d);
-+}
-+
-+/**
-+ * clk_rates_store
-+ *
-+ * It parses the buf to create multi clocks transaction
-+ * via user space
-+ * The buffer has to be something like:
-+ * clock_A @ rate_A; clock_B @ rate_b; clock_C @ rate_c
-+ */
-+static ssize_t clk_rates_store(struct kobject *kobj,
-+		struct kobj_attribute *attr, const char *buf, size_t count)
-+{
-+	int i, ret;
-+	int nclock = 0;
-+	unsigned long *rates;
-+	struct clk **clocks;
-+
-+	if (!buf)
-+		return -1;
-+
-+	for (i = 0; i < count; ++i)
-+		if (buf[i] == '@')
-+			++nclock;
-+
-+	rates = kmalloc(sizeof(long) * nclock, GFP_KERNEL);
-+	if (!rates)
-+		return -ENOMEM;
-+
-+	clocks = kmalloc(sizeof(void *) * nclock, GFP_KERNEL);
-+	if (!clocks) {
-+		ret = -ENOMEM;
-+		goto err_0;
-+	}
-+
-+	/* Parse the buffer */
-+	for (i = 0; i < nclock; ++i) {
-+		char *name;
-+		char *nrate;
-+		name  = _strsep((char **)&buf, "@ "); ++buf;
-+		nrate = _strsep((char **)&buf, " ;"); ++buf;
-+		if (!name || !nrate) {
-+			ret = -EINVAL;
-+			goto err_1;
-+			}
-+		clocks[i] = clk_get(NULL, name);
-+		rates[i]  = simple_strtoul(nrate, NULL, 10);
-+		if (!clocks[i]) { /* the clock doesn't exist! */
-+			ret = -EINVAL;
-+			goto err_1;
-+			}
-+	}
-+
-+	ret = clk_set_rates(clocks, rates, nclock);
-+	if (ret >= 0)
-+		ret = count; /* to say OK */
-+
-+err_1:
-+	kfree(clocks);
-+err_0:
-+	kfree(rates);
-+	return ret;
-+}
-+
-+static struct kobj_attribute clk_rates_attr =
-+	__ATTR(rates, S_IWUSR, NULL, clk_rates_store);
-+#endif
-+
-+static int __init clk_add_attributes(struct clk *clk, void *data)
-+{
-+	int ret;
-+
-+	ret = sysfs_update_group(&clk->kobj, &clk_attr_group);
-+
-+	return ret;
-+}
-+
-+static int __init clk_late_init(void)
-+{
-+	int ret;
-+
-+	ret = clk_for_each(clk_add_attributes, NULL);
-+
-+	return ret;
-+}
-+
-+late_initcall(clk_late_init);
-+#endif
-diff --git a/drivers/base/init.c b/drivers/base/init.c
-index 7bd9b6a..2441b26 100644
---- a/drivers/base/init.c
-+++ b/drivers/base/init.c
-@@ -24,6 +24,7 @@ void __init driver_init(void)
- 	buses_init();
- 	classes_init();
- 	firmware_init();
-+	clock_init();
- 	hypervisor_init();
- 
- 	/* These are also core pieces, but must come after the
-diff --git a/drivers/base/platform.c b/drivers/base/platform.c
-index 8b4708e..550d993 100644
---- a/drivers/base/platform.c
-+++ b/drivers/base/platform.c
-@@ -17,6 +17,8 @@
- #include <linux/bootmem.h>
- #include <linux/err.h>
- #include <linux/slab.h>
-+#include <linux/clk.h>
-+#include "clk.h"
- 
- #include "base.h"
- 
-@@ -272,9 +274,20 @@ int platform_device_add(struct platform_device *pdev)
- 	pr_debug("Registering platform device '%s'. Parent at %s\n",
- 		 dev_name(&pdev->dev), dev_name(pdev->dev.parent));
- 
-+#ifdef CONFIG_GENERIC_CLK_FM
-+	clk_add_device(pdev, PDEV_ADDING);
-+
-+	ret = device_add(&pdev->dev);
-+
-+	clk_add_device(pdev, (ret ? PDEV_ADD_FAILED : PDEV_ADDED));
-+
-+	if (ret == 0)
-+		return ret;
-+#else
- 	ret = device_add(&pdev->dev);
- 	if (ret == 0)
- 		return ret;
-+#endif
- 
-  failed:
- 	while (--i >= 0) {
-@@ -311,6 +324,9 @@ void platform_device_del(struct platform_device *pdev)
- 			if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
- 				release_resource(r);
- 		}
-+#ifdef CONFIG_GENERIC_CLK_FM
-+	clk_del_device(pdev);
-+#endif
- 	}
- }
- EXPORT_SYMBOL_GPL(platform_device_del);
-@@ -445,7 +461,18 @@ static int platform_drv_probe(struct device *_dev)
- 	struct platform_driver *drv = to_platform_driver(_dev->driver);
- 	struct platform_device *dev = to_platform_device(_dev);
- 
-+#ifdef CONFIG_GENERIC_CLK_FM
-+	int ret;
-+	ret = clk_probe_device(dev, PDEV_PROBEING);
-+	if (ret)
-+		return ret;
-+	ret = drv->probe(dev);
-+
-+	clk_probe_device(dev, (ret ? PDEV_PROBE_FAILED : PDEV_PROBED));
-+	return ret;
-+#else
- 	return drv->probe(dev);
-+#endif
- }
- 
- static int platform_drv_probe_fail(struct device *_dev)
-diff --git a/include/linux/clk.h b/include/linux/clk.h
-index 1db9bbf..e537bcd 100644
---- a/include/linux/clk.h
-+++ b/include/linux/clk.h
-@@ -12,6 +12,7 @@
- #define __LINUX_CLK_H
- 
- struct device;
-+struct platform_device;
- 
- /*
-  * The base API.
-@@ -142,4 +143,254 @@ struct clk *clk_get_parent(struct clk *clk);
-  */
- struct clk *clk_get_sys(const char *dev_id, const char *con_id);
- 
-+/**
-+ * clk_set_rates - set the clock rates
-+ * @clk: clocks source
-+ * @rate: desired clock rates in Hz
-+ * @nclks: the number of clocks
-+ *
-+ * Returns success (0) or negative errno.
-+ */
-+int clk_set_rates(struct clk **clk, unsigned long *rates, unsigned long nclks);
-+
-+#ifndef CONFIG_GENERIC_CLK_FM
-+
-+#define bind_clock(_clk)
-+#define pdevice_setclock(_dev, _clk)
-+#define pdevice_setclock_byname(_dev, _clkname)
-+#define pdevice_num_clocks(_dev)
-+#define pdevice_clock(dev, idx)
-+
-+#else
-+
-+#include <linux/kobject.h>
-+#include <linux/klist.h>
-+#include <linux/notifier.h>
-+#include <linux/pm.h>
-+#include <linux/spinlock.h>
-+#include <asm/atomic.h>
-+
-+
-+/**
-+ * Clock operation -
-+ *
-+ * It's a set of function pointer to identify all the capability on a clock
-+ */
-+struct clk_ops {
-+/** @init initializes the clock	*/
-+	int (*init)(struct clk *);
-+/** @enable enables the clock	*/
-+	int (*enable)(struct clk *);
-+/** @disable disables the clock	*/
-+	int (*disable)(struct clk *);
-+/** @set_rate sets the new frequency rate */
-+	int (*set_rate)(struct clk *, unsigned long value);
-+/** @set_parent sets the new parent clock */
-+	int (*set_parent)(struct clk *clk, struct clk *parent);
-+/** @recalc updates the clock rate when the parent clock is updated	 */
-+	void (*recalc)(struct clk *);
-+/** @round returns the allowed rate on the required value	*/
-+	unsigned long (*round)(struct clk *, unsigned long value);
-+/** @eval evaluates the clock rate based on a parent_rate but the
-+ * real clock rate is __not__ changed
-+ */
-+	unsigned long (*eval)(struct clk *, unsigned long parent_rate);
-+};
-+
-+/**
-+ * struct clk - clock object
-+ */
-+struct clk {
-+	spinlock_t		lock;
-+
-+	struct kobject		kobj;
-+	struct kobject		*kdevices;
-+
-+	int			id;
-+
-+	const char		*name;
-+	struct module		*owner;
-+
-+	struct clk		*parent;
-+	struct clk_ops		*ops;
-+
-+	void			*private_data;
-+
-+	unsigned long		rate;
-+	unsigned long		flags;
-+
-+	unsigned int		nr_active_clocks;
-+	unsigned int		nr_active_devices;
-+	unsigned int		nr_clocks;
-+
-+	void			*towner;/* the transaction owner of the clock */
-+
-+	struct klist		childs;
-+	struct klist		devices;
-+
-+	struct klist_node	node;		/* for global link	*/
-+	struct klist_node	child_node;	/* for child link	*/
-+};
-+
-+#define CLK_ALWAYS_ENABLED		(0x1 << 0)
-+#define CLK_EVENT_PROPAGATES		(0x1 << 1)
-+#define CLK_RATE_PROPAGATES		CLK_EVENT_PROPAGATES
-+/* CLK_AUTO_SWITCHING: enable/disable the clock based on the
-+ * current active children
-+ */
-+#define CLK_AUTO_SWITCHING		(0x1 << 2)
-+/* CLK_FOLLOW_PARENT: enable/disable the clock as the parent is
-+ * enabled/disabled
-+ */
-+#define CLK_FOLLOW_PARENT		(0x1 << 3)
-+
-+/*
-+ * Flags to support the system standby
-+ */
-+#define CLK_PM_EXP_SHIFT	(24)
-+#define CLK_PM_EXP_NRBITS	(7)
-+#define CLK_PM_RATIO_SHIFT	(16)
-+#define CLK_PM_RATIO_NRBITS	(8)
-+#define CLK_PM_EDIT_SHIFT	(31)
-+#define CLK_PM_EDIT_NRBITS	(1)
-+#define CLK_PM_TURNOFF		(((1<<CLK_PM_EXP_NRBITS)-1) << CLK_PM_EXP_SHIFT)
-+
-+int early_clk_register(struct clk *);
-+/**
-+ * Registers a new clock into the system
-+ */
-+int clk_register(struct clk *);
-+/**
-+ * Unregisters a clock into the system
-+ */
-+int clk_unregister(struct clk *);
-+
-+/**
-+ * Returns the clock rate if the  parent clock is 'parent_rate'
-+ */
-+unsigned long clk_evaluate_rate(struct clk *, unsigned long parent_rate);
-+
-+#define CLK_UNDEFINED_RATE	(-1UL)
-+/**
-+ * Utility functions in the clock framework
-+ */
-+int clk_for_each(int (*fn)(struct clk *, void *), void *);
-+
-+int clk_for_each_child(struct clk *, int (*fn)(struct clk *, void *), void *);
-+
-+/** struct pdev_clk_info -
-+ *
-+ *  It's a meta data used to link the device of linux driver model
-+ *  to the clock framework.
-+ *  The device driver developers has to set only the clk field
-+ *  all the other fileds are managed in the clk core code
-+ */
-+struct pdev_clk_info {
-+	/** the device owner    */
-+	struct platform_device  *pdev;
-+	/** the clock address	*/
-+	struct clk		*clk;
-+	/** used by the clock core*/
-+	struct klist_node	node;
-+};
-+
-+/******************** clk transition notifiers *******************/
-+#define	NOTIFY_CLK_ENTERCHANGE	0x1
-+#define	NOTIFY_CLK_PRECHANGE	0x2
-+#define	NOTIFY_CLK_POSTCHANGE	0x4
-+#define NOTIFY_CLK_EXITCHANGE	0x8
-+
-+/** struct clk_event
-+ *
-+ * It's the object propagated during a clock transaction.
-+ * During a transaction each device will receive an array of 'struct clk_event'
-+ * based on the clocks it uses
-+ */
-+struct clk_event {
-+	/** on which clock the event is		*/
-+	struct clk *clk;
-+	/** the clock rate before the event	*/
-+	unsigned long old_rate;
-+	/** the clock rate after the event	*/
-+	unsigned long new_rate;
-+};
-+
-+enum clk_event_e {
-+	_CLK_NOCHANGE,
-+	_CLK_ENABLE,
-+	_CLK_DISABLE,
-+	_CLK_CHANGE
-+};
-+
-+/**
-+ * clk_event_decode -
-+ *
-+ * @event: the events has to be decoded
-+ * It's an utility function to identify what each clock
-+ * is doing
-+ */
-+static inline enum clk_event_e clk_event_decode(struct clk_event const *event)
-+{
-+	if (event->old_rate == event->new_rate)
-+		return _CLK_NOCHANGE;
-+	if (!event->old_rate && event->new_rate)
-+		return _CLK_ENABLE;
-+	if (event->old_rate && !event->new_rate)
-+		return _CLK_DISABLE;
-+	return _CLK_CHANGE;
-+}
-+
-+enum notify_ret_e {
-+	NOTIFY_EVENT_HANDLED = 0,		/* event handled	*/
-+	NOTIFY_EVENT_NOTHANDLED,		/* event not handled	*/
-+};
-+
-+/* Some macro device oriented static initialization */
-+#define bind_clock(_clk)					\
-+	.nr_clks = 1,						\
-+	.clks = (struct pdev_clk_info[]) { {			\
-+		.clk = (_clk),					\
-+		} },
-+
-+#define pdevice_setclock(_dev, _clk)				\
-+	(_dev)->clks[0].clk = (_clk);				\
-+	(_dev)->nr_clks = 1;
-+
-+#define pdevice_setclock_byname(_dev, _clkname)			\
-+	(_dev)->clks[0].clk = clk_get(NULL, _clkname);		\
-+	(_dev)->nr_clks = 1;
-+
-+#define pdevice_num_clocks(_dev)	((_dev)->nr_clks)
-+
-+#define pdevice_clock(dev, idx)		((dev)->clks[(idx)].clk)
-+
-+/**
-+ * clk_generic_notify -
-+ *
-+ * @code: the code event
-+ * @dev: the platform_device under transaction
-+ * @data: the clock event descriptor
-+ *
-+ * it's a generic notify function for devie with _only_
-+ * one clock. It will :
-+ * - accept every 'ENTER' state
-+ * - suspend on 'PRE' state
-+ * - resume on 'POST' state
-+ * - do nothing on 'EXIT' state
-+ */
-+int clk_generic_notify(unsigned long code, struct platform_device *dev,
-+	void *data);
-+
-+/*
-+ * clk_generic_evaluate_rate
-+ *
-+ * @clk: the analised clock
-+ * @prate: the parent rate
-+ *
-+ * Evaluate the clock rate (without hardware modification) based on a 'prate'
-+ * parent clock rate. It's based on 'divisor' relationship
-+ * between parent and child
-+ */
-+unsigned long clk_generic_evaluate_rate(struct clk *clk, unsigned long prate);
-+#endif
- #endif
-diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
-index b67bb5d..db1989d 100644
---- a/include/linux/platform_device.h
-+++ b/include/linux/platform_device.h
-@@ -12,6 +12,7 @@
- #define _PLATFORM_DEVICE_H_
- 
- #include <linux/device.h>
-+#include <linux/clk.h>
- #include <linux/mod_devicetable.h>
- 
- struct platform_device {
-@@ -22,6 +23,11 @@ struct platform_device {
- 	struct resource	* resource;
- 
- 	struct platform_device_id	*id_entry;
-+#ifdef CONFIG_GENERIC_CLK_FM
-+	unsigned long	clk_state;      /* used by the core */
-+	unsigned long	nr_clks;
-+	struct pdev_clk_info    *clks;
-+#endif
- };
- 
- #define platform_get_device_id(pdev)	((pdev)->id_entry)
-@@ -61,6 +67,9 @@ struct platform_driver {
- 	int (*resume_early)(struct platform_device *);
- 	int (*resume)(struct platform_device *);
- 	struct device_driver driver;
-+#ifdef CONFIG_GENERIC_CLK_FM
-+	int (*notify)(unsigned long code, struct platform_device *, void *);
-+#endif
- 	struct platform_device_id *id_table;
- };
- 
-diff --git a/init/Kconfig b/init/Kconfig
-index 0682ecc..4254c5f 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1042,6 +1042,29 @@ config SLOW_WORK
- 
- 	  See Documentation/slow-work.txt.
- 
-+config GENERIC_CLK_FM
-+        default n
-+	depends on EXPERIMENTAL
-+        bool "Generic Clock Framework"
-+        help
-+          Add the clock framework in the Linux driver model
-+          to track the clocks used by each devices and drivers
-+
-+config CLK_FORCE_GENERIC_EVALUATE
-+        depends on GENERIC_CLK_FM
-+        default n
-+        bool "Force the clk_generic_evaluate_rate"
-+        help
-+          Say the if you want use the clk_generic_evaluate_rate on every clock
-+          without evaluate_rate
-+
-+config CLK_DEBUG
-+        depends on GENERIC_CLK_FM
-+        default n
-+        bool "Debug the Generic Clk Framework"
-+        help
-+          Prints some message to debug the clock framework
-+
- endmenu		# General setup
- 
- config HAVE_GENERIC_DMA_COHERENT
--- 
-1.6.2.5
diff --git a/a/3.hdr b/a/3.hdr
deleted file mode 100644
index 4b86001..0000000
--- a/a/3.hdr
+++ /dev/null
@@ -1,4 +0,0 @@
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
diff --git a/a/3.txt b/a/3.txt
deleted file mode 100644
index 8133cf0..0000000
--- a/a/3.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-_______________________________________________
-linux-arm-kernel mailing list
-linux-arm-kernel@lists.infradead.org
-http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff --git a/a/content_digest b/N1/content_digest
index 0140af8..729cc90 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,10 +1,8 @@
- "From\0Francesco VIRLINZI <francesco.virlinzi@st.com>\0"
+ "From\0francesco.virlinzi@st.com (Francesco VIRLINZI)\0"
  "Subject\0[Proposal] [PATCH] generic clock framework\0"
  "Date\0Tue, 10 Nov 2009 15:00:59 +0100\0"
- "To\0linux-arm-kernel@lists.infradead.org"
-  Linux-sh <linux-sh@vger.kernel.org>
- " linux-embedded@vger.kernel.org\0"
- "\02:1.1\0"
+ "To\0linux-arm-kernel@lists.infradead.org\0"
+ "\00:1\0"
  "b\0"
  "Hi all\n"
  "\n"
@@ -59,3155 +57,13 @@
  "to extend/fix/share it.\n"
  "\n"
  "Regards\n"
-   Francesco
- "\02:1.2\0"
- "b\0"
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
- "<html>\n"
- "<head>\n"
- "\n"
- "<meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\">\n"
- "</head>\n"
- "<body text=\"#000000\" bgcolor=\"#ffffff\">\n"
- "<big><big><tt>Hi all<br>\n"
- "<br>\n"
- "I'm Francesco and I work in STMicroelectronics<br>\n"
- "<br>\n"
- "In the last ELC-E_2009 I spoke on a generic clock framework I'm working\n"
- "on<br>\n"
- "&nbsp;(see\n"
- "<a class=\"moz-txt-link-freetext\" href=\"http://tree.celinuxforum.org/CelfPubWiki/ELCEurope2009Presentations?action=AttachFile&amp;do=view&amp;target=ELC_E_2009_Generic_Clock_Framework.pdf\">http://tree.celinuxforum.org/CelfPubWiki/ELCEurope2009Presentations?action=AttachFile&amp;do=view&amp;target=ELC_E_2009_Generic_Clock_Framework.pdf</a>).<br>\n"
- "<br>\n"
- "</tt><tt>I wrote the gcf to manage both clocks the platform_devices\n"
- "during a clock operation.<br>\n"
- "<br>\n"
- "</tt><tt>The main features are:<br>\n"
- "&nbsp;- it's integrated in the LDM<br>\n"
- "</tt></big></big><big><big><tt>&nbsp;- it tracks the clock-to-clock\n"
- "relationship<br>\n"
- "&nbsp;- it tracks the clock-to-device relationship<br>\n"
- "<br>\n"
- "</tt></big></big><big><big><tt>&nbsp;- it has sysfs interface<br>\n"
- "&nbsp;- - the user can navigate the clock tree under /sys/clocks/...<br>\n"
- "<br>\n"
- "&nbsp;- it uses the linux API (&lt;linux/clk.h&gt;) with some extra\n"
- "functions (to register/unregister a clock<br>\n"
- "&nbsp;&nbsp; and other utility functions as clk_for_each())<br>\n"
- "<br>\n"
- "&nbsp;- it involves the platform_device and the platform_driver in the clock\n"
- "propagation.<br>\n"
- "&nbsp;- - basically each clock operation is managed as a transaction which\n"
- "evolves step by step.<br>\n"
- "&nbsp;- - </tt><tt>all the clock rates are evaluated (before the clk\n"
- "operation is actually done)<br>\n"
- "</tt><tt>&nbsp;- - each platform_device can check (</tt><tt>before the clk\n"
- "operation is </tt></big></big><big><big><tt>actually</tt></big></big><big><big><tt>\n"
- "done</tt><tt>) the clk environment<br>\n"
- "&nbsp;&nbsp;&nbsp;&nbsp; it will have at the end of clock operation and if required it can\n"
- "reject the operation.<br>\n"
- "&nbsp;- - each clock operation is </tt></big></big><big><big><tt>actually</tt></big></big><big><big><tt>\n"
- "executed only if all the </tt><tt>platform_</tt><tt>devices accept the\n"
- "operation it-self<br>\n"
- "<br>\n"
- "<br>\n"
- "Moreover a common clock framework could be used to avoid a lot of\n"
- "duplicated and/or similar code<br>\n"
- "&nbsp;just a grep of 'EXPORT_SYMBOL\\(clk_enable' under arch/arm finds 22\n"
- "entries.<br>\n"
- "<br>\n"
- "The patch is based on a 2.6.30 kernel also if it has a preliminary\n"
- "integration with the PM_RUNTIME<br>\n"
- "&nbsp;support.<br>\n"
- "<br>\n"
- "It works on our st40 (an sh4 cpu based system) no test/porting was done\n"
- "on any ARM platform.<br>\n"
- "<br>\n"
- "It would be mainly a starting point for a discussion and I'm available\n"
- "to extend/fix/share it.<br>\n"
- "<br>\n"
- "Regards<br>\n"
- "&nbsp;Francesco</tt></big></big><br>\n"
- "</body>\n"
- "</html>\n"
- "\01:2\0"
- "fn\00001-generic-clock-framework.patch\0"
- "b\0"
- "From 4e065fb9247ec511bfdc88001f0713977d3f4e89 Mon Sep 17 00:00:00 2001\n"
- "From: Francesco Virlinzi <francesco.virlinzi@st.com>\n"
- "Date: Fri, 23 Oct 2009 15:26:42 +0200\n"
- "Subject: [PATCH] generic clock framework\n"
- "\n"
- "version: 0.6.2\n"
- "\n"
- "Signed-off-by: Francesco Virlinzi <francesco.virlinzi@st.com>\n"
- "---\n"
- " drivers/base/Makefile           |    4 +\n"
- " drivers/base/base.h             |    5 +\n"
- " drivers/base/clk.c              | 1606 +++++++++++++++++++++++++++++++++++++++\n"
- " drivers/base/clk.h              |  319 ++++++++\n"
- " drivers/base/clk_pm.c           |  197 +++++\n"
- " drivers/base/clk_utils.c        |  456 +++++++++++\n"
- " drivers/base/init.c             |    1 +\n"
- " drivers/base/platform.c         |   27 +\n"
- " include/linux/clk.h             |  251 ++++++\n"
- " include/linux/platform_device.h |    9 +\n"
- " init/Kconfig                    |   23 +\n"
- " 11 files changed, 2898 insertions(+), 0 deletions(-)\n"
- " create mode 100644 drivers/base/clk.c\n"
- " create mode 100644 drivers/base/clk.h\n"
- " create mode 100644 drivers/base/clk_pm.c\n"
- " create mode 100644 drivers/base/clk_utils.c\n"
- "\n"
- "diff --git a/drivers/base/Makefile b/drivers/base/Makefile\n"
- "index b5b8ba5..b78a2bf 100644\n"
- "--- a/drivers/base/Makefile\n"
- "+++ b/drivers/base/Makefile\n"
- "@@ -16,6 +16,10 @@ ifeq ($(CONFIG_SYSFS),y)\n"
- " obj-$(CONFIG_MODULES)\t+= module.o\n"
- " endif\n"
- " obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o\n"
- "+ifdef CONFIG_GENERIC_CLK_FM\n"
- "+obj-y\t\t\t+= clk.o clk_utils.o\n"
- "+obj-$(CONFIG_PM)\t+= clk_pm.o\n"
- "+endif\n"
- " \n"
- " ifeq ($(CONFIG_DEBUG_DRIVER),y)\n"
- " EXTRA_CFLAGS += -DDEBUG\n"
- "diff --git a/drivers/base/base.h b/drivers/base/base.h\n"
- "index b528145..bc5b9e8 100644\n"
- "--- a/drivers/base/base.h\n"
- "+++ b/drivers/base/base.h\n"
- "@@ -94,6 +94,11 @@ extern int devices_init(void);\n"
- " extern int buses_init(void);\n"
- " extern int classes_init(void);\n"
- " extern int firmware_init(void);\n"
- "+#ifdef CONFIG_GENERIC_CLK_FM\n"
- "+extern int clock_init(void);\n"
- "+#else\n"
- "+static inline int clock_init(void){ return 0; }\n"
- "+#endif\n"
- " #ifdef CONFIG_SYS_HYPERVISOR\n"
- " extern int hypervisor_init(void);\n"
- " #else\n"
- "diff --git a/drivers/base/clk.c b/drivers/base/clk.c\n"
- "new file mode 100644\n"
- "index 0000000..7feae61\n"
- "--- /dev/null\n"
- "+++ b/drivers/base/clk.c\n"
- "@@ -0,0 +1,1606 @@\n"
- "+/*\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * clk.c\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * (C) STMicroelectronics 2008\n"
- "+ * (C) STMicroelectronics 2009\n"
- "+ * Author: Francesco M. Virlinzi <francesco.virlinzi@st.com>\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * May be copied or modified under the terms of the GNU General Public\n"
- "+ * License v.2 ONLY.  See linux/COPYING for more information.\n"
- "+ *\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ */\n"
- "+\n"
- "+#include <linux/platform_device.h>\n"
- "+#include <linux/clk.h>\n"
- "+#include <linux/klist.h>\n"
- "+#include <linux/sysdev.h>\n"
- "+#include <linux/kref.h>\n"
- "+#include <linux/kobject.h>\n"
- "+#include <linux/err.h>\n"
- "+#include <linux/spinlock.h>\n"
- "+#include <asm/atomic.h>\n"
- "+#include \"clk.h\"\n"
- "+#include \"base.h\"\n"
- "+\n"
- "+#define CLK_NAME\t\t\"Generic Clk Framework\"\n"
- "+#define CLK_VERSION\t\t\"0.6.2\"\n"
- "+\n"
- "+/* #define CLK_SAFE_CODE */\n"
- "+\n"
- "+klist_entry_support(clock, clk, node)\n"
- "+klist_entry_support(child_clock, clk, child_node)\n"
- "+klist_entry_support(dev_info, pdev_clk_info, node)\n"
- "+\n"
- "+#define to_clk(ptr)\tcontainer_of(ptr, struct clk, kobj)\n"
- "+#define to_tnode(ptr)\tcontainer_of(ptr, struct clk_tnode, pnode)\n"
- "+\n"
- "+static int sysfs_clk_attr_show(struct kobject *kobj,\n"
- "+\t\t\t\tstruct attribute *attr, char *buf)\n"
- "+{\n"
- "+\tssize_t ret = -EIO;\n"
- "+\tstruct kobj_attribute *kattr\n"
- "+\t    = container_of(attr, struct kobj_attribute, attr);\n"
- "+\tif (kattr->show)\n"
- "+\t\tret = kattr->show(kobj, kattr, buf);\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static ssize_t\n"
- "+sysfs_clk_attr_store(struct kobject *kobj, struct attribute *attr,\n"
- "+\t\t\tconst char *buf, size_t count)\n"
- "+{\n"
- "+\tssize_t ret = -EIO;\n"
- "+\tstruct kobj_attribute *kattr\n"
- "+\t    = container_of(attr, struct kobj_attribute, attr);\n"
- "+\tif (kattr->store)\n"
- "+\t\tret = kattr->store(kobj, kattr, buf, count);\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static struct sysfs_ops clk_sysfs_ops = {\n"
- "+\t.show = sysfs_clk_attr_show,\n"
- "+\t.store = sysfs_clk_attr_store,\n"
- "+};\n"
- "+\n"
- "+static struct kobj_type ktype_clk = {\n"
- "+\t.sysfs_ops = &clk_sysfs_ops,\n"
- "+};\n"
- "+\n"
- "+static struct clk *check_clk(struct clk *);\n"
- "+\n"
- "+static struct kobject *clk_kobj;\n"
- "+static DEFINE_MUTEX(clk_list_sem);\n"
- "+static atomic_t transaction_counter = ATOMIC_INIT(0);\n"
- "+struct klist clk_list = KLIST_INIT(clk_list, NULL, NULL);\n"
- "+\n"
- "+klist_function_support(child, clk, child_node, kobj)\n"
- "+klist_function_support(device, pdev_clk_info, node, pdev->dev.kobj)\n"
- "+\n"
- "+/*\n"
- "+ * The ___clk_xxx operations doesn't raise propagation\n"
- "+ * they are used to operate on the real clock\n"
- "+ */\n"
- "+static int\n"
- "+__clk_operations(struct clk *clk, unsigned long rate,\n"
- "+\tenum clk_ops_id const id_ops)\n"
- "+{\n"
- "+\tint ret = 0;\n"
- "+\tunsigned long *ops_fns = (unsigned long *)clk->ops;\n"
- "+\tif (likely(ops_fns && ops_fns[id_ops])) {\n"
- "+\t\tint (*fns)(struct clk *clk, unsigned long rate)\n"
- "+\t\t\t= (void *)ops_fns[id_ops];\n"
- "+\t\tunsigned long flags;\n"
- "+\t\tspin_lock_irqsave(&clk->lock, flags);\n"
- "+\t\tret = fns(clk, rate);\n"
- "+\t\tspin_unlock_irqrestore(&clk->lock, flags);\n"
- "+\t}\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static inline int __clk_init(struct clk *clk)\n"
- "+{\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\treturn __clk_operations(clk, 0, __CLK_INIT);\n"
- "+}\n"
- "+static inline int __clk_enable(struct clk *clk)\n"
- "+{\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\treturn __clk_operations(clk, 0, __CLK_ENABLE);\n"
- "+}\n"
- "+static inline int __clk_disable(struct clk *clk)\n"
- "+{\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\treturn __clk_operations(clk, 0, __CLK_DISABLE);\n"
- "+}\n"
- "+static inline int __clk_set_rate(struct clk *clk, unsigned long rate)\n"
- "+{\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\treturn __clk_operations(clk, rate, __CLK_SET_RATE);\n"
- "+}\n"
- "+static inline int __clk_set_parent(struct clk *clk, struct clk *parent)\n"
- "+{\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\treturn __clk_operations(clk, (unsigned long)parent, __CLK_SET_PARENT);\n"
- "+}\n"
- "+static inline int __clk_recalc_rate(struct clk *clk)\n"
- "+{\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\treturn __clk_operations(clk, 0, __CLK_RECALC);\n"
- "+}\n"
- "+static inline int __clk_round(struct clk *clk, unsigned long value)\n"
- "+{\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\treturn __clk_operations(clk, value, __CLK_ROUND);\n"
- "+}\n"
- "+\n"
- "+static inline int __clk_eval(struct clk *clk, unsigned long prate)\n"
- "+{\n"
- "+#ifndef CONFIG_CLK_FORCE_GENERIC_EVALUATE\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\treturn\t__clk_operations(clk, prate, __CLK_EVAL);\n"
- "+#else\n"
- "+\tunsigned long rate, flags;\n"
- "+\tpr_debug(\": %s\\n\", clk->name);\n"
- "+\tif (likely(clk->ops && clk->ops->eval)) {\n"
- "+\t\tspin_lock_irqsave(&clk->lock, flags);\n"
- "+\t\trate = clk->ops->eval(clk, prate);\n"
- "+\t\tspin_unlock_irqrestore(&clk->lock, flags);\n"
- "+\t} else\n"
- "+\t\trate = clk_generic_evaluate_rate(clk, prate);\n"
- "+\treturn rate;\n"
- "+#endif\n"
- "+}\n"
- "+\n"
- "+#ifdef CONFIG_PM_RUNTIME\n"
- "+static int\n"
- "+clk_pm_runtime_devinfo(enum rpm_status code, struct pdev_clk_info *info)\n"
- "+{\n"
- "+\tstruct platform_device *pdev = info->pdev;\n"
- "+\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tswitch (code) {\n"
- "+\tcase RPM_ACTIVE:\n"
- "+\t\treturn clk_notify_child_event(CHILD_DEVICE_ENABLED, info->clk);\n"
- "+\tcase RPM_SUSPENDED:\n"
- "+\t\treturn clk_notify_child_event(CHILD_DEVICE_DISABLED, info->clk);\n"
- "+\t}\n"
- "+\treturn -EINVAL;\n"
- "+}\n"
- "+\n"
- "+int clk_pm_runtime_device(enum rpm_status code, struct platform_device *dev)\n"
- "+{\n"
- "+\tint idx;\n"
- "+\tint ret = 0;\n"
- "+\tstruct pdev_clk_info *info;\n"
- "+\n"
- "+\tif (!dev)\n"
- "+\t\treturn -EFAULT;\n"
- "+\n"
- "+\tif (!dev->clks || !pdevice_num_clocks(dev))\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tpr_debug(\"\\n\");\n"
- "+/*\n"
- "+ *\tCheck if the device is under a transaction.\n"
- "+ * \tIf so the GCFdoesn't raise a 'clk_pm_runtime_devinfo'\n"
- "+ *\tall the device change will be notified on 'tnode_transaction_complete'\n"
- "+ *\tif required....\n"
- "+ */\n"
- "+\tif (atomic_read((atomic_t *)&dev->clk_flags)) {\n"
- "+\t\tpr_debug(\"%s.%d under transaction\\n\", dev->name, dev->id);\n"
- "+\t\treturn ret;\n"
- "+\t}\n"
- "+\tfor (idx = 0, info = dev->clks; idx < pdevice_num_clocks(dev); ++idx)\n"
- "+\t\tret |= clk_pm_runtime_devinfo(&info[idx], state, 0);\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+#else\n"
- "+#define clk_pm_runtime_devinfo(x, y)\n"
- "+#define clk_pm_runtime_device(x, y)\n"
- "+#endif\n"
- "+\n"
- "+/**\n"
- "+ * tnode_malloc\n"
- "+ *\n"
- "+ * Allocs the memory for both the transaction and the\n"
- "+ * clk_event objects\n"
- "+ */\n"
- "+static struct clk_tnode *tnode_malloc(struct clk_tnode *parent,\n"
- "+\tunsigned long nevent)\n"
- "+{\n"
- "+\tstruct clk_event *evt;\n"
- "+\tstruct clk_tnode *node;\n"
- "+\n"
- "+\tif (nevent > 32)\n"
- "+\t\treturn NULL;\n"
- "+\n"
- "+\tnode = kmalloc(sizeof(*node) + nevent *\tsizeof(*evt), GFP_KERNEL);\n"
- "+\n"
- "+\tif (!node)\n"
- "+\t\treturn NULL;\n"
- "+\n"
- "+\tevt = (struct clk_event *)(sizeof(struct clk_tnode) + (long)node);\n"
- "+\n"
- "+\tnode->tid    = atomic_inc_return(&transaction_counter);\n"
- "+\tnode->parent = parent;\n"
- "+\tnode->size   = nevent;\n"
- "+\tnode->events = evt;\n"
- "+\tnode->events_map = 0;\n"
- "+\tINIT_LIST_HEAD(&node->childs);\n"
- "+\n"
- "+\treturn node;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * tnode_free\n"
- "+ *\n"
- "+ * Free the tnode memory\n"
- "+ */\n"
- "+static void tnode_free(struct clk_tnode *node)\n"
- "+{\n"
- "+\tif (tnode_get_parent(node)) {\n"
- "+\t\tlist_del(&node->pnode);\n"
- "+\t\tkfree(node);\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ *  tnode_check_clock -\n"
- "+ *\n"
- "+ *  @node: the tnode object\n"
- "+ *  @clk:  the clock object\n"
- "+ *\n"
- "+ *  returns a boolean value\n"
- "+ *  it checks if the clock (clk) is managed by the\n"
- "+ *  tnode (node) or any parent node\n"
- "+ */\n"
- "+static int __must_check\n"
- "+tnode_check_clock(struct clk_tnode *node, struct clk *clk)\n"
- "+{\n"
- "+\tint j;\n"
- "+\tfor (; node; node = tnode_get_parent(node))\n"
- "+\t\t/* scans all the event */\n"
- "+\t\ttnode_for_each_valid_events(node, j)\n"
- "+\t\t\tif (tnode_get_clock(node, j) == clk)\n"
- "+\t\t\t\t\treturn 1; /* FOUND!!! */\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+  * tnode_lock_clocks -\n"
- "+  *\n"
- "+  * @node: the tnode object\n"
- "+  *\n"
- "+  * marks all the clocks under transaction to be sure there is no more\n"
- "+  * than one transaction for each clock\n"
- "+  */\n"
- "+static int __must_check\n"
- "+tnode_lock_clocks(struct clk_tnode *node)\n"
- "+{\n"
- "+\tint i;\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\t/* 1. try to mark all the clocks in transaction */\n"
- "+\tfor (i = 0; i < tnode_get_size(node); ++i)\n"
- "+\t\tif (clk_set_towner(tnode_get_clock(node, i), node)) {\n"
- "+\t\t\tstruct clk *clkp = tnode_get_clock(node, i);\n"
- "+\t\t\t/* this clock is already locked */\n"
- "+\t\t\t/* we accept that __only__ if it is locked by a\n"
- "+\t\t\t * parent tnode!!!\n"
- "+\t\t\t */\n"
- "+\t\t\tif (!tnode_get_parent(node)) {\n"
- "+\t\t\t\tpr_debug(\"Error clk %s locked but \"\n"
- "+\t\t\t\t\t  \"there is no parent!\\n\", clkp->name);\n"
- "+\t\t\t\tgoto err_0;\n"
- "+\t\t\t}\n"
- "+\t\t\tpr_debug(\"clk %s already locked\\n\", clkp->name);\n"
- "+\t\t\tif (tnode_check_clock(tnode_get_parent(node), clkp)) {\n"
- "+\t\t\t\tpr_debug(\"ok clk %s locked \"\n"
- "+\t\t\t\t\t  \"by a parent\\n\", clkp->name);\n"
- "+\t\t\t\tcontinue;\n"
- "+\t\t\t} else\n"
- "+\t\t\t\tgoto err_0;\n"
- "+\t\t} else\n"
- "+\t\t\t/* set the event as valid in the bitmap*/\n"
- "+\t\t\ttnode_set_map_id(node, i);\n"
- "+\n"
- "+/*\n"
- "+ * all the clocks are marked succesfully or all the clock on\n"
- "+ * this tnode are already managed by parent\n"
- "+ */\n"
- "+\tif (!tnode_get_map(node)) { /* check if the bitamp is not zero */\n"
- "+\t\tif (tnode_get_parent(node))\n"
- "+\t\t\tkfree(node);\n"
- "+\t\treturn 1;\n"
- "+\t}\n"
- "+\n"
- "+ /*\n"
- "+ * all the clocks are marked succesfully _and_ there is at least\n"
- "+ * one clock marked.\n"
- "+ * Add the tnode to its parent! and return\n"
- "+ */\n"
- "+\tif (tnode_get_parent(node))\n"
- "+\t\tlist_add_tail(&node->pnode, &tnode_get_parent(node)->childs);\n"
- "+\n"
- "+\treturn 0;\n"
- "+\n"
- "+err_0:\n"
- "+\tpr_debug(\"Error on clock locking...\\n\");\n"
- "+\tfor (--i; i >= 0; --i)\n"
- "+\t\tif (tnode_check_map_id(node, i))\n"
- "+\t\t\tclk_clean_towner(tnode_get_clock(node, i));\n"
- "+\n"
- "+\tif (tnode_get_parent(node))\n"
- "+\t\tkfree(node);\n"
- "+\n"
- "+\treturn -EINVAL;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * tnode_transaction_complete -\n"
- "+ *\n"
- "+ * checks the devices status when the transaction is complete.\n"
- "+ */\n"
- "+static void tnode_transaction_complete(struct clk_tnode *node)\n"
- "+{\n"
- "+\tstruct klist_iter i;\n"
- "+\tstruct pdev_clk_info *dev_info;\n"
- "+\tint j;\n"
- "+\n"
- "+\tpr_debug(\"tid: %d\\n\", (int)tnode_get_id(node));\n"
- "+\ttnode_for_each_valid_events(node, j) {\n"
- "+\tklist_iter_init(&tnode_get_clock(node, j)->devices, &i);\n"
- "+\twhile ((dev_info = next_dev_info(&i))) {\n"
- "+\t\t/* update the device state */\n"
- "+\t\tstruct platform_device *dev = dev_info->pdev;\n"
- "+\t\tswitch (dev->clk_state & (DEV_SUSPENDED_ON_TRANSACTION |\n"
- "+\t\t\t\t\t  DEV_RESUMED_ON_TRANSACTION)) {\n"
- "+\t\tcase 0: /* this device doesn't care on the clock transaction */\n"
- "+\t\t\tatomic_clear_mask(DEV_ON_TRANSACTION,\n"
- "+\t\t\t\t(atomic_t *)&dev->clk_state);\n"
- "+\t\t\tbreak;\n"
- "+\n"
- "+\t\tcase (DEV_SUSPENDED_ON_TRANSACTION |\n"
- "+\t\t\tDEV_RESUMED_ON_TRANSACTION):\n"
- "+\t\t\t/* this device was suspended and\n"
- "+\t\t\t * resumed therefore no real change\n"
- "+\t\t\t */\n"
- "+\t\t\tpr_debug(\"dev: %s.%d \"\n"
- "+\t\t\t\t\"Suspended&Resumed (no child event)\\n\",\n"
- "+\t\t\t\tdev->name, dev->id);\n"
- "+\t\t\tatomic_clear_mask(DEV_ON_TRANSACTION |\n"
- "+\t\t\t\t\t  DEV_SUSPENDED_ON_TRANSACTION |\n"
- "+\t\t\t\t\t  DEV_RESUMED_ON_TRANSACTION,\n"
- "+\t\t\t\t\t  (atomic_t *)&dev->clk_state);\n"
- "+\t\t\tbreak;\n"
- "+\t\tcase DEV_SUSPENDED_ON_TRANSACTION:\n"
- "+\t\t\tatomic_clear_mask(DEV_ON_TRANSACTION |\n"
- "+\t\t\t\tDEV_SUSPENDED_ON_TRANSACTION,\n"
- "+\t\t\t\t(atomic_t *)&dev->clk_state);\n"
- "+\t\t\tpr_debug(\"dev: %s.%d Suspended\\n\",\n"
- "+\t\t\t\tdev->name, dev->id);\n"
- "+\t\t\tclk_pm_runtime_device(RPM_SUSPENDED, dev);\n"
- "+\t\t\tbreak;\n"
- "+\t\tcase DEV_RESUMED_ON_TRANSACTION:\n"
- "+\t\t\tatomic_clear_mask(DEV_ON_TRANSACTION |\n"
- "+\t\t\t\tDEV_RESUMED_ON_TRANSACTION,\n"
- "+\t\t\t\t(atomic_t *)&dev->clk_state);\n"
- "+\t\t\tpr_debug(\"dev: %s.%d Resumed\\n\",\n"
- "+\t\t\t\tdev->name, dev->id);\n"
- "+\t\t\tclk_pm_runtime_device(RPM_ACTIVE, dev);\n"
- "+\t\t\tbreak;\n"
- "+\n"
- "+\t\tdefault:\n"
- "+\t\t\tprintk(KERN_ERR \"%s: device %s,%d clk_flags _not_ valid %u\\n\",\n"
- "+\t\t\t\t__func__, dev->name, dev->id,\n"
- "+\t\t\t\t(unsigned int)dev->clk_state);\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\tklist_iter_exit(&i);\n"
- "+\tclk_clean_towner(tnode_get_clock(node, j));\n"
- "+\t}\n"
- "+\tpr_debug(\"tid: %d exit\\n\", (int)tnode_get_id(node));\n"
- "+\treturn;\n"
- "+}\n"
- "+\n"
- "+/*\n"
- "+ * Check if the clk is registered\n"
- "+ */\n"
- "+#ifdef CLK_SAFE_CODE\n"
- "+static struct clk *check_clk(struct clk *clk)\n"
- "+{\n"
- "+\tstruct clk *clkp;\n"
- "+\tstruct clk *result = NULL;\n"
- "+\tstruct klist_iter i;\n"
- "+\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tklist_iter_init(&clk_list, &i);\n"
- "+\twhile ((clkp = next_clock(&i)))\n"
- "+\t\tif (clk == clkp) {\n"
- "+\t\t\tresult = clk;\n"
- "+\t\t\tbreak;\n"
- "+\t\t}\n"
- "+\tklist_iter_exit(&i);\n"
- "+\treturn result;\n"
- "+}\n"
- "+#else\n"
- "+static inline struct clk *check_clk(struct clk *clk)\n"
- "+{\n"
- "+\treturn clk;\n"
- "+}\n"
- "+#endif\n"
- "+\n"
- "+enum child_event_e {\n"
- "+\tCHILD_CLOCK_ENABLED = 1,\n"
- "+\tCHILD_CLOCK_DISABLED,\n"
- "+\tCHILD_DEVICE_ENABLED,\n"
- "+\tCHILD_DEVICE_DISABLED,\n"
- "+};\n"
- "+\n"
- "+static int\n"
- "+clk_notify_child_event(enum child_event_e const code, struct clk *clk)\n"
- "+{\n"
- "+\tif (!clk)\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tswitch (code) {\n"
- "+\tcase CHILD_CLOCK_ENABLED:\n"
- "+\t\t++clk->nr_active_clocks;\n"
- "+\t\tbreak;\n"
- "+\tcase CHILD_CLOCK_DISABLED:\n"
- "+\t\t--clk->nr_active_clocks;\n"
- "+\t\tbreak;\n"
- "+\tcase CHILD_DEVICE_ENABLED:\n"
- "+\t\t++clk->nr_active_devices;\n"
- "+\t\tbreak;\n"
- "+\tcase CHILD_DEVICE_DISABLED:\n"
- "+\t\t--clk->nr_active_devices;\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\tif (clk_is_auto_switching(clk)) {\n"
- "+\t\t/*\n"
- "+\t\t * Check if there are still users\n"
- "+\t\t */\n"
- "+\t\tif (!clk->nr_active_devices && !clk->nr_active_clocks)\n"
- "+\t\t\tclk_disable(clk);\n"
- "+\t\telse if (!clk_get_rate(clk)) /* if off.. turn-on */\n"
- "+\t\t\tclk_enable(clk);\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * clk_dev_events_malloc -\n"
- "+ *\n"
- "+ * builds a struct clk_event array (dev_event).\n"
- "+ * the array size (how many elements) is based on device_num_clocks(dev)\n"
- "+ * the contenets of each element is equal to:\n"
- "+ * - the events array (if the idx-clock is under transaction)\n"
- "+ * - the current clock setting if the idx-clock isn't under transaction\n"
- "+ */\n"
- "+static struct clk_event * __must_check\n"
- "+clk_dev_events_malloc(struct platform_device const *dev)\n"
- "+{\n"
- "+\tstruct clk_event *dev_events;\n"
- "+\tstruct clk_tnode *node;\n"
- "+\tint i, j;\n"
- "+\tpr_debug(\"\\n\");\n"
- "+/*\n"
- "+ * 1.  simple case:\n"
- "+ *\t- device_num_clocks(dev) = 1\n"
- "+ */\n"
- "+\tif (pdevice_num_clocks(dev) == 1) {\n"
- "+\t\tnode = (struct clk_tnode *)pdevice_clock(dev, 0)->towner;\n"
- "+\t\tfor (i = 0; i < tnode_get_size(node); ++i)\n"
- "+\t\t\tif (tnode_get_clock(node, i) == pdevice_clock(dev, 0))\n"
- "+\t\t\t\treturn tnode_get_event(node, i);\n"
- "+\t}\n"
- "+/*\n"
- "+ * 2. - device_num_clocks(dev) > 1\n"
- "+ *\tGCF has to build a dedicated device events (devents) array\n"
- "+ *\tfor this device! sorted as the device registered it-self!\n"
- "+ */\n"
- "+\tdev_events = kmalloc(sizeof(*dev_events) * pdevice_num_clocks(dev),\n"
- "+\t\t\tGFP_KERNEL);\n"
- "+\tif (!dev_events)\n"
- "+\t\treturn NULL;\n"
- "+\n"
- "+\tfor (i = 0; i < pdevice_num_clocks(dev); ++i) {\n"
- "+\t\tnode = (struct clk_tnode *)pdevice_clock(dev, i)->towner;\n"
- "+\t\tdev_events[i].clk = pdevice_clock(dev, i);\n"
- "+\t\tif (!node) {/* this means this clocs isn't under transaction */\n"
- "+\t\t     dev_events[i].old_rate =\n"
- "+\t\t\t\tclk_get_rate(pdevice_clock(dev, i));\n"
- "+\t\t     dev_events[i].new_rate =\n"
- "+\t\t\t\tclk_get_rate(pdevice_clock(dev, i));\n"
- "+\t\t     continue;\n"
- "+\t\t}\n"
- "+\t\t/* search the right clk_event */\n"
- "+\t\tfor (j = 0; tnode_get_clock(node, j) != pdevice_clock(dev, i);\n"
- "+\t\t     ++j);\n"
- "+\n"
- "+\t\tdev_events[i].old_rate = tnode_get_event(node, j)->old_rate;\n"
- "+\t\tdev_events[i].new_rate = tnode_get_event(node, j)->new_rate;\n"
- "+\t}\n"
- "+\treturn dev_events;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * clk_devents_free -\n"
- "+ * free the devent allocated on the device dev.\n"
- "+ */\n"
- "+static inline void\n"
- "+clk_dev_events_free(struct clk_event *dev_events, struct platform_device *dev)\n"
- "+{\n"
- "+\tif (pdevice_num_clocks(dev) == 1)\n"
- "+\t\treturn ;\n"
- "+\tkfree(dev_events);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * clk_trnsc_fsm -\n"
- "+ *\n"
- "+ * propagate the transaction to all the childs\n"
- "+ * each transaction has the following life-time:\n"
- "+ *\n"
- "+ *\t+---------------+\n"
- "+ *\t|    ENTER_CLK\t|   The ENTER state only for clocks\n"
- "+ *\t+---------------+     - acquires all the clock of the transaction\n"
- "+ *\t\t|\t       - builds the transaction graph\n"
- "+ *\t\t|\t      - for each clock generates a child transaction\n"
- "+ *\t\t|\n"
- "+ *   +---------------------+\n"
- "+ *   |\t+---------------+  |\n"
- "+ *   |\t|    ENTER_DEV \t|  |  The ENTER state only for devices\n"
- "+ *   |  +---------------+  |  - >> NOTIFY_CLK_ENTERCHANGE << notified\n"
- "+ *   |\t\t|\t   |  - - the device could refuse the operation\n"
- "+ *   |\t\t|\t   |\n"
- "+ *   |\t+---------------+  |\n"
- "+ *   |\t|    PRE_DEV\t|  |  The PRE state only devices\n"
- "+ *   |\t+---------------+  |  - >> NOTIFY_CLK_PRECHANGE << notified\n"
- "+ *   |\t\t|\t   |  - - the device could be suspended\n"
- "+ *   +---------------------+\n"
- "+ *\t\t|\n"
- "+ *\t+---------------+\n"
- "+ * \t|   CHANGE_CLK\t|    The CHANGE state only for clocks\n"
- "+ *\t+---------------+     - updates all the physical clocks\n"
- "+ *\t\t|\t        and relative clk_event_s according to\n"
- "+ *\t\t|\t        the hw value.\n"
- "+ *   +---------------------+\n"
- "+ *   |\t\t|\t   |\n"
- "+ *   |\t+---------------+  |\n"
- "+ *   |\t|   POST_DEV\t|  |  The POST state only for devices\n"
- "+ *   |  +---------------+  |  - >> NOTIFY_CLK_POSTCHANGE << notified\n"
- "+ *   |\t\t|\t   |  - - the devices could be resumed\n"
- "+ *   |\t\t|\t   |\n"
- "+ *   |\t+---------------+  |\n"
- "+ *   |\t|  EXIT_DEV\t|  |   The EXIT state only for devices\n"
- "+ *   |  +---------------+  |   - >> NOTIFY_CLK_EXITCHANGE << notified\n"
- "+ *   |\t\t|\t   |   - - the devices is aware all the other\n"
- "+ *   +---------------------+\t   devices are resumed.\n"
- "+ *\t\t|\n"
- "+ *\t+---------------+\n"
- "+ *\t|  EXIT_CLK\t|      The EXIT state only for clocks\n"
- "+ *\t+---------------+      (to free all the memory)\n"
- "+ *\t\t\t\t- Free all the allocated memory\n"
- "+ *\n"
- "+ */\n"
- "+\n"
- "+static enum notify_ret_e\n"
- "+clk_trnsc_fsm(enum clk_fsm_e const code, struct clk_tnode *node)\n"
- "+{\n"
- "+\tstruct pdev_clk_info *dev_info;\n"
- "+\tstruct clk_tnode *tchild;\n"
- "+\tstruct klist_iter i;\n"
- "+\tint j;\n"
- "+\tenum notify_ret_e tmp, ret_notifier = NOTIFY_EVENT_HANDLED;\n"
- "+\n"
- "+#ifdef CONFIG_CLK_DEBUG\n"
- "+\tswitch (code) {\n"
- "+\tcase TRNSC_ENTER_CLOCK:\n"
- "+\tcase TRNSC_ENTER_DEVICE:\n"
- "+\t\tprintk(KERN_INFO \"ENTER_%s \",\n"
- "+\t\t\t(code == TRNSC_ENTER_CLOCK ? \"CLK\" : \"DEV\"));\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_PRE_DEVICE:\n"
- "+\t\tprintk(KERN_INFO \"PRE_DEV \");\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_CHANGE_CLOCK:\n"
- "+\t\tprintk(KERN_INFO \"CHANGE_CLK \");\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_POST_DEVICE:\n"
- "+\t\tprintk(KERN_INFO \"POST_DEV \");\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_EXIT_DEVICE:\n"
- "+\tcase TRNSC_EXIT_CLOCK:\n"
- "+\t\tprintk(KERN_INFO \"EXIT_%s \",\n"
- "+\t\t\t(code == TRNSC_EXIT_DEVICE ? \"DEV\" : \"CLK\"));\n"
- "+\t\t\tbreak;\n"
- "+\t}\n"
- "+\tprintk(KERN_INFO\"tid:%u \", (unsigned int)tnode_get_id(node));\n"
- "+\tif (tnode_get_parent(node))\n"
- "+\t\tprintk(KERN_INFO \" (tpid: %d)\",\n"
- "+\t\t\t(int)tnode_get_id(tnode_get_parent(node)));\n"
- "+\tprintk(KERN_INFO \" (0x%x/0x%x) \", (unsigned int)tnode_get_size(node),\n"
- "+\t\t\t(unsigned int)tnode_get_map(node));\n"
- "+\tfor (j = 0; j < tnode_get_size(node); ++j) {\n"
- "+\t\tif (tnode_check_map_id(node, j))\n"
- "+\t\t\t/* print only the valid event... */\n"
- "+\t\t\tprintk(KERN_INFO\"- %s \",\n"
- "+\t\t\t\ttnode_get_clock(node, j)->name);\n"
- "+\t\telse if (code == TRNSC_ENTER_CLOCK)\n"
- "+\t\t\tprintk(KERN_INFO\"- %s \",\n"
- "+\t\t\t\ttnode_get_clock(node, j)->name);\n"
- "+\t}\n"
- "+\tprintk(KERN_INFO\"\\n\");\n"
- "+#endif\n"
- "+\n"
- "+\t/* \n"
- "+\t * Clk ENTER state\n"
- "+\t */\n"
- "+\tif (code == TRNSC_ENTER_CLOCK) {\n"
- "+\t\tunsigned long idx;\n"
- "+\t\tenum clk_event_e sub_code;\n"
- "+\t\tstruct clk *clkp;\n"
- "+\t\tstruct clk_event *sub_event = NULL;\n"
- "+\n"
- "+\t\t/* first of all the GCF tries to lock the clock of this tnode\n"
- "+\t\t * and links the tnode to its parent (if any)\n"
- "+\t\t */\n"
- "+\t\tswitch (tnode_lock_clocks(node)) {\n"
- "+\t\tcase 0:\n"
- "+\t\t\tbreak;\n"
- "+\t\tcase -EINVAL:\n"
- "+\t\t\treturn NOTIFY_EVENT_NOTHANDLED;\n"
- "+\t\tcase 1:\n"
- "+\t\t\treturn NOTIFY_EVENT_HANDLED;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tpr_debug(\"clocks acquired\\n\");\n"
- "+\t\t/* Propagates the events to the sub clks */\n"
- "+\t\ttnode_for_each_valid_events(node, j) {\n"
- "+\n"
- "+\t\tif (!clk_allow_propagation(tnode_get_clock(node, j))) {\n"
- "+\t\t\tpr_debug(\"clk: %s doesn't want propagation\\n\",\n"
- "+\t\t\t\ttnode_get_clock(node, j)->name);\n"
- "+\t\t\tcontinue;\n"
- "+\t\t}\n"
- "+\t\tif (!(tnode_get_clock(node, j)->nr_clocks))\n"
- "+\t\t\tcontinue;\n"
- "+\n"
- "+\t\ttchild = tnode_malloc(node,\n"
- "+\t\t\ttnode_get_clock(node, j)->nr_clocks);\n"
- "+\t\tif (!tchild) {\n"
- "+\t\t\tprintk(KERN_ERR \"No enough memory during a clk \"\n"
- "+\t\t\t\t\t\"transaction\\n\");\n"
- "+\t\t\tret_notifier |= NOTIFY_EVENT_NOTHANDLED;;\n"
- "+\t\t\treturn ret_notifier;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tpr_debug(\"memory for child transaction acquired\\n\");\n"
- "+\t\tidx = 0;\n"
- "+\t\tsub_code = clk_event_decode(tnode_get_event(node, j));\n"
- "+\t\tklist_iter_init(&tnode_get_clock(node, j)->childs, &i);\n"
- "+\t\twhile ((clkp = next_child_clock(&i))) {\n"
- "+\t\t\tsub_event = tnode_get_event(tchild, idx);\n"
- "+\t\t\tclk_event_init(sub_event, clkp, clk_get_rate(clkp),\n"
- "+\t\t\t\tclk_get_rate(clkp));\n"
- "+\t\t\tswitch (sub_code) {/* prepare the sub event fields */\n"
- "+\t\t\tcase _CLK_CHANGE:\n"
- "+\t\t\tcase _CLK_ENABLE:\n"
- "+\t\t\t\tsub_event->new_rate = clk_evaluate_rate(clkp,\n"
- "+\t\t\t\t\ttnode_get_event(node, j)->new_rate);\n"
- "+\t\t\t\tbreak;\n"
- "+\t\t\tcase _CLK_DISABLE:\n"
- "+\t\t\t\tsub_event->new_rate = 0;\n"
- "+\t\t\t\tbreak;\n"
- "+\t\t\tcase _CLK_NOCHANGE:\n"
- "+\t\t\t\tbreak;\n"
- "+\t\t\t}\n"
- "+\t\t\t++idx;\n"
- "+\t\t\t}\n"
- "+\t\tklist_iter_exit(&i);\n"
- "+\t\t/* now GCF can araiese the sub transaction */\n"
- "+\t\tret_notifier |=\n"
- "+\t\t\tclk_trnsc_fsm(code, tchild);\n"
- "+\t\t}\n"
- "+\t\treturn ret_notifier;\n"
- "+\t}\n"
- "+\n"
- "+\t/*\n"
- "+\t * Clk CHANGE state\n"
- "+\t */\n"
- "+\tif (code == TRNSC_CHANGE_CLOCK) {\n"
- "+\t\t/* the clocks on the root node are managed directly in the\n"
- "+\t\t * clk_set_rate/clk_enable/... functions ...\n"
- "+\t\t * while all the other clocks have to managed here!\n"
- "+\t\t */\n"
- "+\t\tif (node->parent)\n"
- "+\t\t\ttnode_for_each_valid_events(node, j) {\n"
- "+\t\t\t\tstruct clk_event *event;\n"
- "+\t\t\t\tlong code;\n"
- "+\t\t\t\tevent = tnode_get_event(node, j);\n"
- "+\t\t\t\tcode = clk_event_decode(event);\n"
- "+\t\t\t\tswitch (code) {\n"
- "+\t\t\t\tcase _CLK_CHANGE:\n"
- "+\t\t\t\t\t__clk_recalc_rate(event->clk);\n"
- "+\t\t\t\t\tevent->new_rate =\n"
- "+\t\t\t\t\t\tclk_get_rate(event->clk);\n"
- "+\t\t\t\t\tbreak;\n"
- "+\t\t\t\tcase _CLK_ENABLE:\n"
- "+\t\t\t\t\tif (clk_follow_parent(event->clk)) {\n"
- "+\t\t\t\t\t\t__clk_enable(event->clk);\n"
- "+\t\t\t\t\t\tevent->new_rate =\n"
- "+\t\t\t\t\t\tclk_get_rate(event->clk);\n"
- "+\t\t\t\t\t}\n"
- "+\t\t\t\t\tbreak;\n"
- "+\t\t\t\tcase _CLK_DISABLE:\n"
- "+\t\t\t\t\tif (clk_is_enabled(event->clk))\n"
- "+\t\t\t\t\t\t__clk_disable(event->clk);\n"
- "+\t\t\t\t\tbreak;\n"
- "+\t\t\t\t}\n"
- "+\t\t\t}\n"
- "+\n"
- "+\t\tlist_for_each_entry(tchild, &node->childs, pnode)\n"
- "+\t\t\tret_notifier |= clk_trnsc_fsm(code, tchild);\n"
- "+\n"
- "+\t\treturn ret_notifier;\n"
- "+\t}\n"
- "+\n"
- "+\t/*\n"
- "+\t * Clk EXIT state\n"
- "+\t */\n"
- "+\tif (code == TRNSC_EXIT_CLOCK) {\n"
- "+\t\tstruct list_head *ptr, *next;\n"
- "+\t\t/* scans all the transaction childs */\n"
- "+\t\tlist_for_each_safe(ptr, next, &node->childs)\n"
- "+\t\t\tclk_trnsc_fsm(code, to_tnode(ptr));\n"
- "+\n"
- "+\t\t/* update the devices/clocks state */\n"
- "+\t\ttnode_transaction_complete(node);\n"
- "+\n"
- "+\t\ttnode_free(node);\n"
- "+\t\tpr_debug(\"EXIT_CLK complete\\n\");\n"
- "+\n"
- "+\t\treturn ret_notifier;\n"
- "+\t}\n"
- "+\n"
- "+\t/*\n"
- "+\t * Here the devices management\n"
- "+\t */\n"
- "+\ttnode_for_each_valid_events(node, j) {\n"
- "+\t\tif (!clk_allow_propagation(tnode_get_clock(node, j)))\n"
- "+\t\t\tcontinue;\n"
- "+\tklist_iter_init(&tnode_get_clock(node, j)->devices, &i);\n"
- "+\twhile ((dev_info = next_dev_info(&i))) {\n"
- "+\t\tstruct platform_device *pdev = dev_info->pdev;\n"
- "+\t\tstruct platform_driver *pdrv = \tcontainer_of(\n"
- "+\t\t\tpdev->dev.driver, struct platform_driver, driver);\n"
- "+\n"
- "+\t\tstruct clk_event *dev_events;\n"
- "+\n"
- "+\t\tif (!pdrv || !pdrv->notify) {\n"
- "+\t\t\tpr_debug(\n"
- "+\t\t\t\"device %s.%d registered with no notify function\\n\",\n"
- "+\t\t\t\tpdev->name, pdev->id);\n"
- "+\t\t\tcontinue;\n"
- "+\t\t}\n"
- "+\t\t/* check if it already had a 'code' event */\n"
- "+\t\tif (pdev_transaction_move_on(pdev, code))\n"
- "+\t\t\tcontinue;\n"
- "+\n"
- "+\t\tdev_events = clk_dev_events_malloc(pdev);\n"
- "+\t\tif (!dev_events) {\n"
- "+\t\t\tprintk(KERN_ERR\"%s: No Memory during a clk \"\n"
- "+\t\t\t\t\"transaction\\n\", __func__);\n"
- "+\t\t\tcontinue;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\t/* GCF can use 'code' directly in the .notify function\n"
- "+\t\t * just because external 'NOTIFY_CLK_xxxCHANGE' code\n"
- "+\t\t * matchs with the internal 'device' code\n"
- "+\t\t */\n"
- "+\t\ttmp = pdrv->notify(code, pdev, dev_events);\n"
- "+\t\tclk_dev_events_free(dev_events, pdev);\n"
- "+\t\tret_notifier |= tmp;\n"
- "+#ifdef CONFIG_PM_RUNTIME\n"
- "+\t\tif (code == TRNSC_PRE_DEVICE && tmp == NOTIFY_EVENT_HANDLED) {\n"
- "+\t\t\tprintk(KERN_INFO \"clk %s on code %u suspends \"\n"
- "+\t\t\t\t\"device %s.%d\\n\",\n"
- "+\t\t\t\ttransaction_get_clock(node, j)->name,\n"
- "+\t\t\t\t(unsigned int)code, pdev->name, pdev->id);\n"
- "+\t\t\tpm_runtime_suspend(&pdev->dev);\n"
- "+\t\t} else\n"
- "+\t\tif (code == TRNSC_POST_DEVICE && tmp == NOTIFY_EVENT_HANDLED) {\n"
- "+\t\t\tprintk(KERN_INFO \"clk %s on code %u resumes \"\n"
- "+\t\t\t\t\"device %s.%d\\n\",\n"
- "+\t\t\t\ttransaction_get_clock(node, j)->name,\n"
- "+\t\t\t\t(unsigned int)code, pdev->name, pdev->id);\n"
- "+\t\t\tpm_runtime_resume(&pdev->dev);\n"
- "+\t\t};\n"
- "+#endif\n"
- "+\t} /* while closed */\n"
- "+\tklist_iter_exit(&i);\n"
- "+\t} /* for closed */\n"
- "+\n"
- "+\t/*\n"
- "+\t *and propagate down...\n"
- "+\t */\n"
- "+\tlist_for_each_entry(tchild, &node->childs, pnode)\n"
- "+\t\t\tret_notifier |= clk_trnsc_fsm(code, tchild);\n"
- "+\n"
- "+\treturn ret_notifier;\n"
- "+}\n"
- "+\n"
- "+static void clk_initialize(struct clk *clk)\n"
- "+{\n"
- "+\tkobject_init(&clk->kobj, &ktype_clk);\n"
- "+\tkobject_set_name(&clk->kobj, \"%s\", clk->name);\n"
- "+\tkobject_get(&clk->kobj);\n"
- "+\n"
- "+\tclk->nr_clocks = 0;\n"
- "+\tclk->nr_active_clocks = 0;\n"
- "+\tclk->nr_active_devices = 0;\n"
- "+\tclk->towner = NULL;\n"
- "+\n"
- "+\tklist_init(&clk->childs, klist_get_child, klist_put_child);\n"
- "+\tklist_init(&clk->devices, klist_get_device, klist_put_device);\n"
- "+\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+  * clk_register -\n"
- "+  *\n"
- "+  * registers a new clk in the system.\n"
- "+  * returns zero if success\n"
- "+  */\n"
- "+int clk_register(struct clk *clk)\n"
- "+{\n"
- "+\tint ret = 0;\n"
- "+\tif (!clk)\n"
- "+\t\treturn -EFAULT;\n"
- "+\tpr_debug(\"%s\\n\", clk->name);\n"
- "+\n"
- "+\tclk_initialize(clk);\n"
- "+\n"
- "+\t/* Initialize ... */\n"
- "+\t__clk_init(clk);\n"
- "+\n"
- "+\tif (clk->parent) {\n"
- "+#ifdef CLK_SAFE_CODE\n"
- "+\t\t/* 1. the parent has to be registered */\n"
- "+\t\tif (!check_clk(clk->parent))\n"
- "+\t\t\treturn -ENODEV;\n"
- "+\t\t/* 2. an always enabled child has to sit on a always\n"
- "+\t\t *    enabled parent!\n"
- "+\t\t */\n"
- "+\t\tif (clk->flags & CLK_ALWAYS_ENABLED &&\n"
- "+\t\t\t!(clk->parent->flags & CLK_ALWAYS_ENABLED))\n"
- "+\t\t\treturn -EFAULT;\n"
- "+\t\t/* 3. a fixed child has to sit on a fixed parent */\n"
- "+\t\tif (clk_is_readonly(clk) && !clk_is_readonly(clk->parent))\n"
- "+\t\t\treturn -EFAULT;\n"
- "+#endif\n"
- "+\t\tklist_add_tail(&clk->child_node, &clk->parent->childs);\n"
- "+\t\tclk->parent->nr_clocks++;\n"
- "+\t}\n"
- "+\n"
- "+\tret = kobject_add(&clk->kobj,\n"
- "+\t\t(clk->parent ? &clk->parent->kobj : clk_kobj), clk->name);\n"
- "+\tif (ret)\n"
- "+\t\tgoto err_0;\n"
- "+\n"
- "+\tclk->kdevices =\tkobject_create_and_add(\"devices\", &clk->kobj);\n"
- "+\tif (!clk->kdevices)\n"
- "+\t\tgoto err_1;\n"
- "+\n"
- "+\tklist_add_tail(&clk->node, &clk_list);\n"
- "+\tif (clk->flags & CLK_ALWAYS_ENABLED) {\n"
- "+\t\t__clk_enable(clk);\n"
- "+\t\tclk_notify_child_event(CHILD_CLOCK_ENABLED, clk->parent);\n"
- "+\t}\n"
- "+\treturn ret;\n"
- "+\n"
- "+err_1:\n"
- "+\t/* subsystem_remove_file... removed in the common code... ??? */\n"
- "+\tkobject_del(&clk->kobj);\n"
- "+err_0:\n"
- "+\treturn ret;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_register);\n"
- "+\n"
- "+/**\n"
- "+  * clk_unregister -\n"
- "+  * unregisters the clock from system\n"
- "+  */\n"
- "+int clk_unregister(struct clk *clk)\n"
- "+{\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tif (!clk)\n"
- "+\t\treturn -EFAULT;\n"
- "+\n"
- "+\tif (!list_empty(&clk->devices.k_list))\n"
- "+\t\treturn -EFAULT; /* somebody is still using this clock */\n"
- "+\n"
- "+\tkobject_del(clk->kdevices);\n"
- "+\tkfree(clk->kdevices);\n"
- "+\t/* subsystem_remove_file... removed in the common code... ??? */\n"
- "+\tkobject_del(&clk->kobj);\n"
- "+\tklist_del(&clk->node);\n"
- "+\tif (clk->parent) {\n"
- "+\t\tklist_del(&clk->child_node);\n"
- "+\t\tclk->parent->nr_clocks--;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_unregister);\n"
- "+\n"
- "+static int clk_add_devinfo(struct pdev_clk_info *info)\n"
- "+{\n"
- "+\tint ret = 0;\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+#ifdef CLK_SAFE_CODE\n"
- "+\tif (!info || !info->clk || !check_clk(info->clk))\n"
- "+\t\treturn -EFAULT;\n"
- "+#endif\n"
- "+\tret = sysfs_create_link(info->clk->kdevices, &info->pdev->dev.kobj,\n"
- "+\t\tdev_name(&info->pdev->dev));\n"
- "+\tif (ret) {\n"
- "+\t\tpr_debug(\" Error %d\\n\", ret);\n"
- "+\t\treturn ret;\n"
- "+\t}\n"
- "+\tklist_add_tail(&info->node, &info->clk->devices);\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int clk_del_devinfo(struct pdev_clk_info *info)\n"
- "+{\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+#ifdef CLK_SAFE_CODE\n"
- "+\tif (!info || !info->clk || !check_clk(info->clk))\n"
- "+\t\treturn -EFAULT;\n"
- "+#endif\n"
- "+\tsysfs_remove_link(info->clk->kdevices, dev_name(&info->pdev->dev));\n"
- "+\tklist_del(&info->node);\n"
- "+\n"
- "+#ifndef CONFIG_PM_RUNTIME\n"
- "+\t/*\n"
- "+\t * Without PM_RUNTIME the GCF assumes the device is\n"
- "+\t * 'not active' when it's removed\n"
- "+\t */\n"
- "+\tclk_notify_child_event(CHILD_DEVICE_DISABLED, info->clk);\n"
- "+#endif\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+int clk_probe_device(struct platform_device *dev, enum pdev_probe_state state)\n"
- "+{\n"
- "+\tint idx;\n"
- "+\tswitch (state) {\n"
- "+\tcase PDEV_PROBEING:\n"
- "+\t\t/* before the .probe function is called the GCF\n"
- "+\t\t * has to turn-on _all_ the clocks the device uses\n"
- "+\t\t * to garantee a safe .probe\n"
- "+\t\t */\n"
- "+\t\tfor (idx = 0; idx < pdevice_num_clocks(dev); ++idx)\n"
- "+\t\t\tif (pdevice_clock(dev, idx))\n"
- "+\t\t\t\tclk_enable(pdevice_clock(dev, idx));\n"
- "+\t\treturn 0;\n"
- "+\tcase PDEV_PROBED:\n"
- "+#ifdef CONFIG_PM_RUNTIME\n"
- "+\t/*\n"
- "+\t * Here the GCF should check the device's pm_runtime state\n"
- "+\t * And if the device is suspended the clk_frmwk can turn-off the clocks\n"
- "+\t */\n"
- "+#else\n"
- "+\t/*\n"
- "+\t * Without PM_RUNTIME the GCF assumes the device is active\n"
- "+\t */\n"
- "+\tfor (idx = 0; idx < pdevice_num_clocks(dev); ++idx)\n"
- "+\t\tclk_notify_child_event(CHILD_DEVICE_ENABLED,\n"
- "+\t\t\tpdevice_clock(dev, idx));\n"
- "+#endif\n"
- "+\tbreak;\n"
- "+\tcase PDEV_PROBE_FAILED:\n"
- "+\t/*\n"
- "+\t * TO DO something...\n"
- "+\t */\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+int clk_add_device(struct platform_device *dev, enum pdev_add_state state)\n"
- "+{\n"
- "+\tint idx;\n"
- "+\tint ret;\n"
- "+\n"
- "+\tif (!dev)\n"
- "+\t\treturn -EFAULT;\n"
- "+\n"
- "+\tswitch (state) {\n"
- "+\tcase PDEV_ADDING:\n"
- "+\tcase PDEV_ADD_FAILED:\n"
- "+\t\t/*\n"
- "+\t\t * TO DO something\n"
- "+\t\t */\n"
- "+\t\treturn 0;\n"
- "+\tcase PDEV_ADDED:\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\t/* case PDEV_ADDED ... */\n"
- "+\tif (!dev->clks || !pdevice_num_clocks(dev))\n"
- "+\t\treturn 0;\t/* this device will not use\n"
- "+\t\t\t\t   the clk framework */\n"
- "+\n"
- "+\tpr_debug(\"%s.%d with %u clocks\\n\", dev->name, dev->id,\n"
- "+\t\t(unsigned int)pdevice_num_clocks(dev));\n"
- "+\n"
- "+\tdev->clk_state = 0;\n"
- "+\tfor (idx = 0; idx < pdevice_num_clocks(dev); ++idx) {\n"
- "+\t\tif (!pdevice_clock(dev, idx)) {\t/* clk can not be NULL... */\n"
- "+\t\t\tpr_debug(\"Error clock NULL\\n\");\n"
- "+\t\t\tcontinue;\n"
- "+\t\t}\n"
- "+\t\tpr_debug(\"->under %s\\n\", dev->clks[idx].clk->name);\n"
- "+\t\tdev->clks[idx].pdev = dev;\n"
- "+\t\tret = clk_add_devinfo(&dev->clks[idx]);\n"
- "+\t\tif (ret)\n"
- "+\t\t\tgoto err_0;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+err_0:\n"
- "+\tfor (--idx; idx >= 0; --idx)\n"
- "+\t\tclk_del_devinfo(&dev->clks[idx]);\n"
- "+\n"
- "+\treturn -EINVAL;\n"
- "+}\n"
- "+\n"
- "+int clk_del_device(struct platform_device *dev)\n"
- "+{\n"
- "+\tint idx;\n"
- "+\tif (!dev)\n"
- "+\t\treturn -EFAULT;\n"
- "+\n"
- "+\tfor (idx = 0; idx < pdevice_num_clocks(dev); ++idx)\n"
- "+\t\tclk_del_devinfo(&dev->clks[idx]);\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+void clk_put(struct clk *clk)\n"
- "+{\n"
- "+\tif (clk && !IS_ERR(clk))\n"
- "+\t\tkobject_put(&clk->kobj);\n"
- "+}\n"
- "+\n"
- "+static int clk_is_parent(struct clk const *child, struct clk const *parent)\n"
- "+{\n"
- "+\tif (!child || !parent)\n"
- "+\t\treturn 0;\n"
- "+\tif (!child->parent)\n"
- "+\t\treturn 0;\n"
- "+\tif (child->parent == parent)\n"
- "+\t\treturn 1;\n"
- "+\telse\n"
- "+\t\treturn clk_is_parent(child->parent, parent);\n"
- "+}\n"
- "+\n"
- "+int clk_enable(struct clk *clk)\n"
- "+{\n"
- "+\tint ret;\n"
- "+\tstruct clk_tnode transaction;\n"
- "+\tstruct clk_event event;\n"
- "+\n"
- "+\tevent = EVENT(clk, 0, CLK_UNDEFINED_RATE);\n"
- "+\ttransaction = TRANSACTION_ROOT(1, &event);\n"
- "+\n"
- "+\tpr_debug(\"%s\\n\", clk->name);\n"
- "+\n"
- "+\n"
- "+\tif (clk->flags & CLK_ALWAYS_ENABLED || clk_is_enabled(clk))\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tif (clk->parent) {\n"
- "+\t\t/* turn-on the parent if the parent is 'auto_switch' */\n"
- "+\t\tclk_notify_child_event(CHILD_CLOCK_ENABLED, clk->parent);\n"
- "+\n"
- "+\t\tif (!clk_is_enabled(clk->parent)) {\n"
- "+\t\t\t/* the parent is still disabled... */\n"
- "+\t\t\tclk_notify_child_event(CHILD_CLOCK_DISABLED,\n"
- "+\t\t\t\tclk->parent);\n"
- "+\t\t\treturn -EINVAL;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);\n"
- "+\tif (ret) {\n"
- "+\t\tret = -EPERM;\n"
- "+\t\tgoto err_0;\n"
- "+\t}\n"
- "+\n"
- "+\t/* if not zero somebody doens't agree the clock update */\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);\n"
- "+\tif (ret) {\n"
- "+\t\tret = -EPERM;\n"
- "+\t\tgoto err_1;\n"
- "+\t\t}\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);\n"
- "+\n"
- "+\tret = __clk_enable(clk);\n"
- "+\n"
- "+\tevent.new_rate = clk_get_rate(clk);\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);\n"
- "+\n"
- "+err_1:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);\n"
- "+\n"
- "+err_0:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);\n"
- "+\n"
- "+\tif (ret)\n"
- "+\t\tclk_notify_child_event(CHILD_CLOCK_DISABLED, clk->parent);\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_enable);\n"
- "+\n"
- "+/**\n"
- "+ * clk_disable -\n"
- "+ * disables the clock\n"
- "+ * Is isn't really good that it's a 'void' function...\n"
- "+ * but this is common interface\n"
- "+ */\n"
- "+void clk_disable(struct clk *clk)\n"
- "+{\n"
- "+\tstruct clk_tnode transaction;\n"
- "+\tstruct clk_event event;\n"
- "+\tint ret;\n"
- "+\n"
- "+\tevent = EVENT(clk, clk_get_rate(clk), 0);\n"
- "+\ttransaction = TRANSACTION_ROOT(1, &event);\n"
- "+\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tif (clk->flags & CLK_ALWAYS_ENABLED || !clk_is_enabled(clk))\n"
- "+\t\treturn;\n"
- "+\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);\n"
- "+\tif (ret)\n"
- "+\t\tgoto err_0;\n"
- "+\n"
- "+\t/* if not zero somebody doens't agree the clock update */\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);\n"
- "+\tif (ret)\n"
- "+\t\tgoto err_1;\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);\n"
- "+\n"
- "+\t__clk_disable(clk);\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);\n"
- "+\n"
- "+err_0:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);\n"
- "+err_1:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);\n"
- "+\n"
- "+\tclk_notify_child_event(CHILD_CLOCK_DISABLED, clk->parent);\n"
- "+\n"
- "+\treturn ;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_disable);\n"
- "+\n"
- "+unsigned long clk_get_rate(struct clk *clk)\n"
- "+{\n"
- "+\treturn clk->rate;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_get_rate);\n"
- "+\n"
- "+struct clk *clk_get_parent(struct clk *clk)\n"
- "+{\n"
- "+\treturn clk->parent;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_get_parent);\n"
- "+\n"
- "+int clk_set_parent(struct clk *clk, struct clk *parent)\n"
- "+{\n"
- "+\tint ret = -EOPNOTSUPP;\n"
- "+\tstruct clk *old_parent = clk->parent;\n"
- "+\tstruct clk_event event;\n"
- "+\tstruct clk_tnode transaction;\n"
- "+\tint clk_was_enabled = clk_is_enabled(clk);\n"
- "+\n"
- "+\tevent = EVENT(clk, clk_get_rate(clk), CLK_UNDEFINED_RATE);\n"
- "+\ttransaction = TRANSACTION_ROOT(1, &event);\n"
- "+\n"
- "+\tif (!clk || !parent)\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tif (clk->parent == parent)\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tif (clk_was_enabled && !clk_is_enabled(parent))\n"
- "+\t\t/* turn-on parent if possible */\n"
- "+\t\tclk_notify_child_event(CHILD_CLOCK_ENABLED, parent);\n"
- "+\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);\n"
- "+\tif (ret) {\n"
- "+\t\tret = -EPERM;\n"
- "+\t\tgoto err_0;\n"
- "+\t}\n"
- "+\n"
- "+\t/* if not zero somebody doens't agree the clock updated */\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);\n"
- "+\tif (ret) {\n"
- "+\t\tret = -EPERM;\n"
- "+\t\tgoto err_1;\n"
- "+\t}\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);\n"
- "+\n"
- "+\t/* Now we updated the hw */\n"
- "+\tret = __clk_set_parent(clk, parent);\n"
- "+\tif (ret) {\n"
- "+\t\t/* there was a problem...\n"
- "+\t\t * therefore clk is still on the old parent\n"
- "+\t\t */\n"
- "+\t\tclk->parent = old_parent; /* to be safe ! */\n"
- "+\t\tgoto err_2;\n"
- "+\t}\n"
- "+\n"
- "+\tklist_del(&clk->child_node);\n"
- "+\n"
- "+\tclk->parent = parent;\n"
- "+\n"
- "+\tret = kobject_move(&clk->kobj, &clk->parent->kobj);\n"
- "+\tif (ret)\n"
- "+\t\t;\n"
- "+\n"
- "+\tklist_add_tail(&clk->child_node, &clk->parent->childs);\n"
- "+\n"
- "+\tclk->parent->nr_clocks++;\n"
- "+\told_parent->nr_clocks--;\n"
- "+\n"
- "+err_2:\n"
- "+\tevent.new_rate = clk_get_rate(clk);\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);\n"
- "+\n"
- "+err_1:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);\n"
- "+err_0:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);\n"
- "+\n"
- "+\tif (clk_was_enabled && !ret) {\n"
- "+\t\t/* 5. to decrease the old_parent nchild counter */\n"
- "+\t\tclk_notify_child_event(CHILD_CLOCK_DISABLED, old_parent);\n"
- "+\t\t/* 5. increase the new_parent nchild counter */\n"
- "+\t\tclk_notify_child_event(CHILD_CLOCK_ENABLED, clk->parent);\n"
- "+\t\t/* 6. to decrease the old_parent nchild counter */\n"
- "+\t\tclk_notify_child_event(CHILD_CLOCK_DISABLED, old_parent);\n"
- "+\t\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_set_parent);\n"
- "+\n"
- "+int clk_set_rate(struct clk *clk, unsigned long rate)\n"
- "+{\n"
- "+\tint ret = -EOPNOTSUPP;\n"
- "+\tstruct clk_event event;\n"
- "+\tstruct clk_tnode transaction;\n"
- "+\n"
- "+\tevent = EVENT(clk, clk_get_rate(clk), clk_round_rate(clk, rate));\n"
- "+\ttransaction = TRANSACTION_ROOT(1, &event);\n"
- "+\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tif (clk_is_readonly(clk))\n"
- "+\t\t/* read only clock doesn't have to be \"touched\" !!!! */\n"
- "+\t\treturn -EPERM;\n"
- "+\n"
- "+\tif (event.new_rate == clk_get_rate(clk))\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);\n"
- "+\tif (ret) {\n"
- "+\t\tret = -EPERM;\n"
- "+\t\tgoto err_0;\n"
- "+\t}\n"
- "+\n"
- "+\t/* if not zero somebody doens't agree the clock updated */\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);\n"
- "+\tif (ret) {\n"
- "+\t\tret = -EPERM;\n"
- "+\t\tgoto err_1;\n"
- "+\t}\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);\n"
- "+\n"
- "+\t__clk_set_rate(clk, event.new_rate);\n"
- "+\t/* reload new_rate to avoid hw rounding... */\n"
- "+\tevent.new_rate = clk_get_rate(clk);\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);\n"
- "+\tclk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);\n"
- "+\n"
- "+err_1:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);\n"
- "+err_0:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_set_rate);\n"
- "+\n"
- "+long clk_round_rate(struct clk *clk, unsigned long rate)\n"
- "+{\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tif (likely(clk->ops && clk->ops->round))\n"
- "+\t\treturn clk->ops->round(clk, rate);\n"
- "+\treturn rate;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_round_rate);\n"
- "+\n"
- "+unsigned long clk_evaluate_rate(struct clk *clk, unsigned long prate)\n"
- "+{\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\tif (!clk->parent)/* without parent this function has no meaning */\n"
- "+\t\treturn CLK_UNDEFINED_RATE;\n"
- "+\n"
- "+\tif (!prate)/* on parent disabled than disable the child */\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tif (likely(clk->ops && clk->ops->eval))\n"
- "+\t\treturn clk->ops->eval(clk, prate);\n"
- "+\n"
- "+\treturn CLK_UNDEFINED_RATE;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_evaluate_rate);\n"
- "+\n"
- "+int clk_set_rates(struct clk **clks, unsigned long *rates, unsigned long nclks)\n"
- "+{\n"
- "+\tint i, ret = 0;\n"
- "+\tstruct clk_event *evt;\n"
- "+\tstruct clk_tnode transaction = TRANSACTION_ROOT(nclks, NULL)\n"
- "+\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tif (!clks || !rates || !nclks)\n"
- "+\t\treturn -EINVAL;\n"
- "+\tevt = kmalloc(sizeof(*evt) *\n"
- "+\t\ttnode_get_size(&transaction), GFP_KERNEL);\n"
- "+\n"
- "+\tif (!evt)\n"
- "+\t\treturn -ENOMEM;\n"
- "+\n"
- "+\ttnode_set_events(&transaction, evt);\n"
- "+\n"
- "+\tfor (i = 0; i < tnode_get_size(&transaction); ++i) {\n"
- "+\t\ttnode_set_clock(&transaction, i, clks[i]);\n"
- "+\t\ttnode_get_event(&transaction, i)->old_rate =\n"
- "+\t\t\tclk_get_rate(clks[i]);\n"
- "+\t\ttnode_get_event(&transaction, i)->new_rate =\n"
- "+\t\t\tclk_round_rate(clks[i], rates[i]);\n"
- "+\t}\n"
- "+\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_CLOCK, &transaction);\n"
- "+\tif (ret) {\n"
- "+\t\tret = -EPERM;\n"
- "+\t\tgoto err_0;\n"
- "+\t}\n"
- "+\n"
- "+\t/* if not zero somebody doens't agree the clock updated */\n"
- "+\tret = clk_trnsc_fsm(TRNSC_ENTER_DEVICE, &transaction);\n"
- "+\tif (ret) {\n"
- "+\t\tret = -EPERM;\n"
- "+\t\tgoto err_1;\n"
- "+\t}\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_PRE_DEVICE, &transaction);\n"
- "+\n"
- "+\tfor (i = 0; i < tnode_get_size(&transaction); ++i) {\n"
- "+\t\tif (!clk_is_enabled(clks[i]) && rates[i])\n"
- "+\t\t\tret |= __clk_enable(clks[i]);\n"
- "+\t\telse if (clk_is_enabled(clks[i]) && !rates[i])\n"
- "+\t\t\tret |= __clk_disable(clks[i]);\n"
- "+\t\telse\n"
- "+\t\t\tret |= __clk_set_rate(clks[i], rates[i]);\n"
- "+\n"
- "+\t\t/* reload new_rate to avoid hw rounding... */\n"
- "+\t\ttnode_get_event(&transaction, i)->new_rate =\n"
- "+\t\t\tclk_get_rate(clks[i]);\n"
- "+\t}\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_CHANGE_CLOCK, &transaction);\n"
- "+\n"
- "+\tclk_trnsc_fsm(TRNSC_POST_DEVICE, &transaction);\n"
- "+\n"
- "+err_1:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_DEVICE, &transaction);\n"
- "+\n"
- "+err_0:\n"
- "+\tclk_trnsc_fsm(TRNSC_EXIT_CLOCK, &transaction);\n"
- "+\n"
- "+\tkfree(evt);\n"
- "+\treturn ret;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_set_rates);\n"
- "+\n"
- "+struct clk *clk_get(struct device *dev, const char *id)\n"
- "+{\n"
- "+\tstruct clk *clk = NULL;\n"
- "+\tstruct clk *clkp;\n"
- "+\tstruct klist_iter i;\n"
- "+\tint found = 0, idno;\n"
- "+\n"
- "+\tmutex_lock(&clk_list_sem);\n"
- "+#if 0\n"
- "+\tif (dev == NULL || dev->bus != &platform_bus_type)\n"
- "+\t\tidno = -1;\n"
- "+\telse\n"
- "+\t\tidno = to_platform_device(dev)->id;\n"
- "+\n"
- "+\tklist_iter_init(&clk_list, &i);\n"
- "+\twhile ((clkp = next_clock(&i)) && !found)\n"
- "+\t\tif (clk->id == idno && strcmp(id, clk->name) == 0 &&\n"
- "+\t\t\ttry_module_get(clk->owner)) {\n"
- "+\t\t\t\tclk = clkp;\n"
- "+\t\t\t\tfound = 1;\n"
- "+\t\t}\n"
- "+\tklist_iter_exit(&i);\n"
- "+\n"
- "+\tif (found)\n"
- "+\t\tgoto _found;\n"
- "+#endif\n"
- "+\tklist_iter_init(&clk_list, &i);\n"
- "+\twhile ((clkp = next_clock(&i)))\n"
- "+\t\tif (strcmp(id, clkp->name) == 0\n"
- "+\t\t    && try_module_get(clkp->owner)) {\n"
- "+\t\t\tclk = clkp;\n"
- "+\t\t\tbreak;\n"
- "+\t\t}\n"
- "+\tklist_iter_exit(&i);\n"
- "+_found:\n"
- "+\tmutex_unlock(&clk_list_sem);\n"
- "+\treturn clk;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_get);\n"
- "+\n"
- "+int clk_for_each(int (*fn) (struct clk *clk, void *data), void *data)\n"
- "+{\n"
- "+\tstruct clk *clkp;\n"
- "+\tstruct klist_iter i;\n"
- "+\tint result = 0;\n"
- "+\n"
- "+\tif (!fn)\n"
- "+\t\treturn -EFAULT;\n"
- "+\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\tmutex_lock(&clk_list_sem);\n"
- "+\tklist_iter_init(&clk_list, &i);\n"
- "+\n"
- "+\twhile ((clkp = next_clock(&i)))\n"
- "+\t\tresult |= fn(clkp, data);\n"
- "+\n"
- "+\tklist_iter_exit(&i);\n"
- "+\tmutex_unlock(&clk_list_sem);\n"
- "+\treturn result;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_for_each);\n"
- "+\n"
- "+int clk_for_each_child(struct clk *clk,\n"
- "+\tint (*fn) (struct clk *clk, void *data), void *data)\n"
- "+{\n"
- "+\tstruct clk *clkp;\n"
- "+\tstruct klist_iter i;\n"
- "+\tint result = 0;\n"
- "+\n"
- "+\tif (!clk || !fn)\n"
- "+\t\treturn -EFAULT;\n"
- "+\n"
- "+\tklist_iter_init(&clk->childs, &i);\n"
- "+\n"
- "+\twhile ((clkp = next_child_clock(&i)))\n"
- "+\t\tresult |= fn(clkp, data);\n"
- "+\n"
- "+\tklist_iter_exit(&i);\n"
- "+\n"
- "+\treturn result;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_for_each_child);\n"
- "+\n"
- "+static int __init early_clk_complete(struct clk *clk, void *data)\n"
- "+{\n"
- "+\tint ret;\n"
- "+\n"
- "+\tret = kobject_add(&clk->kobj,\n"
- "+\t\t(clk->parent ? &clk->parent->kobj : clk_kobj),\n"
- "+\t\tclk->name);\n"
- "+\tif (ret)\n"
- "+\t\treturn ret;\n"
- "+\n"
- "+\tclk->kdevices = kobject_create_and_add(\"devices\", &clk->kobj);\n"
- "+\tif (!clk->kdevices)\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+int __init early_clk_register(struct clk *clk)\n"
- "+{\n"
- "+\tint retval = 0;\n"
- "+\tif (!clk)\n"
- "+\t\treturn -EFAULT;\n"
- "+\tpr_debug(\"%s\\n\", clk->name);\n"
- "+\n"
- "+\tclk_initialize(clk);\n"
- "+\n"
- "+\t/* Initialize ... */\n"
- "+\t__clk_init(clk);\n"
- "+\n"
- "+\tif (clk->parent) {\n"
- "+#ifdef CLK_SAFE_CODE\n"
- "+\t\t/* 1. the parent has to be registered */\n"
- "+\t\tif (!check_clk(clk->parent))\n"
- "+\t\t\treturn -ENODEV;\n"
- "+\t\t/* 2. an always enabled child has to sit on a always\n"
- "+\t\t *    enabled parent!\n"
- "+\t\t */\n"
- "+\t\tif (clk->flags & CLK_ALWAYS_ENABLED &&\n"
- "+\t\t\t!(clk->parent->flags & CLK_ALWAYS_ENABLED))\n"
- "+\t\t\treturn -EFAULT;\n"
- "+\t\t/* 3. a fixed child has to sit on a fixed parent */\n"
- "+\t\tif (clk_is_readonly(clk) && !clk_is_readonly(clk->parent))\n"
- "+\t\t\treturn -EFAULT;\n"
- "+#endif\n"
- "+\t\tklist_add_tail(&clk->child_node, &clk->parent->childs);\n"
- "+\t\tclk->parent->nr_clocks++;\n"
- "+\t}\n"
- "+\n"
- "+\tklist_add_tail(&clk->node, &clk_list);\n"
- "+\tif (clk->flags & CLK_ALWAYS_ENABLED) {\n"
- "+\t\t__clk_enable(clk);\n"
- "+\t\tclk_notify_child_event(CHILD_CLOCK_ENABLED, clk->parent);\n"
- "+\t}\n"
- "+\treturn retval;\n"
- "+}\n"
- "+\n"
- "+int __init clock_init(void)\n"
- "+{\n"
- "+\tclk_kobj = kobject_create_and_add(\"clocks\", NULL);\n"
- "+\tif (!clk_kobj)\n"
- "+\t\treturn -EINVAL ;\n"
- "+\n"
- "+\tclk_for_each(early_clk_complete, NULL);\n"
- "+\n"
- "+\tprintk(KERN_INFO CLK_NAME \" \" CLK_VERSION \"\\n\");\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "diff --git a/drivers/base/clk.h b/drivers/base/clk.h\n"
- "new file mode 100644\n"
- "index 0000000..61672ef\n"
- "--- /dev/null\n"
- "+++ b/drivers/base/clk.h\n"
- "@@ -0,0 +1,319 @@\n"
- "+/*\n"
- "+   -------------------------------------------------------------------------\n"
- "+   clk.h\n"
- "+   -------------------------------------------------------------------------\n"
- "+   (C) STMicroelectronics 2008\n"
- "+   (C) STMicroelectronics 2009\n"
- "+   Author: Francesco M. Virlinzi <francesco.virlinzi@st.com>\n"
- "+   ----------------------------------------------------------------------------\n"
- "+   May be copied or modified under the terms of the GNU General Public\n"
- "+   License v.2 ONLY.  See linux/COPYING for more information.\n"
- "+\n"
- "+   ------------------------------------------------------------------------- */\n"
- "+\n"
- "+#ifdef CONFIG_GENERIC_CLK_FM\n"
- "+\n"
- "+#include <linux/clk.h>\n"
- "+#include <linux/platform_device.h>\n"
- "+#include <linux/kobject.h>\n"
- "+#include <linux/klist.h>\n"
- "+#include <linux/list.h>\n"
- "+#include <linux/notifier.h>\n"
- "+#include <asm/atomic.h>\n"
- "+\n"
- "+enum clk_ops_id {\n"
- "+\t__CLK_INIT = 0,\n"
- "+\t__CLK_ENABLE,\n"
- "+\t__CLK_DISABLE,\n"
- "+\t__CLK_SET_RATE,\n"
- "+\t__CLK_SET_PARENT,\n"
- "+\t__CLK_RECALC,\n"
- "+\t__CLK_ROUND,\n"
- "+\t__CLK_EVAL,\n"
- "+};\n"
- "+\n"
- "+extern struct klist clk_list;\n"
- "+/**\n"
- "+  * clk_tnode\n"
- "+  *      it's the internal strucure used to track each node\n"
- "+  *      in the transaction graph.\n"
- "+  *      _NO_ api is showed to the other modules\n"
- "+  */\n"
- "+struct clk_tnode {\n"
- "+\t/** @tid: the tnode id */\n"
- "+\tunsigned long tid;\n"
- "+\t/** @size: how may clock are involved in this tnode */\n"
- "+\tunsigned long size;\n"
- "+\t/** @parent: the parent tnode */\n"
- "+\tstruct clk_tnode *parent;\n"
- "+\t/* @events_map: a bitmap to declare the\n"
- "+\t * valid events in this tnode\n"
- "+\t */\n"
- "+\tunsigned long events_map;\n"
- "+\t/** @events: the event array of this tnode */\n"
- "+\tstruct clk_event *events;\n"
- "+\t/** @child: links the childres tnode */\n"
- "+\tstruct list_head childs;\n"
- "+\t/** @pnode: links the tnode to the parent */\n"
- "+\tstruct list_head pnode;\n"
- "+};\n"
- "+\n"
- "+/*\n"
- "+ *  tnode_get_size -\n"
- "+ *  returns the number of events in the transaction\n"
- "+ */\n"
- "+static inline unsigned long\n"
- "+tnode_get_size(struct clk_tnode *tnode)\n"
- "+{\n"
- "+\treturn tnode->size;\n"
- "+}\n"
- "+\n"
- "+static inline unsigned long\n"
- "+tnode_get_map(struct clk_tnode *tnode)\n"
- "+{\n"
- "+\treturn tnode->events_map;\n"
- "+}\n"
- "+\n"
- "+static inline unsigned long\n"
- "+tnode_check_map_id(struct clk_tnode *node, int id)\n"
- "+{\n"
- "+\treturn node->events_map & (1 << id);\n"
- "+}\n"
- "+\n"
- "+static inline void\n"
- "+tnode_set_map_id(struct clk_tnode *node, int id)\n"
- "+{\n"
- "+\tnode->events_map |= (1 << id);\n"
- "+}\n"
- "+\n"
- "+static inline unsigned long\n"
- "+tnode_get_id(struct clk_tnode *node)\n"
- "+{\n"
- "+\treturn node->tid;\n"
- "+}\n"
- "+\n"
- "+static inline struct clk_event*\n"
- "+tnode_get_event(struct clk_tnode *node, int id)\n"
- "+{\n"
- "+\treturn &(node->events[id]);\n"
- "+}\n"
- "+\n"
- "+static inline struct clk_event *tnode_get_events(struct clk_tnode *node)\n"
- "+{\n"
- "+\treturn tnode_get_event(node, 0);\n"
- "+}\n"
- "+\n"
- "+static inline void\n"
- "+tnode_set_events(struct clk_tnode *node, struct clk_event *events)\n"
- "+{\n"
- "+\tnode->events = events;\n"
- "+}\n"
- "+\n"
- "+static inline struct clk*\n"
- "+tnode_get_clock(struct clk_tnode *node, int id)\n"
- "+{\n"
- "+\treturn tnode_get_event(node, id)->clk;\n"
- "+}\n"
- "+\n"
- "+static inline void\n"
- "+tnode_set_clock(struct clk_tnode *node, int id, struct clk *clk)\n"
- "+{\n"
- "+\tnode->events[id].clk = clk;\n"
- "+}\n"
- "+\n"
- "+static inline struct clk_tnode *tnode_get_parent(struct clk_tnode *node)\n"
- "+{\n"
- "+\treturn node->parent;\n"
- "+}\n"
- "+\n"
- "+#define tnode_for_each_valid_events(node, _j)\t\t\t\\\n"
- "+\tfor ((_j) = (ffs(tnode_get_map(node)) - 1);\t\t\\\n"
- "+\t     (_j) < tnode_get_size((node)); ++(_j))\t\t\\\n"
- "+\t\t\tif (tnode_check_map_id((node), (_j)))\n"
- "+\n"
- "+#define EVENT(_clk,  _oldrate, _newrate)\t\t\\\n"
- "+\t(struct clk_event)\t\t\t\t\\\n"
- "+\t{\t\t\t\t\t\t\\\n"
- "+\t\t.clk = (struct clk *)(_clk),\t\t\\\n"
- "+\t\t.old_rate = (unsigned long)(_oldrate),\t\\\n"
- "+\t\t.new_rate = (unsigned long)(_newrate),\t\\\n"
- "+\t};\n"
- "+\n"
- "+#define TRANSACTION_ROOT(_num, _event)\t\t\t\t\t\\\n"
- "+\t(struct clk_tnode) {\t\t\t\t\t\t\\\n"
- "+\t\t.tid    = atomic_inc_return(&transaction_counter),\t\\\n"
- "+\t\t.size   = (_num),\t\t\t\t\t\\\n"
- "+\t\t.events = (struct clk_event *)(_event),\t\t\t\\\n"
- "+\t\t.parent = NULL,\t\t\t\t\t\t\\\n"
- "+\t\t.childs = LIST_HEAD_INIT(transaction.childs),\t\t\\\n"
- "+\t\t.events_map = 0,\t\t\t\t\t\\\n"
- "+\t\t};\n"
- "+\n"
- "+#define klist_function_support(_name, _type, _field, _kobj)\t\t\\\n"
- "+static void klist_get_##_name(struct klist_node *n)\t\t\t\\\n"
- "+{\t\t\t\t\t\t\t\t\t\\\n"
- "+\tstruct _type *entry = container_of(n, struct _type, _field);\t\\\n"
- "+\tkobject_get(&entry->_kobj);\t\t\t\t\t\\\n"
- "+}\t\t\t\t\t\t\t\t\t\\\n"
- "+static void klist_put_##_name(struct klist_node *n)\t\t\t\\\n"
- "+{\t\t\t\t\t\t\t\t\t\\\n"
- "+\tstruct _type *entry = container_of(n, struct _type, _field);\t\\\n"
- "+\tkobject_put(&entry->_kobj);\t\t\t\t\t\\\n"
- "+}\n"
- "+\n"
- "+#define klist_entry_support(name, type, field)\t\t\t\t\\\n"
- "+static struct type *next_##name(struct klist_iter *i)\t\t\t\\\n"
- "+{\tstruct klist_node *n = klist_next(i);\t\t\t\t\\\n"
- "+\treturn n ? container_of(n, struct type, field) : NULL;\t\t\\\n"
- "+}\n"
- "+\n"
- "+static inline void\n"
- "+clk_event_init(struct clk_event *evt, struct clk *clk,\n"
- "+\t\tunsigned long oldrate, unsigned long newrate)\n"
- "+{\n"
- "+\tevt->clk      = clk;\n"
- "+\tevt->old_rate = oldrate;\n"
- "+\tevt->new_rate = newrate;\n"
- "+}\n"
- "+\n"
- "+enum clk_fsm_e {\n"
- "+\tTRNSC_ENTER_CLOCK\t= 0x10,\n"
- "+\tTRNSC_ENTER_DEVICE\t= NOTIFY_CLK_ENTERCHANGE,\t/* 0x1 */\n"
- "+\tTRNSC_PRE_DEVICE\t= NOTIFY_CLK_PRECHANGE,\t\t/* 0x2 */\n"
- "+\tTRNSC_CHANGE_CLOCK\t= 0x20,\n"
- "+\tTRNSC_POST_DEVICE\t= NOTIFY_CLK_POSTCHANGE,\t/* 0x4 */\n"
- "+\tTRNSC_EXIT_DEVICE\t= NOTIFY_CLK_EXITCHANGE,\t/* 0x8 */\n"
- "+\tTRNSC_EXIT_CLOCK\t= 0x40\n"
- "+};\n"
- "+\n"
- "+#define DEV_SUSPENDED_ON_TRANSACTION\t(0x10)\n"
- "+#define DEV_RESUMED_ON_TRANSACTION\t(0x20)\n"
- "+#define DEV_ON_TRANSACTION\t(TRNSC_ENTER_DEVICE\t|\t\\\n"
- "+\t\t\t\tTRNSC_PRE_DEVICE\t|\t\\\n"
- "+\t\t\t\tTRNSC_POST_DEVICE\t|\t\\\n"
- "+\t\t\t\tTRNSC_EXIT_DEVICE)\n"
- "+\n"
- "+static inline int\n"
- "+pdev_transaction_move_on(struct platform_device *dev, unsigned int value)\n"
- "+{\n"
- "+\tint ret = -EINVAL;\n"
- "+\tunsigned long flag;\n"
- "+#ifdef CONFIG_CLK_DEBUG\n"
- "+\tstatic const char *dev_state[] = {\n"
- "+\t\t\"dev_enter\",\n"
- "+\t\t\"dev_pre\",\n"
- "+\t\t\"dev_post\",\n"
- "+\t\t\"dev_exit\"\n"
- "+\t};\n"
- "+\n"
- "+\tunsigned long old = dev->clk_state & DEV_ON_TRANSACTION;\n"
- "+\tint was = 0, is = 0;\n"
- "+\tif (\n"
- "+\t   (old == 0 && value == TRNSC_ENTER_DEVICE) ||\n"
- "+\t   (old == TRNSC_ENTER_DEVICE && value == TRNSC_EXIT_DEVICE) ||\n"
- "+\t   (old == TRNSC_ENTER_DEVICE && value == TRNSC_PRE_DEVICE) ||\n"
- "+\t   (old == TRNSC_PRE_DEVICE && value == TRNSC_POST_DEVICE) ||\n"
- "+\t   (old == TRNSC_POST_DEVICE && value == TRNSC_EXIT_DEVICE))\n"
- "+\t\tgoto ok;\n"
- "+\tswitch (old) {\n"
- "+\tcase TRNSC_ENTER_DEVICE:\n"
- "+\t\twas = 0;\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_PRE_DEVICE:\n"
- "+\t\twas = 1;\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_POST_DEVICE:\n"
- "+\t\twas = 2;\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_EXIT_DEVICE:\n"
- "+\t\twas = 3;\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\tswitch (value) {\n"
- "+\tcase TRNSC_ENTER_DEVICE:\n"
- "+\t\tis = 0;\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_PRE_DEVICE:\n"
- "+\t\tis = 1;\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_POST_DEVICE:\n"
- "+\t\tis = 2;\n"
- "+\t\tbreak;\n"
- "+\tcase TRNSC_EXIT_DEVICE:\n"
- "+\t\tis = 3;\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\tprintk(KERN_ERR \"The device %s.%d shows a wrong evolution during \"\n"
- "+\t\t\"a clock transaction\\nDev state was %s and moved on %s\\n\",\n"
- "+\t\tdev->name, dev->id, dev_state[was], dev_state[is]);\n"
- "+ok:\n"
- "+#endif\n"
- "+\tlocal_irq_save(flag);\n"
- "+\tif ((dev->clk_state & DEV_ON_TRANSACTION) != value) {\n"
- "+\t\tdev->clk_state &= ~DEV_ON_TRANSACTION;\n"
- "+\t\tdev->clk_state |= value;\n"
- "+\t\tret = 0;\n"
- "+\t}\n"
- "+\tlocal_irq_restore(flag);\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static inline int\n"
- "+clk_set_towner(struct clk *clk, struct clk_tnode *node)\n"
- "+{\n"
- "+\treturn atomic_cmpxchg((atomic_t *)&clk->towner, 0, (int)node);\n"
- "+}\n"
- "+\n"
- "+static inline void\n"
- "+clk_clean_towner(struct clk *clk)\n"
- "+{\n"
- "+\tatomic_set((atomic_t *)(&clk->towner), 0);\n"
- "+}\n"
- "+\n"
- "+static inline int\n"
- "+clk_is_enabled(struct clk *clk)\n"
- "+{\n"
- "+\treturn clk->rate != 0;\n"
- "+}\n"
- "+\n"
- "+static inline int\n"
- "+clk_is_readonly(struct clk *clk)\n"
- "+{\n"
- "+\treturn !clk->ops || !clk->ops->set_rate;\n"
- "+}\n"
- "+\n"
- "+static inline int\n"
- "+clk_allow_propagation(struct clk *clk)\n"
- "+{\n"
- "+\treturn !!(clk->flags & CLK_EVENT_PROPAGATES);\n"
- "+}\n"
- "+\n"
- "+static inline int\n"
- "+clk_is_auto_switching(struct clk *clk)\n"
- "+{\n"
- "+\treturn !!(clk->flags & CLK_AUTO_SWITCHING);\n"
- "+}\n"
- "+\n"
- "+static inline int\n"
- "+clk_follow_parent(struct clk *clk)\n"
- "+{\n"
- "+\treturn !!(clk->flags & CLK_FOLLOW_PARENT);\n"
- "+}\n"
- "+\n"
- "+enum pdev_add_state {\n"
- "+\tPDEV_ADDING,\n"
- "+\tPDEV_ADDED,\n"
- "+\tPDEV_ADD_FAILED,\n"
- "+};\n"
- "+\n"
- "+enum pdev_probe_state {\n"
- "+\tPDEV_PROBEING,\n"
- "+\tPDEV_PROBED,\n"
- "+\tPDEV_PROBE_FAILED,\n"
- "+};\n"
- "+\n"
- "+int clk_add_device(struct platform_device *dev, enum pdev_add_state state);\n"
- "+int clk_probe_device(struct platform_device *dev, enum pdev_probe_state state);\n"
- "+int clk_del_device(struct platform_device *dev);\n"
- "+\n"
- "+#endif\n"
- "diff --git a/drivers/base/clk_pm.c b/drivers/base/clk_pm.c\n"
- "new file mode 100644\n"
- "index 0000000..56c1760\n"
- "--- /dev/null\n"
- "+++ b/drivers/base/clk_pm.c\n"
- "@@ -0,0 +1,197 @@\n"
- "+/*\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * clk_pm.c\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * (C) STMicroelectronics 2008\n"
- "+ * (C) STMicroelectronics 2009\n"
- "+ * Author: Francesco M. Virlinzi <francesco.virlinzi@st.com>\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * May be copied or modified under the terms of the GNU General Public\n"
- "+ * License v.2 ONLY.  See linux/COPYING for more information.\n"
- "+ *\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ */\n"
- "+\n"
- "+#include <linux/clk.h>\n"
- "+#include <linux/klist.h>\n"
- "+#include <linux/list.h>\n"
- "+#include <linux/sysdev.h>\n"
- "+#include <linux/device.h>\n"
- "+#include <linux/kref.h>\n"
- "+#include <linux/kobject.h>\n"
- "+#include <linux/err.h>\n"
- "+#include <linux/spinlock.h>\n"
- "+#include <linux/proc_fs.h>\n"
- "+#include \"power/power.h\"\n"
- "+#include \"clk.h\"\n"
- "+#include \"base.h\"\n"
- "+\n"
- "+static int\n"
- "+__clk_operations(struct clk *clk, unsigned long rate, enum clk_ops_id id_ops)\n"
- "+{\n"
- "+\tint ret = -EINVAL;\n"
- "+\tunsigned long *ops_fns = (unsigned long *)clk->ops;\n"
- "+\tif (likely(ops_fns && ops_fns[id_ops])) {\n"
- "+\t\tint (*fns)(struct clk *clk, unsigned long rate)\n"
- "+\t\t\t= (void *)ops_fns[id_ops];\n"
- "+\t\tunsigned long flags;\n"
- "+\t\tspin_lock_irqsave(&clk->lock, flags);\n"
- "+\t\tret = fns(clk, rate);\n"
- "+\t\tspin_unlock_irqrestore(&clk->lock, flags);\n"
- "+\t}\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static inline int __clk_init(struct clk *clk)\n"
- "+{\n"
- "+\treturn __clk_operations(clk, 0, __CLK_INIT);\n"
- "+}\n"
- "+\n"
- "+static inline int __clk_enable(struct clk *clk)\n"
- "+{\n"
- "+\treturn __clk_operations(clk, 0, __CLK_ENABLE);\n"
- "+}\n"
- "+\n"
- "+static inline int __clk_disable(struct clk *clk)\n"
- "+{\n"
- "+\treturn __clk_operations(clk, 0, __CLK_DISABLE);\n"
- "+}\n"
- "+\n"
- "+static inline int __clk_set_rate(struct clk *clk, unsigned long rate)\n"
- "+{\n"
- "+\treturn __clk_operations(clk, rate, __CLK_SET_RATE);\n"
- "+}\n"
- "+\n"
- "+static inline int __clk_set_parent(struct clk *clk, struct clk *parent)\n"
- "+{\n"
- "+\treturn __clk_operations(clk, (unsigned long)parent, __CLK_SET_PARENT);\n"
- "+}\n"
- "+\n"
- "+static inline int __clk_recalc_rate(struct clk *clk)\n"
- "+{\n"
- "+\treturn __clk_operations(clk, 0, __CLK_RECALC);\n"
- "+}\n"
- "+\n"
- "+static inline int pm_clk_ratio(struct clk *clk)\n"
- "+{\n"
- "+\tregister unsigned int val, exp;\n"
- "+\n"
- "+\tval = ((clk->flags >> CLK_PM_RATIO_SHIFT) &\n"
- "+\t\t((1 << CLK_PM_RATIO_NRBITS) - 1)) + 1;\n"
- "+\texp = ((clk->flags >> CLK_PM_EXP_SHIFT) &\n"
- "+\t\t((1 << CLK_PM_EXP_NRBITS) - 1));\n"
- "+\n"
- "+\treturn val << exp;\n"
- "+}\n"
- "+\n"
- "+static inline int pm_clk_is_off(struct clk *clk)\n"
- "+{\n"
- "+\treturn ((clk->flags & CLK_PM_TURNOFF) == CLK_PM_TURNOFF);\n"
- "+}\n"
- "+\n"
- "+static inline void pm_clk_set(struct clk *clk, int edited)\n"
- "+{\n"
- "+#define CLK_PM_EDITED (1 << CLK_PM_EDIT_SHIFT)\n"
- "+\tclk->flags &= ~CLK_PM_EDITED;\n"
- "+\tclk->flags |= (edited ? CLK_PM_EDITED : 0);\n"
- "+}\n"
- "+\n"
- "+static inline int pm_clk_is_modified(struct clk *clk)\n"
- "+{\n"
- "+\treturn ((clk->flags & CLK_PM_EDITED) != 0);\n"
- "+}\n"
- "+\n"
- "+static int clk_resume_from_standby(struct clk *clk, void *data)\n"
- "+{\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\tif (!likely(clk->ops))\n"
- "+\t\treturn 0;\n"
- "+\t/* check if the pm modified the clock */\n"
- "+\tif (!pm_clk_is_modified(clk))\n"
- "+\t\treturn 0;;\n"
- "+\tpm_clk_set(clk, 0);\n"
- "+\tif (pm_clk_is_off(clk))\n"
- "+\t\t__clk_enable(clk);\n"
- "+\telse\n"
- "+\t\t__clk_set_rate(clk, clk->rate * pm_clk_ratio(clk));\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int clk_on_standby(struct clk *clk, void *data)\n"
- "+{\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\n"
- "+\tif (!clk->ops)\n"
- "+\t\treturn 0;\n"
- "+\tif (!clk->rate) /* already disabled */\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tpm_clk_set(clk, 1);\t/* set as modified */\n"
- "+\tif (pm_clk_is_off(clk))\t\t/* turn-off */\n"
- "+\t\t__clk_disable(clk);\n"
- "+\telse    /* reduce */\n"
- "+\t\t__clk_set_rate(clk, clk->rate / pm_clk_ratio(clk));\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int clk_resume_from_hibernation(struct clk *clk, void *data)\n"
- "+{\n"
- "+\tunsigned long rate = clk->rate;\n"
- "+\tpr_debug(\"\\n\");\n"
- "+\t__clk_set_parent(clk, clk->parent);\n"
- "+\t__clk_set_rate(clk, rate);\n"
- "+\t__clk_recalc_rate(clk);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)\n"
- "+{\n"
- "+\tstatic pm_message_t prev_state;\n"
- "+\n"
- "+\tswitch (state.event) {\n"
- "+\tcase PM_EVENT_ON:\n"
- "+\t\tswitch (prev_state.event) {\n"
- "+\t\tcase PM_EVENT_FREEZE: /* Resumeing from hibernation */\n"
- "+\t\t\tclk_for_each(clk_resume_from_hibernation, NULL);\n"
- "+\t\t\tbreak;\n"
- "+\t\tcase PM_EVENT_SUSPEND:\n"
- "+\t\t\tclk_for_each(clk_resume_from_standby, NULL);\n"
- "+\t\t\tbreak;\n"
- "+\t\t}\n"
- "+\tcase PM_EVENT_SUSPEND:\n"
- "+\t\tclk_for_each(clk_on_standby, NULL);\n"
- "+\t\tbreak;\n"
- "+\tcase PM_EVENT_FREEZE:\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\tprev_state = state;\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static int clks_sysdev_resume(struct sys_device *dev)\n"
- "+{\n"
- "+\treturn clks_sysdev_suspend(dev, PMSG_ON);\n"
- "+}\n"
- "+\n"
- "+static struct sysdev_class clk_sysdev_class = {\n"
- "+\t.name = \"clks\",\n"
- "+};\n"
- "+\n"
- "+static struct sysdev_driver clks_sysdev_driver = {\n"
- "+\t.suspend = clks_sysdev_suspend,\n"
- "+\t.resume = clks_sysdev_resume,\n"
- "+};\n"
- "+\n"
- "+static struct sys_device clks_sysdev_dev = {\n"
- "+\t.cls = &clk_sysdev_class,\n"
- "+};\n"
- "+\n"
- "+static int __init clk_sysdev_init(void)\n"
- "+{\n"
- "+\tsysdev_class_register(&clk_sysdev_class);\n"
- "+\tsysdev_driver_register(&clk_sysdev_class, &clks_sysdev_driver);\n"
- "+\tsysdev_register(&clks_sysdev_dev);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+subsys_initcall(clk_sysdev_init);\n"
- "diff --git a/drivers/base/clk_utils.c b/drivers/base/clk_utils.c\n"
- "new file mode 100644\n"
- "index 0000000..a222aa7\n"
- "--- /dev/null\n"
- "+++ b/drivers/base/clk_utils.c\n"
- "@@ -0,0 +1,456 @@\n"
- "+/*\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * clk_utils.c\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * (C) STMicroelectronics 2008\n"
- "+ * (C) STMicroelectronics 2009\n"
- "+ * Author: Francesco M. Virlinzi <francesco.virlinzi@st.com>\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ * May be copied or modified under the terms of the GNU General Public\n"
- "+ * License v.2 ONLY.  See linux/COPYING for more information.\n"
- "+ *\n"
- "+ * -------------------------------------------------------------------------\n"
- "+ */\n"
- "+\n"
- "+#include <linux/platform_device.h>\n"
- "+#include <linux/clk.h>\n"
- "+#include <linux/klist.h>\n"
- "+#include <linux/list.h>\n"
- "+#include <linux/delay.h>\n"
- "+#include <linux/sysdev.h>\n"
- "+#include <linux/kref.h>\n"
- "+#include <linux/kobject.h>\n"
- "+#include <linux/err.h>\n"
- "+#include <linux/spinlock.h>\n"
- "+#include <asm/atomic.h>\n"
- "+#include \"power/power.h\"\n"
- "+#include \"clk.h\"\n"
- "+#include \"base.h\"\n"
- "+\n"
- "+int clk_generic_notify(unsigned long code,\n"
- "+\tstruct platform_device *pdev, void *data)\n"
- "+{\n"
- "+\tstruct clk_event *event = (struct clk_event *)data;\n"
- "+\tunsigned long event_decode = clk_event_decode(event);\n"
- "+\n"
- "+\tswitch (code) {\n"
- "+\tcase NOTIFY_CLK_ENTERCHANGE:\n"
- "+\t\treturn NOTIFY_EVENT_HANDLED;\t/* to accept */\n"
- "+\n"
- "+\tcase NOTIFY_CLK_PRECHANGE:\n"
- "+\t\t/* without clock (not still enabled) the device can not work */\n"
- "+\t\tif (event_decode == _CLK_ENABLE)\n"
- "+\t\t\treturn NOTIFY_EVENT_NOTHANDLED;\n"
- "+\t\treturn NOTIFY_EVENT_HANDLED;\t/* to suspend */\n"
- "+\n"
- "+\tcase NOTIFY_CLK_POSTCHANGE:\n"
- "+\t\t/* without clock (just disabled) the device can not work */\n"
- "+\t\tif (event_decode == _CLK_DISABLE)\n"
- "+\t\t\treturn NOTIFY_EVENT_NOTHANDLED;\n"
- "+\t\treturn NOTIFY_EVENT_HANDLED;\t/* to resume */\n"
- "+\n"
- "+\tcase NOTIFY_CLK_EXITCHANGE:\n"
- "+\t\treturn NOTIFY_EVENT_HANDLED;\n"
- "+\t}\n"
- "+\n"
- "+\treturn NOTIFY_EVENT_HANDLED;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_generic_notify);\n"
- "+\n"
- "+unsigned long clk_generic_evaluate_rate(struct clk *clk, unsigned long prate)\n"
- "+{\n"
- "+\tunsigned long current_prate;\n"
- "+\n"
- "+\tif (!clk->parent)\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tif (!prate)\t/* if zero return zero (on disable: disable!) */\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tif (prate == CLK_UNDEFINED_RATE) /* on undefined: undefined */\n"
- "+\t\treturn CLK_UNDEFINED_RATE;\n"
- "+\n"
- "+\tcurrent_prate = clk_get_rate(clk->parent);\n"
- "+\tif (current_prate == prate)\n"
- "+\t\treturn clk_get_rate(clk);\n"
- "+\n"
- "+\tif (current_prate > prate) /* down scale */\n"
- "+\t\treturn (clk_get_rate(clk) * prate) / current_prate;\n"
- "+\telse\n"
- "+\t\treturn (clk_get_rate(clk) / current_prate) * prate;\n"
- "+}\n"
- "+EXPORT_SYMBOL(clk_generic_evaluate_rate);\n"
- "+\n"
- "+#ifdef CONFIG_PROC_FS\n"
- "+/*\n"
- "+ * The \"clocks\" file is created under /proc\n"
- "+ * to list all the clocks registered in the system\n"
- "+ */\n"
- "+#include <linux/proc_fs.h>\n"
- "+#include <linux/seq_file.h>\n"
- "+static void *clk_seq_next(struct seq_file *s, void *v, loff_t *pos)\n"
- "+{\n"
- "+\tstruct list_head *tmp;\n"
- "+\tunion {\n"
- "+\t\tloff_t value;\n"
- "+\t\tlong parts[2];\n"
- "+\t} ltmp;\n"
- "+\n"
- "+\tltmp.value = *pos;\n"
- "+\ttmp = (struct list_head *)ltmp.parts[0];\n"
- "+\ttmp = tmp->next;\n"
- "+\tltmp.parts[0] = (long)tmp;\n"
- "+\n"
- "+\t*pos = ltmp.value;\n"
- "+\n"
- "+\tif (tmp == &clk_list.k_list)\n"
- "+\t\treturn NULL; /* No more to read */\n"
- "+\n"
- "+\treturn pos;\n"
- "+}\n"
- "+\n"
- "+static void *clk_seq_start(struct seq_file *s, loff_t *pos)\n"
- "+{\n"
- "+\tif (!*pos) { /* first call! */\n"
- "+\t\tunion {\n"
- "+\t\t\tloff_t value;\n"
- "+\t\t\tlong parts[2];\n"
- "+\t\t} ltmp;\n"
- "+\t\tltmp.parts[0] = (long) clk_list.k_list.next;\n"
- "+\t\t*pos = ltmp. value;\n"
- "+\t\treturn pos;\n"
- "+\t}\n"
- "+\t--(*pos); /* to realign *pos value! */\n"
- "+\n"
- "+\treturn clk_seq_next(s, NULL, pos);\n"
- "+}\n"
- "+\n"
- "+static int clk_seq_show(struct seq_file *s, void *v)\n"
- "+{\n"
- "+\tunsigned long *l = (unsigned long *)v;\n"
- "+\tstruct list_head *node = (struct list_head *)(*l);\n"
- "+\tstruct clk *clk = container_of(node, struct clk, node.n_node);\n"
- "+\tunsigned long rate = clk_get_rate(clk);\n"
- "+\n"
- "+\tif (unlikely(!rate && !clk->parent))\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tseq_printf(s, \"%-12s\\t: %ld.%02ldMHz - \", clk->name,\n"
- "+\t       rate / 1000000, (rate % 1000000) / 10000);\n"
- "+\tseq_printf(s, \"[0x%p]\", clk);\n"
- "+\tif (clk_is_enabled(clk))\n"
- "+\t\tseq_printf(s, \" - enabled\");\n"
- "+\n"
- "+\tif (clk->parent)\n"
- "+\t\tseq_printf(s, \" - [%s]\", clk->parent->name);\n"
- "+\tseq_printf(s, \"\\n\");\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static void clk_seq_stop(struct seq_file *s, void *v)\n"
- "+{\n"
- "+}\n"
- "+\n"
- "+static const struct seq_operations clk_seq_ops = {\n"
- "+\t.start = clk_seq_start,\n"
- "+\t.next = clk_seq_next,\n"
- "+\t.stop = clk_seq_stop,\n"
- "+\t.show = clk_seq_show,\n"
- "+};\n"
- "+\n"
- "+static int clk_proc_open(struct inode *inode, struct file *file)\n"
- "+{\n"
- "+\treturn seq_open(file, &clk_seq_ops);\n"
- "+}\n"
- "+\n"
- "+static const struct file_operations clk_proc_ops = {\n"
- "+\t.owner = THIS_MODULE,\n"
- "+\t.open = clk_proc_open,\n"
- "+\t.read = seq_read,\n"
- "+\t.llseek = seq_lseek,\n"
- "+\t.release = seq_release,\n"
- "+};\n"
- "+\n"
- "+static int __init clk_proc_init(void)\n"
- "+{\n"
- "+\tstruct proc_dir_entry *p;\n"
- "+\n"
- "+\tp = create_proc_entry(\"clocks\", S_IRUGO, NULL);\n"
- "+\n"
- "+\tif (unlikely(!p))\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tp->proc_fops = &clk_proc_ops;\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+subsys_initcall(clk_proc_init);\n"
- "+#endif\n"
- "+\n"
- "+#ifdef CONFIG_SYSFS\n"
- "+static ssize_t clk_rate_show(struct kobject *kobj,\n"
- "+\t\tstruct kobj_attribute *attr, char *buf)\n"
- "+{\n"
- "+\tstruct clk *clk = container_of(kobj, struct clk, kobj);\n"
- "+\n"
- "+\treturn sprintf(buf, \"%u\\n\", (unsigned int)clk_get_rate(clk));\n"
- "+}\n"
- "+\n"
- "+static ssize_t clk_rate_store(struct kobject *kobj,\n"
- "+\t\tstruct kobj_attribute *attr, const char *buf, size_t count)\n"
- "+{\n"
- "+\tunsigned long rate = simple_strtoul(buf, NULL, 10);\n"
- "+\tstruct clk *clk = container_of(kobj, struct clk, kobj);\n"
- "+\n"
- "+\tif (rate) {\n"
- "+\t\tif (!clk_is_enabled(clk))\n"
- "+\t\t\tclk_enable(clk);\n"
- "+\t\tif (clk_set_rate(clk, rate) < 0)\n"
- "+\t\t\treturn -EINVAL;\n"
- "+\t} else\n"
- "+\t\tclk_disable(clk);\n"
- "+\treturn count;\n"
- "+}\n"
- "+\n"
- "+static const char *clk_ctrl_token[] = {\n"
- "+\t\"auto_switching\",\n"
- "+\t\"no_auto_switching\",\n"
- "+\t\"allow_propagation\",\n"
- "+\t\"no_allow_propagation\",\n"
- "+\t\"follow_parent\",\n"
- "+\t\"no_follow_parent\",\n"
- "+};\n"
- "+static ssize_t clk_state_show(struct kobject *kobj,\n"
- "+\t\tstruct kobj_attribute *attr, char *buf)\n"
- "+{\n"
- "+\tstruct clk *clk = container_of(kobj, struct clk, kobj);\n"
- "+\tssize_t ret;\n"
- "+\n"
- "+\n"
- "+\tret = sprintf(buf, \"clock name: %s\\n\", clk->name);\n"
- "+\tif (clk_is_enabled(clk))\n"
- "+\t\tret += sprintf(buf + ret, \" + enabled\\n\");\n"
- "+\telse\n"
- "+\t\tret += sprintf(buf + ret, \" + disabled\\n\");\n"
- "+\tif (clk_is_readonly(clk))\n"
- "+\t\tret += sprintf(buf + ret, \" + rate read only\\n\");\n"
- "+\telse\n"
- "+\t\tret += sprintf(buf + ret, \" + rate writable\\n\");\n"
- "+\tret +=\n"
- "+\t    sprintf(buf + ret, \" + %s\\n\",\n"
- "+\t\t    clk_ctrl_token[(clk_allow_propagation(clk) ? 2 : 3)]);\n"
- "+\tret +=\n"
- "+\t    sprintf(buf + ret, \" + %s\\n\",\n"
- "+\t\t    clk_ctrl_token[(clk_is_auto_switching(clk) ? 0 : 1)]);\n"
- "+\tret +=\n"
- "+\t    sprintf(buf + ret, \" + %s\\n\",\n"
- "+\t\t    clk_ctrl_token[(clk_follow_parent(clk) ? 4 : 5)]);\n"
- "+\tret +=\n"
- "+\t    sprintf(buf + ret, \" + nr_clocks:  %u\\n\", clk->nr_clocks);\n"
- "+\tret +=\n"
- "+\t    sprintf(buf + ret, \" + nr_active_clocks:  %u\\n\",\n"
- "+\t\tclk->nr_active_clocks);\n"
- "+\tret +=\n"
- "+\t    sprintf(buf + ret, \" + nr_active_devices:  %u\\n\",\n"
- "+\t\tclk->nr_active_devices);\n"
- "+\tret +=\n"
- "+\t    sprintf(buf + ret, \" + rate: %u\\n\",\n"
- "+\t\t    (unsigned int)clk_get_rate(clk));\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static ssize_t clk_ctrl_show(struct kobject *kobj,\n"
- "+\t\tstruct kobj_attribute *attr, char *buf)\n"
- "+{\n"
- "+\tint idx, ret = 0;\n"
- "+\n"
- "+\tret += sprintf(buf + ret, \"Allowed command:\\n\");\n"
- "+\n"
- "+\tfor (idx = 0; idx < ARRAY_SIZE(clk_ctrl_token); ++idx)\n"
- "+\t\tret += sprintf(buf + ret, \" + %s\\n\", clk_ctrl_token[idx]);\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+static ssize_t clk_ctrl_store(struct kobject *kobj,\n"
- "+\t\tstruct kobj_attribute *attr, const char *buf, size_t count)\n"
- "+{\n"
- "+\tint i, idx_token, ret = -EINVAL;\n"
- "+\tstruct clk *clk = container_of(kobj, struct clk, kobj);\n"
- "+\n"
- "+\tif (!count)\n"
- "+\t\treturn ret;\n"
- "+\n"
- "+\tfor (i = 0, idx_token = -1; i < ARRAY_SIZE(clk_ctrl_token); ++i)\n"
- "+\t\tif (!strcmp(buf, clk_ctrl_token[i]))\n"
- "+\t\t\tidx_token = i;\n"
- "+\n"
- "+\tif (idx_token == -EINVAL)\n"
- "+\t\treturn ret;     /* token not valid... */\n"
- "+\n"
- "+\tswitch (idx_token) {\n"
- "+\tcase 0:\n"
- "+\t\tclk->flags |= CLK_EVENT_PROPAGATES;\n"
- "+\t\tbreak;\n"
- "+\tcase 1:\n"
- "+\t\tclk->flags &= ~CLK_EVENT_PROPAGATES;\n"
- "+\t\tbreak;\n"
- "+\tcase 2:\n"
- "+\t\tclk->flags |= CLK_AUTO_SWITCHING;\n"
- "+\t\tif (!clk->nr_active_clocks && !clk->nr_active_devices)\n"
- "+\t\t\tclk_disable(clk);\n"
- "+\t\telse if (clk->nr_active_clocks || clk->nr_active_devices)\n"
- "+\t\t\tclk_enable(clk);\n"
- "+\t\tbreak;\n"
- "+\tcase 3:\n"
- "+\t\tclk->flags &= ~CLK_AUTO_SWITCHING;\n"
- "+\t\tbreak;\n"
- "+\tcase 4:\n"
- "+\t\tclk->flags |= CLK_FOLLOW_PARENT;\n"
- "+\t\tbreak;\n"
- "+\tcase 5:\n"
- "+\t\tclk->flags &= ~CLK_FOLLOW_PARENT;\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\treturn count;\n"
- "+}\n"
- "+\n"
- "+static ssize_t clk_parent_store(struct kobject *kobj,\n"
- "+\t\tstruct kobj_attribute *attr, const char *buf, size_t count)\n"
- "+{\n"
- "+\tstruct clk *clk = container_of(kobj, struct clk, kobj);\n"
- "+\tstruct clk *parent = clk_get(NULL, buf);\n"
- "+\n"
- "+\tif (!parent)\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tclk_put(parent);\n"
- "+\tclk_set_parent(clk, parent);\n"
- "+\n"
- "+\treturn count;\n"
- "+}\n"
- "+\n"
- "+static struct kobj_attribute attributes[] = {\n"
- "+__ATTR(state, S_IRUSR, clk_state_show, NULL),\n"
- "+__ATTR(rate, S_IRUSR | S_IWUSR, clk_rate_show, clk_rate_store),\n"
- "+__ATTR(control, S_IRUSR | S_IWUSR, clk_ctrl_show, clk_ctrl_store),\n"
- "+__ATTR(parent, S_IWUSR, NULL, clk_parent_store)\n"
- "+};\n"
- "+\n"
- "+static struct attribute *clk_attrs[] = {\n"
- "+\t&attributes[0].attr,\n"
- "+\t&attributes[1].attr,\n"
- "+\t&attributes[2].attr,\n"
- "+\t&attributes[3].attr,\n"
- "+\tNULL\n"
- "+};\n"
- "+\n"
- "+static struct attribute_group clk_attr_group = {\n"
- "+\t.attrs = clk_attrs,\n"
- "+\t.name = \"attributes\"\n"
- "+};\n"
- "+\n"
- "+#if 0\n"
- "+static inline char *_strsep(char **s, const char *d)\n"
- "+{\n"
- "+\tint i, len = strlen(d);\n"
- "+retry:\n"
- "+\tif (!(*s) || !(**s))\n"
- "+\t\treturn NULL;\n"
- "+\tfor (i = 0; i < len; ++i) {\n"
- "+\t\tif (**s != *(d+i))\n"
- "+\t\t\tcontinue;\n"
- "+\t\t++(*s);\n"
- "+\t\tgoto retry;\n"
- "+\t}\n"
- "+\treturn strsep(s, d);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * clk_rates_store\n"
- "+ *\n"
- "+ * It parses the buf to create multi clocks transaction\n"
- "+ * via user space\n"
- "+ * The buffer has to be something like:\n"
- "+ * clock_A @ rate_A; clock_B @ rate_b; clock_C @ rate_c\n"
- "+ */\n"
- "+static ssize_t clk_rates_store(struct kobject *kobj,\n"
- "+\t\tstruct kobj_attribute *attr, const char *buf, size_t count)\n"
- "+{\n"
- "+\tint i, ret;\n"
- "+\tint nclock = 0;\n"
- "+\tunsigned long *rates;\n"
- "+\tstruct clk **clocks;\n"
- "+\n"
- "+\tif (!buf)\n"
- "+\t\treturn -1;\n"
- "+\n"
- "+\tfor (i = 0; i < count; ++i)\n"
- "+\t\tif (buf[i] == '@')\n"
- "+\t\t\t++nclock;\n"
- "+\n"
- "+\trates = kmalloc(sizeof(long) * nclock, GFP_KERNEL);\n"
- "+\tif (!rates)\n"
- "+\t\treturn -ENOMEM;\n"
- "+\n"
- "+\tclocks = kmalloc(sizeof(void *) * nclock, GFP_KERNEL);\n"
- "+\tif (!clocks) {\n"
- "+\t\tret = -ENOMEM;\n"
- "+\t\tgoto err_0;\n"
- "+\t}\n"
- "+\n"
- "+\t/* Parse the buffer */\n"
- "+\tfor (i = 0; i < nclock; ++i) {\n"
- "+\t\tchar *name;\n"
- "+\t\tchar *nrate;\n"
- "+\t\tname  = _strsep((char **)&buf, \"@ \"); ++buf;\n"
- "+\t\tnrate = _strsep((char **)&buf, \" ;\"); ++buf;\n"
- "+\t\tif (!name || !nrate) {\n"
- "+\t\t\tret = -EINVAL;\n"
- "+\t\t\tgoto err_1;\n"
- "+\t\t\t}\n"
- "+\t\tclocks[i] = clk_get(NULL, name);\n"
- "+\t\trates[i]  = simple_strtoul(nrate, NULL, 10);\n"
- "+\t\tif (!clocks[i]) { /* the clock doesn't exist! */\n"
- "+\t\t\tret = -EINVAL;\n"
- "+\t\t\tgoto err_1;\n"
- "+\t\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\tret = clk_set_rates(clocks, rates, nclock);\n"
- "+\tif (ret >= 0)\n"
- "+\t\tret = count; /* to say OK */\n"
- "+\n"
- "+err_1:\n"
- "+\tkfree(clocks);\n"
- "+err_0:\n"
- "+\tkfree(rates);\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static struct kobj_attribute clk_rates_attr =\n"
- "+\t__ATTR(rates, S_IWUSR, NULL, clk_rates_store);\n"
- "+#endif\n"
- "+\n"
- "+static int __init clk_add_attributes(struct clk *clk, void *data)\n"
- "+{\n"
- "+\tint ret;\n"
- "+\n"
- "+\tret = sysfs_update_group(&clk->kobj, &clk_attr_group);\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static int __init clk_late_init(void)\n"
- "+{\n"
- "+\tint ret;\n"
- "+\n"
- "+\tret = clk_for_each(clk_add_attributes, NULL);\n"
- "+\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+late_initcall(clk_late_init);\n"
- "+#endif\n"
- "diff --git a/drivers/base/init.c b/drivers/base/init.c\n"
- "index 7bd9b6a..2441b26 100644\n"
- "--- a/drivers/base/init.c\n"
- "+++ b/drivers/base/init.c\n"
- "@@ -24,6 +24,7 @@ void __init driver_init(void)\n"
- " \tbuses_init();\n"
- " \tclasses_init();\n"
- " \tfirmware_init();\n"
- "+\tclock_init();\n"
- " \thypervisor_init();\n"
- " \n"
- " \t/* These are also core pieces, but must come after the\n"
- "diff --git a/drivers/base/platform.c b/drivers/base/platform.c\n"
- "index 8b4708e..550d993 100644\n"
- "--- a/drivers/base/platform.c\n"
- "+++ b/drivers/base/platform.c\n"
- "@@ -17,6 +17,8 @@\n"
- " #include <linux/bootmem.h>\n"
- " #include <linux/err.h>\n"
- " #include <linux/slab.h>\n"
- "+#include <linux/clk.h>\n"
- "+#include \"clk.h\"\n"
- " \n"
- " #include \"base.h\"\n"
- " \n"
- "@@ -272,9 +274,20 @@ int platform_device_add(struct platform_device *pdev)\n"
- " \tpr_debug(\"Registering platform device '%s'. Parent at %s\\n\",\n"
- " \t\t dev_name(&pdev->dev), dev_name(pdev->dev.parent));\n"
- " \n"
- "+#ifdef CONFIG_GENERIC_CLK_FM\n"
- "+\tclk_add_device(pdev, PDEV_ADDING);\n"
- "+\n"
- "+\tret = device_add(&pdev->dev);\n"
- "+\n"
- "+\tclk_add_device(pdev, (ret ? PDEV_ADD_FAILED : PDEV_ADDED));\n"
- "+\n"
- "+\tif (ret == 0)\n"
- "+\t\treturn ret;\n"
- "+#else\n"
- " \tret = device_add(&pdev->dev);\n"
- " \tif (ret == 0)\n"
- " \t\treturn ret;\n"
- "+#endif\n"
- " \n"
- "  failed:\n"
- " \twhile (--i >= 0) {\n"
- "@@ -311,6 +324,9 @@ void platform_device_del(struct platform_device *pdev)\n"
- " \t\t\tif (type == IORESOURCE_MEM || type == IORESOURCE_IO)\n"
- " \t\t\t\trelease_resource(r);\n"
- " \t\t}\n"
- "+#ifdef CONFIG_GENERIC_CLK_FM\n"
- "+\tclk_del_device(pdev);\n"
- "+#endif\n"
- " \t}\n"
- " }\n"
- " EXPORT_SYMBOL_GPL(platform_device_del);\n"
- "@@ -445,7 +461,18 @@ static int platform_drv_probe(struct device *_dev)\n"
- " \tstruct platform_driver *drv = to_platform_driver(_dev->driver);\n"
- " \tstruct platform_device *dev = to_platform_device(_dev);\n"
- " \n"
- "+#ifdef CONFIG_GENERIC_CLK_FM\n"
- "+\tint ret;\n"
- "+\tret = clk_probe_device(dev, PDEV_PROBEING);\n"
- "+\tif (ret)\n"
- "+\t\treturn ret;\n"
- "+\tret = drv->probe(dev);\n"
- "+\n"
- "+\tclk_probe_device(dev, (ret ? PDEV_PROBE_FAILED : PDEV_PROBED));\n"
- "+\treturn ret;\n"
- "+#else\n"
- " \treturn drv->probe(dev);\n"
- "+#endif\n"
- " }\n"
- " \n"
- " static int platform_drv_probe_fail(struct device *_dev)\n"
- "diff --git a/include/linux/clk.h b/include/linux/clk.h\n"
- "index 1db9bbf..e537bcd 100644\n"
- "--- a/include/linux/clk.h\n"
- "+++ b/include/linux/clk.h\n"
- "@@ -12,6 +12,7 @@\n"
- " #define __LINUX_CLK_H\n"
- " \n"
- " struct device;\n"
- "+struct platform_device;\n"
- " \n"
- " /*\n"
- "  * The base API.\n"
- "@@ -142,4 +143,254 @@ struct clk *clk_get_parent(struct clk *clk);\n"
- "  */\n"
- " struct clk *clk_get_sys(const char *dev_id, const char *con_id);\n"
- " \n"
- "+/**\n"
- "+ * clk_set_rates - set the clock rates\n"
- "+ * @clk: clocks source\n"
- "+ * @rate: desired clock rates in Hz\n"
- "+ * @nclks: the number of clocks\n"
- "+ *\n"
- "+ * Returns success (0) or negative errno.\n"
- "+ */\n"
- "+int clk_set_rates(struct clk **clk, unsigned long *rates, unsigned long nclks);\n"
- "+\n"
- "+#ifndef CONFIG_GENERIC_CLK_FM\n"
- "+\n"
- "+#define bind_clock(_clk)\n"
- "+#define pdevice_setclock(_dev, _clk)\n"
- "+#define pdevice_setclock_byname(_dev, _clkname)\n"
- "+#define pdevice_num_clocks(_dev)\n"
- "+#define pdevice_clock(dev, idx)\n"
- "+\n"
- "+#else\n"
- "+\n"
- "+#include <linux/kobject.h>\n"
- "+#include <linux/klist.h>\n"
- "+#include <linux/notifier.h>\n"
- "+#include <linux/pm.h>\n"
- "+#include <linux/spinlock.h>\n"
- "+#include <asm/atomic.h>\n"
- "+\n"
- "+\n"
- "+/**\n"
- "+ * Clock operation -\n"
- "+ *\n"
- "+ * It's a set of function pointer to identify all the capability on a clock\n"
- "+ */\n"
- "+struct clk_ops {\n"
- "+/** @init initializes the clock\t*/\n"
- "+\tint (*init)(struct clk *);\n"
- "+/** @enable enables the clock\t*/\n"
- "+\tint (*enable)(struct clk *);\n"
- "+/** @disable disables the clock\t*/\n"
- "+\tint (*disable)(struct clk *);\n"
- "+/** @set_rate sets the new frequency rate */\n"
- "+\tint (*set_rate)(struct clk *, unsigned long value);\n"
- "+/** @set_parent sets the new parent clock */\n"
- "+\tint (*set_parent)(struct clk *clk, struct clk *parent);\n"
- "+/** @recalc updates the clock rate when the parent clock is updated\t */\n"
- "+\tvoid (*recalc)(struct clk *);\n"
- "+/** @round returns the allowed rate on the required value\t*/\n"
- "+\tunsigned long (*round)(struct clk *, unsigned long value);\n"
- "+/** @eval evaluates the clock rate based on a parent_rate but the\n"
- "+ * real clock rate is __not__ changed\n"
- "+ */\n"
- "+\tunsigned long (*eval)(struct clk *, unsigned long parent_rate);\n"
- "+};\n"
- "+\n"
- "+/**\n"
- "+ * struct clk - clock object\n"
- "+ */\n"
- "+struct clk {\n"
- "+\tspinlock_t\t\tlock;\n"
- "+\n"
- "+\tstruct kobject\t\tkobj;\n"
- "+\tstruct kobject\t\t*kdevices;\n"
- "+\n"
- "+\tint\t\t\tid;\n"
- "+\n"
- "+\tconst char\t\t*name;\n"
- "+\tstruct module\t\t*owner;\n"
- "+\n"
- "+\tstruct clk\t\t*parent;\n"
- "+\tstruct clk_ops\t\t*ops;\n"
- "+\n"
- "+\tvoid\t\t\t*private_data;\n"
- "+\n"
- "+\tunsigned long\t\trate;\n"
- "+\tunsigned long\t\tflags;\n"
- "+\n"
- "+\tunsigned int\t\tnr_active_clocks;\n"
- "+\tunsigned int\t\tnr_active_devices;\n"
- "+\tunsigned int\t\tnr_clocks;\n"
- "+\n"
- "+\tvoid\t\t\t*towner;/* the transaction owner of the clock */\n"
- "+\n"
- "+\tstruct klist\t\tchilds;\n"
- "+\tstruct klist\t\tdevices;\n"
- "+\n"
- "+\tstruct klist_node\tnode;\t\t/* for global link\t*/\n"
- "+\tstruct klist_node\tchild_node;\t/* for child link\t*/\n"
- "+};\n"
- "+\n"
- "+#define CLK_ALWAYS_ENABLED\t\t(0x1 << 0)\n"
- "+#define CLK_EVENT_PROPAGATES\t\t(0x1 << 1)\n"
- "+#define CLK_RATE_PROPAGATES\t\tCLK_EVENT_PROPAGATES\n"
- "+/* CLK_AUTO_SWITCHING: enable/disable the clock based on the\n"
- "+ * current active children\n"
- "+ */\n"
- "+#define CLK_AUTO_SWITCHING\t\t(0x1 << 2)\n"
- "+/* CLK_FOLLOW_PARENT: enable/disable the clock as the parent is\n"
- "+ * enabled/disabled\n"
- "+ */\n"
- "+#define CLK_FOLLOW_PARENT\t\t(0x1 << 3)\n"
- "+\n"
- "+/*\n"
- "+ * Flags to support the system standby\n"
- "+ */\n"
- "+#define CLK_PM_EXP_SHIFT\t(24)\n"
- "+#define CLK_PM_EXP_NRBITS\t(7)\n"
- "+#define CLK_PM_RATIO_SHIFT\t(16)\n"
- "+#define CLK_PM_RATIO_NRBITS\t(8)\n"
- "+#define CLK_PM_EDIT_SHIFT\t(31)\n"
- "+#define CLK_PM_EDIT_NRBITS\t(1)\n"
- "+#define CLK_PM_TURNOFF\t\t(((1<<CLK_PM_EXP_NRBITS)-1) << CLK_PM_EXP_SHIFT)\n"
- "+\n"
- "+int early_clk_register(struct clk *);\n"
- "+/**\n"
- "+ * Registers a new clock into the system\n"
- "+ */\n"
- "+int clk_register(struct clk *);\n"
- "+/**\n"
- "+ * Unregisters a clock into the system\n"
- "+ */\n"
- "+int clk_unregister(struct clk *);\n"
- "+\n"
- "+/**\n"
- "+ * Returns the clock rate if the  parent clock is 'parent_rate'\n"
- "+ */\n"
- "+unsigned long clk_evaluate_rate(struct clk *, unsigned long parent_rate);\n"
- "+\n"
- "+#define CLK_UNDEFINED_RATE\t(-1UL)\n"
- "+/**\n"
- "+ * Utility functions in the clock framework\n"
- "+ */\n"
- "+int clk_for_each(int (*fn)(struct clk *, void *), void *);\n"
- "+\n"
- "+int clk_for_each_child(struct clk *, int (*fn)(struct clk *, void *), void *);\n"
- "+\n"
- "+/** struct pdev_clk_info -\n"
- "+ *\n"
- "+ *  It's a meta data used to link the device of linux driver model\n"
- "+ *  to the clock framework.\n"
- "+ *  The device driver developers has to set only the clk field\n"
- "+ *  all the other fileds are managed in the clk core code\n"
- "+ */\n"
- "+struct pdev_clk_info {\n"
- "+\t/** the device owner    */\n"
- "+\tstruct platform_device  *pdev;\n"
- "+\t/** the clock address\t*/\n"
- "+\tstruct clk\t\t*clk;\n"
- "+\t/** used by the clock core*/\n"
- "+\tstruct klist_node\tnode;\n"
- "+};\n"
- "+\n"
- "+/******************** clk transition notifiers *******************/\n"
- "+#define\tNOTIFY_CLK_ENTERCHANGE\t0x1\n"
- "+#define\tNOTIFY_CLK_PRECHANGE\t0x2\n"
- "+#define\tNOTIFY_CLK_POSTCHANGE\t0x4\n"
- "+#define NOTIFY_CLK_EXITCHANGE\t0x8\n"
- "+\n"
- "+/** struct clk_event\n"
- "+ *\n"
- "+ * It's the object propagated during a clock transaction.\n"
- "+ * During a transaction each device will receive an array of 'struct clk_event'\n"
- "+ * based on the clocks it uses\n"
- "+ */\n"
- "+struct clk_event {\n"
- "+\t/** on which clock the event is\t\t*/\n"
- "+\tstruct clk *clk;\n"
- "+\t/** the clock rate before the event\t*/\n"
- "+\tunsigned long old_rate;\n"
- "+\t/** the clock rate after the event\t*/\n"
- "+\tunsigned long new_rate;\n"
- "+};\n"
- "+\n"
- "+enum clk_event_e {\n"
- "+\t_CLK_NOCHANGE,\n"
- "+\t_CLK_ENABLE,\n"
- "+\t_CLK_DISABLE,\n"
- "+\t_CLK_CHANGE\n"
- "+};\n"
- "+\n"
- "+/**\n"
- "+ * clk_event_decode -\n"
- "+ *\n"
- "+ * @event: the events has to be decoded\n"
- "+ * It's an utility function to identify what each clock\n"
- "+ * is doing\n"
- "+ */\n"
- "+static inline enum clk_event_e clk_event_decode(struct clk_event const *event)\n"
- "+{\n"
- "+\tif (event->old_rate == event->new_rate)\n"
- "+\t\treturn _CLK_NOCHANGE;\n"
- "+\tif (!event->old_rate && event->new_rate)\n"
- "+\t\treturn _CLK_ENABLE;\n"
- "+\tif (event->old_rate && !event->new_rate)\n"
- "+\t\treturn _CLK_DISABLE;\n"
- "+\treturn _CLK_CHANGE;\n"
- "+}\n"
- "+\n"
- "+enum notify_ret_e {\n"
- "+\tNOTIFY_EVENT_HANDLED = 0,\t\t/* event handled\t*/\n"
- "+\tNOTIFY_EVENT_NOTHANDLED,\t\t/* event not handled\t*/\n"
- "+};\n"
- "+\n"
- "+/* Some macro device oriented static initialization */\n"
- "+#define bind_clock(_clk)\t\t\t\t\t\\\n"
- "+\t.nr_clks = 1,\t\t\t\t\t\t\\\n"
- "+\t.clks = (struct pdev_clk_info[]) { {\t\t\t\\\n"
- "+\t\t.clk = (_clk),\t\t\t\t\t\\\n"
- "+\t\t} },\n"
- "+\n"
- "+#define pdevice_setclock(_dev, _clk)\t\t\t\t\\\n"
- "+\t(_dev)->clks[0].clk = (_clk);\t\t\t\t\\\n"
- "+\t(_dev)->nr_clks = 1;\n"
- "+\n"
- "+#define pdevice_setclock_byname(_dev, _clkname)\t\t\t\\\n"
- "+\t(_dev)->clks[0].clk = clk_get(NULL, _clkname);\t\t\\\n"
- "+\t(_dev)->nr_clks = 1;\n"
- "+\n"
- "+#define pdevice_num_clocks(_dev)\t((_dev)->nr_clks)\n"
- "+\n"
- "+#define pdevice_clock(dev, idx)\t\t((dev)->clks[(idx)].clk)\n"
- "+\n"
- "+/**\n"
- "+ * clk_generic_notify -\n"
- "+ *\n"
- "+ * @code: the code event\n"
- "+ * @dev: the platform_device under transaction\n"
- "+ * @data: the clock event descriptor\n"
- "+ *\n"
- "+ * it's a generic notify function for devie with _only_\n"
- "+ * one clock. It will :\n"
- "+ * - accept every 'ENTER' state\n"
- "+ * - suspend on 'PRE' state\n"
- "+ * - resume on 'POST' state\n"
- "+ * - do nothing on 'EXIT' state\n"
- "+ */\n"
- "+int clk_generic_notify(unsigned long code, struct platform_device *dev,\n"
- "+\tvoid *data);\n"
- "+\n"
- "+/*\n"
- "+ * clk_generic_evaluate_rate\n"
- "+ *\n"
- "+ * @clk: the analised clock\n"
- "+ * @prate: the parent rate\n"
- "+ *\n"
- "+ * Evaluate the clock rate (without hardware modification) based on a 'prate'\n"
- "+ * parent clock rate. It's based on 'divisor' relationship\n"
- "+ * between parent and child\n"
- "+ */\n"
- "+unsigned long clk_generic_evaluate_rate(struct clk *clk, unsigned long prate);\n"
- "+#endif\n"
- " #endif\n"
- "diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h\n"
- "index b67bb5d..db1989d 100644\n"
- "--- a/include/linux/platform_device.h\n"
- "+++ b/include/linux/platform_device.h\n"
- "@@ -12,6 +12,7 @@\n"
- " #define _PLATFORM_DEVICE_H_\n"
- " \n"
- " #include <linux/device.h>\n"
- "+#include <linux/clk.h>\n"
- " #include <linux/mod_devicetable.h>\n"
- " \n"
- " struct platform_device {\n"
- "@@ -22,6 +23,11 @@ struct platform_device {\n"
- " \tstruct resource\t* resource;\n"
- " \n"
- " \tstruct platform_device_id\t*id_entry;\n"
- "+#ifdef CONFIG_GENERIC_CLK_FM\n"
- "+\tunsigned long\tclk_state;      /* used by the core */\n"
- "+\tunsigned long\tnr_clks;\n"
- "+\tstruct pdev_clk_info    *clks;\n"
- "+#endif\n"
- " };\n"
- " \n"
- " #define platform_get_device_id(pdev)\t((pdev)->id_entry)\n"
- "@@ -61,6 +67,9 @@ struct platform_driver {\n"
- " \tint (*resume_early)(struct platform_device *);\n"
- " \tint (*resume)(struct platform_device *);\n"
- " \tstruct device_driver driver;\n"
- "+#ifdef CONFIG_GENERIC_CLK_FM\n"
- "+\tint (*notify)(unsigned long code, struct platform_device *, void *);\n"
- "+#endif\n"
- " \tstruct platform_device_id *id_table;\n"
- " };\n"
- " \n"
- "diff --git a/init/Kconfig b/init/Kconfig\n"
- "index 0682ecc..4254c5f 100644\n"
- "--- a/init/Kconfig\n"
- "+++ b/init/Kconfig\n"
- "@@ -1042,6 +1042,29 @@ config SLOW_WORK\n"
- " \n"
- " \t  See Documentation/slow-work.txt.\n"
- " \n"
- "+config GENERIC_CLK_FM\n"
- "+        default n\n"
- "+\tdepends on EXPERIMENTAL\n"
- "+        bool \"Generic Clock Framework\"\n"
- "+        help\n"
- "+          Add the clock framework in the Linux driver model\n"
- "+          to track the clocks used by each devices and drivers\n"
- "+\n"
- "+config CLK_FORCE_GENERIC_EVALUATE\n"
- "+        depends on GENERIC_CLK_FM\n"
- "+        default n\n"
- "+        bool \"Force the clk_generic_evaluate_rate\"\n"
- "+        help\n"
- "+          Say the if you want use the clk_generic_evaluate_rate on every clock\n"
- "+          without evaluate_rate\n"
- "+\n"
- "+config CLK_DEBUG\n"
- "+        depends on GENERIC_CLK_FM\n"
- "+        default n\n"
- "+        bool \"Debug the Generic Clk Framework\"\n"
- "+        help\n"
- "+          Prints some message to debug the clock framework\n"
- "+\n"
- " endmenu\t\t# General setup\n"
- " \n"
- " config HAVE_GENERIC_DMA_COHERENT\n"
- "-- \n"
- 1.6.2.5
- "\01:3\0"
- "b\0"
- "_______________________________________________\n"
- "linux-arm-kernel mailing list\n"
- "linux-arm-kernel@lists.infradead.org\n"
- http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
+ "  Francesco\n"
+ "-------------- next part --------------\n"
+ "An HTML attachment was scrubbed...\n"
+ "URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20091110/a197b928/attachment-0001.htm>\n"
+ "-------------- next part --------------\n"
+ "An embedded and charset-unspecified text was scrubbed...\n"
+ "Name: 0001-generic-clock-framework.patch\n"
+ URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20091110/a197b928/attachment-0001.el>
 
-722b6b97e358e49c261c236cffa3973e57a9e77fbafce148cb2d13547051f6d3
+8ee3db8167487feb3806c9b36ca0cbd707f648353f6abd185eac353d5493546a

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.