Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[ARM] clkdev: add generic clkdev infrastructure

Add some generic infrastructure to assist looking up struct clks
for the ARM architecture.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Russell King and committed by
Russell King
0318e693 ed313489

+162
+3
arch/arm/common/Kconfig
··· 33 33 34 34 config SHARP_SCOOP 35 35 bool 36 + 37 + config COMMON_CLKDEV 38 + bool
+1
arch/arm/common/Makefile
··· 17 17 obj-$(CONFIG_ARCH_IXP2000) += uengine.o 18 18 obj-$(CONFIG_ARCH_IXP23XX) += uengine.o 19 19 obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o 20 + obj-$(CONFIG_COMMON_CLKDEV) += clkdev.o
+128
arch/arm/common/clkdev.c
··· 1 + /* 2 + * arch/arm/common/clkdev.c 3 + * 4 + * Copyright (C) 2008 Russell King. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * Helper for the clk API to assist looking up a struct clk. 11 + */ 12 + #include <linux/module.h> 13 + #include <linux/kernel.h> 14 + #include <linux/device.h> 15 + #include <linux/list.h> 16 + #include <linux/errno.h> 17 + #include <linux/err.h> 18 + #include <linux/string.h> 19 + #include <linux/mutex.h> 20 + 21 + #include <asm/clkdev.h> 22 + #include <mach/clkdev.h> 23 + 24 + static LIST_HEAD(clocks); 25 + static DEFINE_MUTEX(clocks_mutex); 26 + 27 + static struct clk *clk_find(const char *dev_id, const char *con_id) 28 + { 29 + struct clk_lookup *p; 30 + struct clk *clk = NULL; 31 + int match, best = 0; 32 + 33 + list_for_each_entry(p, &clocks, node) { 34 + if ((p->dev_id && !dev_id) || (p->con_id && !con_id)) 35 + continue; 36 + match = 0; 37 + if (p->dev_id) 38 + match += 2 * (strcmp(p->dev_id, dev_id) == 0); 39 + if (p->con_id) 40 + match += 1 * (strcmp(p->con_id, con_id) == 0); 41 + if (match == 0) 42 + continue; 43 + 44 + if (match > best) { 45 + clk = p->clk; 46 + best = match; 47 + } 48 + } 49 + return clk; 50 + } 51 + 52 + struct clk *clk_get(struct device *dev, const char *con_id) 53 + { 54 + const char *dev_id = dev ? dev_name(dev) : NULL; 55 + struct clk *clk; 56 + 57 + mutex_lock(&clocks_mutex); 58 + clk = clk_find(dev_id, con_id); 59 + if (clk && !__clk_get(clk)) 60 + clk = NULL; 61 + mutex_unlock(&clocks_mutex); 62 + 63 + return clk ? clk : ERR_PTR(-ENOENT); 64 + } 65 + EXPORT_SYMBOL(clk_get); 66 + 67 + void clk_put(struct clk *clk) 68 + { 69 + __clk_put(clk); 70 + } 71 + EXPORT_SYMBOL(clk_put); 72 + 73 + void clkdev_add(struct clk_lookup *cl) 74 + { 75 + mutex_lock(&clocks_mutex); 76 + list_add_tail(&cl->node, &clocks); 77 + mutex_unlock(&clocks_mutex); 78 + } 79 + EXPORT_SYMBOL(clkdev_add); 80 + 81 + #define MAX_DEV_ID 20 82 + #define MAX_CON_ID 16 83 + 84 + struct clk_lookup_alloc { 85 + struct clk_lookup cl; 86 + char dev_id[MAX_DEV_ID]; 87 + char con_id[MAX_CON_ID]; 88 + }; 89 + 90 + struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, 91 + const char *dev_fmt, ...) 92 + { 93 + struct clk_lookup_alloc *cla; 94 + 95 + cla = kzalloc(sizeof(*cla), GFP_KERNEL); 96 + if (!cla) 97 + return NULL; 98 + 99 + cla->cl.clk = clk; 100 + if (con_id) { 101 + strlcpy(cla->con_id, con_id, sizeof(cla->con_id)); 102 + cla->cl.con_id = cla->con_id; 103 + } 104 + 105 + if (dev_fmt) { 106 + va_list ap; 107 + 108 + va_start(ap, dev_fmt); 109 + vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap); 110 + cla->cl.dev_id = cla->dev_id; 111 + va_end(ap); 112 + } 113 + 114 + return &cla->cl; 115 + } 116 + EXPORT_SYMBOL(clkdev_alloc); 117 + 118 + /* 119 + * clkdev_drop - remove a clock dynamically allocated 120 + */ 121 + void clkdev_drop(struct clk_lookup *cl) 122 + { 123 + mutex_lock(&clocks_mutex); 124 + list_del(&cl->node); 125 + mutex_unlock(&clocks_mutex); 126 + kfree(cl); 127 + } 128 + EXPORT_SYMBOL(clkdev_drop);
+30
arch/arm/include/asm/clkdev.h
··· 1 + /* 2 + * arch/arm/include/asm/clkdev.h 3 + * 4 + * Copyright (C) 2008 Russell King. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * Helper for the clk API to assist looking up a struct clk. 11 + */ 12 + #ifndef __ASM_CLKDEV_H 13 + #define __ASM_CLKDEV_H 14 + 15 + struct clk; 16 + 17 + struct clk_lookup { 18 + struct list_head node; 19 + const char *dev_id; 20 + const char *con_id; 21 + struct clk *clk; 22 + }; 23 + 24 + struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, 25 + const char *dev_fmt, ...); 26 + 27 + void clkdev_add(struct clk_lookup *cl); 28 + void clkdev_drop(struct clk_lookup *cl); 29 + 30 + #endif