sh: Merge clkdev API updates.
authorPaul Mundt <lethal@linux-sh.org>
Mon, 8 Mar 2010 12:45:19 +0000 (21:45 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Tue, 9 Mar 2010 02:57:17 +0000 (11:57 +0900)
This rolls in the remainder of the clkdev API bits from the ARM tree.
This can more or less be used verbatim, so we just copy it over and nuke
our local version.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/include/asm/clkdev.h [new file with mode: 0644]
arch/sh/include/asm/clock.h
arch/sh/kernel/Makefile
arch/sh/kernel/clkdev.c [new file with mode: 0644]
arch/sh/kernel/cpu/clock.c

diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
new file mode 100644 (file)
index 0000000..5645f35
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  arch/sh/include/asm/clkdev.h
+ *
+ * Cloned from arch/arm/include/asm/clkdev.h:
+ *
+ *  Copyright (C) 2008 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#ifndef __ASM_CLKDEV_H
+#define __ASM_CLKDEV_H
+
+struct clk;
+
+struct clk_lookup {
+       struct list_head        node;
+       const char              *dev_id;
+       const char              *con_id;
+       struct clk              *clk;
+};
+
+struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
+       const char *dev_fmt, ...);
+
+void clkdev_add(struct clk_lookup *cl);
+void clkdev_drop(struct clk_lookup *cl);
+
+void clkdev_add_table(struct clk_lookup *, size_t);
+int clk_add_alias(const char *, const char *, char *, struct device *);
+
+#endif
index 11da4c5..4b19179 100644 (file)
@@ -45,13 +45,6 @@ struct clk {
        struct cpufreq_frequency_table *freq_table;
 };
 
-struct clk_lookup {
-       struct list_head        node;
-       const char              *dev_id;
-       const char              *con_id;
-       struct clk              *clk;
-};
-
 #define CLK_ENABLE_ON_INIT     (1 << 0)
 
 /* Should be defined by processor-specific code */
index 02fd3ae..650b92f 100644 (file)
@@ -11,7 +11,7 @@ endif
 
 CFLAGS_REMOVE_return_address.o = -pg
 
-obj-y  := debugtraps.o dma-nommu.o dumpstack.o                         \
+obj-y  := clkdev.o debugtraps.o dma-nommu.o dumpstack.o                \
           idle.o io.o io_generic.o irq.o                               \
           irq_$(BITS).o machvec.o nmi_debug.o process.o                \
           process_$(BITS).o ptrace_$(BITS).o                           \
diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c
new file mode 100644 (file)
index 0000000..29cd802
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * arch/sh/kernel/clkdev.c
+ *
+ * Cloned from arch/arm/common/clkdev.c:
+ *
+ *  Copyright (C) 2008 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <asm/clock.h>
+#include <asm/clkdev.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*
+ * Find the correct struct clk for the device and connection ID.
+ * We do slightly fuzzy matching here:
+ *  An entry with a NULL ID is assumed to be a wildcard.
+ *  If an entry has a device ID, it must match
+ *  If an entry has a connection ID, it must match
+ * Then we take the most specific entry - with the following
+ * order of precidence: dev+con > dev only > con only.
+ */
+static struct clk *clk_find(const char *dev_id, const char *con_id)
+{
+       struct clk_lookup *p;
+       struct clk *clk = NULL;
+       int match, best = 0;
+
+       list_for_each_entry(p, &clocks, node) {
+               match = 0;
+               if (p->dev_id) {
+                       if (!dev_id || strcmp(p->dev_id, dev_id))
+                               continue;
+                       match += 2;
+               }
+               if (p->con_id) {
+                       if (!con_id || strcmp(p->con_id, con_id))
+                               continue;
+                       match += 1;
+               }
+               if (match == 0)
+                       continue;
+
+               if (match > best) {
+                       clk = p->clk;
+                       best = match;
+               }
+       }
+       return clk;
+}
+
+struct clk *clk_get_sys(const char *dev_id, const char *con_id)
+{
+       struct clk *clk;
+
+       mutex_lock(&clocks_mutex);
+       clk = clk_find(dev_id, con_id);
+       mutex_unlock(&clocks_mutex);
+
+       return clk ? clk : ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get_sys);
+
+void clkdev_add(struct clk_lookup *cl)
+{
+       mutex_lock(&clocks_mutex);
+       list_add_tail(&cl->node, &clocks);
+       mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clkdev_add);
+
+void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
+{
+       mutex_lock(&clocks_mutex);
+       while (num--) {
+               list_add_tail(&cl->node, &clocks);
+               cl++;
+       }
+       mutex_unlock(&clocks_mutex);
+}
+
+#define MAX_DEV_ID     20
+#define MAX_CON_ID     16
+
+struct clk_lookup_alloc {
+       struct clk_lookup cl;
+       char    dev_id[MAX_DEV_ID];
+       char    con_id[MAX_CON_ID];
+};
+
+struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
+       const char *dev_fmt, ...)
+{
+       struct clk_lookup_alloc *cla;
+
+       cla = kzalloc(sizeof(*cla), GFP_KERNEL);
+       if (!cla)
+               return NULL;
+
+       cla->cl.clk = clk;
+       if (con_id) {
+               strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
+               cla->cl.con_id = cla->con_id;
+       }
+
+       if (dev_fmt) {
+               va_list ap;
+
+               va_start(ap, dev_fmt);
+               vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
+               cla->cl.dev_id = cla->dev_id;
+               va_end(ap);
+       }
+
+       return &cla->cl;
+}
+EXPORT_SYMBOL(clkdev_alloc);
+
+int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
+       struct device *dev)
+{
+       struct clk *r = clk_get(dev, id);
+       struct clk_lookup *l;
+
+       if (IS_ERR(r))
+               return PTR_ERR(r);
+
+       l = clkdev_alloc(r, alias, alias_dev_name);
+       clk_put(r);
+       if (!l)
+               return -ENODEV;
+       clkdev_add(l);
+       return 0;
+}
+EXPORT_SYMBOL(clk_add_alias);
+
+/*
+ * clkdev_drop - remove a clock dynamically allocated
+ */
+void clkdev_drop(struct clk_lookup *cl)
+{
+       mutex_lock(&clocks_mutex);
+       list_del(&cl->node);
+       mutex_unlock(&clocks_mutex);
+       kfree(cl);
+}
+EXPORT_SYMBOL(clkdev_drop);
index 83da5de..9ded1bc 100644 (file)
  *
  *  Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
  *
- *  With clkdev bits:
- *
- *     Copyright (C) 2008 Russell King.
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -30,6 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/debugfs.h>
 #include <linux/cpufreq.h>
+#include <linux/clk.h>
 #include <asm/clock.h>
 #include <asm/machvec.h>
 
@@ -397,56 +394,6 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL_GPL(clk_round_rate);
 
-/*
- * Find the correct struct clk for the device and connection ID.
- * We do slightly fuzzy matching here:
- *  An entry with a NULL ID is assumed to be a wildcard.
- *  If an entry has a device ID, it must match
- *  If an entry has a connection ID, it must match
- * Then we take the most specific entry - with the following
- * order of precidence: dev+con > dev only > con only.
- */
-static struct clk *clk_find(const char *dev_id, const char *con_id)
-{
-       struct clk_lookup *p;
-       struct clk *clk = NULL;
-       int match, best = 0;
-
-       list_for_each_entry(p, &clock_list, node) {
-               match = 0;
-               if (p->dev_id) {
-                       if (!dev_id || strcmp(p->dev_id, dev_id))
-                               continue;
-                       match += 2;
-               }
-               if (p->con_id) {
-                       if (!con_id || strcmp(p->con_id, con_id))
-                               continue;
-                       match += 1;
-               }
-               if (match == 0)
-                       continue;
-
-               if (match > best) {
-                       clk = p->clk;
-                       best = match;
-               }
-       }
-       return clk;
-}
-
-struct clk *clk_get_sys(const char *dev_id, const char *con_id)
-{
-       struct clk *clk;
-
-       mutex_lock(&clock_list_sem);
-       clk = clk_find(dev_id, con_id);
-       mutex_unlock(&clock_list_sem);
-
-       return clk ? clk : ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL_GPL(clk_get_sys);
-
 /*
  * Returns a clock. Note that we first try to use device id on the bus
  * and clock name. If this fails, we try to use clock name only.