summaryrefslogtreecommitdiff
path: root/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/kexecboot/linux-kexecboot-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch')
-rw-r--r--packages/kexecboot/linux-kexecboot-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch446
1 files changed, 0 insertions, 446 deletions
diff --git a/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch b/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch
deleted file mode 100644
index c09c208c6a..0000000000
--- a/packages/kexecboot/linux-kexecboot-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch
+++ /dev/null
@@ -1,446 +0,0 @@
-From 62c9a23cfa7181369637d0b61a8e90c83c562f03 Mon Sep 17 00:00:00 2001
-From: Dmitry Baryshkov <dbaryshkov@gmail.com>
-Date: Mon, 4 Feb 2008 03:01:06 +0300
-Subject: [PATCH 39/64] Add generic framework for managing clocks.
-
-Provide a generic framework that platform may choose
-to support clocks api. In particular this provides
-platform-independant struct clk definition, a full
-implementation of clocks api and a set of functions
-for registering and unregistering clocks in a safe way.
-
-Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
----
- include/linux/clklib.h | 85 ++++++++++++++
- init/Kconfig | 7 +
- kernel/Makefile | 1 +
- kernel/clklib.c | 295 ++++++++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 388 insertions(+), 0 deletions(-)
- create mode 100644 include/linux/clklib.h
- create mode 100644 kernel/clklib.c
-
-diff --git a/include/linux/clklib.h b/include/linux/clklib.h
-new file mode 100644
-index 0000000..4bd9b4a
---- /dev/null
-+++ b/include/linux/clklib.h
-@@ -0,0 +1,85 @@
-+/*
-+ * Copyright (C) 2008 Dmitry Baryshkov
-+ *
-+ * This file is released under the GPL v2.
-+ */
-+
-+#ifndef CLKLIB_H
-+#define CLKLIB_H
-+
-+#include <linux/list.h>
-+
-+struct clk {
-+ struct list_head node;
-+ struct clk *parent;
-+
-+ const char *name;
-+ struct module *owner;
-+
-+ int users;
-+ unsigned long rate;
-+ int delay;
-+
-+ int (*can_get) (struct clk *, struct device *);
-+ int (*set_parent) (struct clk *, struct clk *);
-+ int (*enable) (struct clk *);
-+ void (*disable) (struct clk *);
-+ unsigned long (*getrate) (struct clk*);
-+ int (*setrate) (struct clk *, unsigned long);
-+ long (*roundrate) (struct clk *, unsigned long);
-+
-+ void *priv;
-+};
-+
-+int clk_register(struct clk *clk);
-+void clk_unregister(struct clk *clk);
-+static void __maybe_unused clks_register(struct clk *clks, size_t num)
-+{
-+ int i;
-+ for (i = 0; i < num; i++) {
-+ clk_register(&clks[i]);
-+ }
-+}
-+
-+
-+int clk_alloc_function(const char *parent, struct clk *clk);
-+
-+struct clk_function {
-+ const char *parent;
-+ struct clk *clk;
-+};
-+
-+#define CLK_FUNC(_clock, _function, _can_get, _data, _format) \
-+ { \
-+ .parent = _clock, \
-+ .clk = &(struct clk) { \
-+ .name= _function, \
-+ .owner = THIS_MODULE, \
-+ .can_get = _can_get, \
-+ .priv = _data, \
-+ .format = _format, \
-+ }, \
-+ }
-+
-+static int __maybe_unused clk_alloc_functions(
-+ struct clk_function *funcs,
-+ int num)
-+{
-+ int i;
-+ int rc;
-+
-+ for (i = 0; i < num; i++) {
-+ rc = clk_alloc_function(funcs[i].parent, funcs[i].clk);
-+
-+ if (rc) {
-+ printk(KERN_ERR "Error allocating %s.%s function.\n",
-+ funcs[i].parent,
-+ funcs[i].clk->name);
-+ return rc;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+#endif
-diff --git a/init/Kconfig b/init/Kconfig
-index b9d11a8..05b62ba 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -435,6 +435,13 @@ config CC_OPTIMIZE_FOR_SIZE
- config SYSCTL
- bool
-
-+config HAVE_CLOCK_LIB
-+ bool
-+ help
-+ Platforms select clocklib if they use this infrastructure
-+ for managing their clocks both built into SoC and provided
-+ by external devices.
-+
- menuconfig EMBEDDED
- bool "Configure standard kernel features (for small systems)"
- help
-diff --git a/kernel/Makefile b/kernel/Makefile
-index 6d9a87c..0b2ade7 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -58,6 +58,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
- obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
- obj-$(CONFIG_MARKERS) += marker.o
- obj-$(CONFIG_LATENCYTOP) += latencytop.o
-+obj-$(CONFIG_HAVE_CLOCK_LIB) += clklib.o
-
- ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
- # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
-diff --git a/kernel/clklib.c b/kernel/clklib.c
-new file mode 100644
-index 0000000..203af3d
---- /dev/null
-+++ b/kernel/clklib.c
-@@ -0,0 +1,295 @@
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/clk.h>
-+#include <linux/clklib.h>
-+#include <linux/spinlock.h>
-+#include <linux/err.h>
-+#include <linux/delay.h>
-+
-+static LIST_HEAD(clocks);
-+static DEFINE_SPINLOCK(clocks_lock);
-+
-+static int __clk_register(struct clk *clk)
-+{
-+ if (clk->parent &&
-+ !try_module_get(clk->parent->owner))
-+ return -EINVAL;
-+
-+ list_add_tail(&clk->node, &clocks);
-+
-+ return 0;
-+}
-+
-+int clk_register(struct clk *clk)
-+{
-+ unsigned long flags;
-+ int rc;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ rc = __clk_register(clk);
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+
-+ return rc;
-+}
-+EXPORT_SYMBOL(clk_register);
-+
-+void clk_unregister(struct clk *clk)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+ list_del(&clk->node);
-+ if (clk->parent)
-+ module_put(clk->parent->owner);
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+}
-+EXPORT_SYMBOL(clk_unregister);
-+
-+struct clk *clk_get(struct device *dev, const char *id)
-+{
-+ struct clk *p, *clk = ERR_PTR(-ENOENT);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ list_for_each_entry(p, &clocks, node) {
-+ if (strcmp(id, p->name) == 0 &&
-+ (!p->can_get || p->can_get(p, dev)) &&
-+ try_module_get(p->owner)) {
-+ clk = p;
-+ break;
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+
-+ return clk;
-+}
-+EXPORT_SYMBOL(clk_get);
-+
-+void clk_put(struct clk *clk)
-+{
-+ unsigned long flags;
-+
-+ if (!clk || IS_ERR(clk))
-+ return;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ module_put(clk->owner);
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+}
-+EXPORT_SYMBOL(clk_put);
-+
-+int clk_set_parent(struct clk *clk, struct clk *parent)
-+{
-+ int rc;
-+ unsigned long flags;
-+
-+ if (!clk || IS_ERR(clk))
-+ return -EINVAL;
-+
-+ if (!clk->set_parent)
-+ return -EINVAL;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ rc = clk->set_parent(clk, parent);
-+ if (!rc)
-+ clk->parent = parent;
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+
-+ return rc;
-+}
-+EXPORT_SYMBOL(clk_set_parent);
-+
-+static int __clk_enable(struct clk *clk)
-+{
-+ int rc = 0;
-+
-+ if (clk->parent) {
-+ rc = __clk_enable(clk->parent);
-+
-+ if (rc)
-+ return rc;
-+ }
-+
-+ if (clk->users++ == 0)
-+ if (clk->enable)
-+ rc = clk->enable(clk);
-+
-+ if (clk->delay)
-+ udelay(clk->delay);
-+
-+ return rc;
-+}
-+
-+int clk_enable(struct clk *clk)
-+{
-+ unsigned long flags;
-+ int rc;
-+
-+ if (!clk || IS_ERR(clk))
-+ return -EINVAL;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ rc = __clk_enable(clk);
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+
-+ return rc;
-+}
-+EXPORT_SYMBOL(clk_enable);
-+
-+static void __clk_disable(struct clk *clk)
-+{
-+ if (clk->users <= 0) {
-+ WARN_ON(1);
-+ return;
-+ }
-+
-+ if (--clk->users == 0)
-+ if (clk->disable)
-+ clk->disable(clk);
-+
-+ if (clk->parent)
-+ __clk_disable(clk->parent);
-+}
-+
-+void clk_disable(struct clk *clk)
-+{
-+ unsigned long flags;
-+
-+ if (!clk || IS_ERR(clk))
-+ return;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ __clk_disable(clk);
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+}
-+EXPORT_SYMBOL(clk_disable);
-+
-+static unsigned long __clk_get_rate(struct clk *clk)
-+{
-+ unsigned long rate = 0;
-+
-+ for (;;) {
-+ if (rate || !clk)
-+ return rate;
-+
-+ if (clk->getrate)
-+ rate = clk->getrate(clk);
-+ else if (clk->rate)
-+ rate = clk->rate;
-+ else
-+ clk = clk->parent;
-+ }
-+}
-+
-+unsigned long clk_get_rate(struct clk *clk)
-+{
-+ unsigned long rate = 0;
-+ unsigned long flags;
-+
-+ if (!clk || IS_ERR(clk))
-+ return -EINVAL;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ rate = __clk_get_rate(clk);
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+
-+ return rate;
-+}
-+EXPORT_SYMBOL(clk_get_rate);
-+
-+long clk_round_rate(struct clk *clk, unsigned long rate)
-+{
-+ long res;
-+ unsigned long flags;
-+
-+ if (!clk || IS_ERR(clk))
-+ return -EINVAL;
-+
-+ if (!clk->roundrate)
-+ return -EINVAL;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ res = clk->roundrate(clk, rate);
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+
-+ return res;
-+}
-+EXPORT_SYMBOL(clk_round_rate);
-+
-+int clk_set_rate(struct clk *clk, unsigned long rate)
-+{
-+ int rc;
-+ unsigned long flags;
-+
-+ if (!clk || IS_ERR(clk))
-+ return -EINVAL;
-+
-+ if (!clk->setrate)
-+ return -EINVAL;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ rc = clk->setrate(clk, rate);
-+
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+
-+ return rc;
-+}
-+EXPORT_SYMBOL(clk_set_rate);
-+
-+int clk_alloc_function(const char *parent, struct clk *clk)
-+{
-+ int rc = 0;
-+ unsigned long flags;
-+ struct clk *pclk;
-+ bool found = false;
-+
-+ spin_lock_irqsave(&clocks_lock, flags);
-+
-+ list_for_each_entry(pclk, &clocks, node) {
-+ if (strcmp(parent, pclk->name) == 0 &&
-+ try_module_get(pclk->owner)) {
-+ found = true;
-+ break;
-+ }
-+ }
-+
-+ if (!found) {
-+ rc = -ENODEV;
-+ goto out;
-+ }
-+
-+ clk->parent = pclk;
-+
-+ __clk_register(clk);
-+ /*
-+ * We locked parent owner during search
-+ * and also in __clk_register. Free one reference
-+ */
-+ module_put(pclk->owner);
-+
-+out:
-+ if (rc) {
-+ kfree(clk);
-+ }
-+ spin_unlock_irqrestore(&clocks_lock, flags);
-+
-+ return rc;
-+}
-+EXPORT_SYMBOL(clk_alloc_function);
---
-1.5.3.8
-