Messages in this thread Patch in this message | | | Date | Thu, 30 Oct 2008 13:35:09 +0100 | From | "Miguel Ángel Álvarez" <> | Subject | [PATCH 1/1] ixp4xx: clock API |
| |
Hi.
This is and implementation of clock API for IXP4XX based on PXA2XX. (linux-2.6.27.4). I would appreciate comments on it.
Signed-off-by: Miguel Angel Alvarez <gotzoncabanes@gmail.com> --- diff -uprN linux-2.6.27.4_orig/arch/arm/mach-ixp4xx/clock.c linux-2.6.27.4/arch/arm/mach-ixp4xx/clock.c --- linux-2.6.27.4_orig/arch/arm/mach-ixp4xx/clock.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.27.4/arch/arm/mach-ixp4xx/clock.c 2008-10-30 12:17:01.000000000 +0100 @@ -0,0 +1,132 @@ +/* + * linux/arch/arm/mach-sa1100/clock.c + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/string.h> +#include <linux/clk.h> +#include <linux/spinlock.h> +#include <linux/platform_device.h> +#include <linux/delay.h> + +#include <mach/hardware.h> + +#include <mach/clock.h> + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); +static DEFINE_SPINLOCK(clocks_lock); + +static struct clk *clk_lookup(struct device *dev, const char *id) +{ + struct clk *p; + + list_for_each_entry(p, &clocks, node) + if (strcmp(id, p->name) == 0 && p->dev == dev) + return p; + + return NULL; +} + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + mutex_lock(&clocks_mutex); + p = clk_lookup(dev, id); + if (!p) + p = clk_lookup(NULL, id); + if (p) + clk = p; + mutex_unlock(&clocks_mutex); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + + spin_lock_irqsave(&clocks_lock, flags); + if (clk->enabled++ == 0) + clk->ops->enable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); + + if (clk->delay) + udelay(clk->delay); + + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + WARN_ON(clk->enabled == 0); + + spin_lock_irqsave(&clocks_lock, flags); + if (--clk->enabled == 0) + clk->ops->disable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + unsigned long rate; + + rate = clk->rate; + if (clk->ops->getrate) + rate = clk->ops->getrate(clk); + + return rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_void_enable(struct clk *clk) +{ +} + +void clk_void_disable(struct clk *clk) +{ +} + +const struct clkops clk_void_ops = { + .enable = clk_void_enable, + .disable = clk_void_disable, +}; + +static struct clk common_clks[] = { + { + .name = "SSPCLK", + .ops = &clk_void_ops, + .rate = 3686400, + }, +}; + +void clks_register(struct clk *clks, size_t num) +{ + int i; + + mutex_lock(&clocks_mutex); + for (i = 0; i < num; i++) + list_add(&clks[i].node, &clocks); + mutex_unlock(&clocks_mutex); +} + +static int __init clk_init(void) +{ + clks_register(common_clks, ARRAY_SIZE(common_clks)); + return 0; +} +arch_initcall(clk_init); diff -uprN linux-2.6.27.4_orig/arch/arm/mach-ixp4xx/include/mach/clock.h linux-2.6.27.4/arch/arm/mach-ixp4xx/include/mach/clock.h --- linux-2.6.27.4_orig/arch/arm/mach-ixp4xx/include/mach/clock.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.27.4/arch/arm/mach-ixp4xx/include/mach/clock.h 2008-10-30 12:17:19.000000000 +0100 @@ -0,0 +1,44 @@ +struct clk; + +struct clkops { + void (*enable)(struct clk *); + void (*disable)(struct clk *); + unsigned long (*getrate)(struct clk *); +}; + +struct clk { + struct list_head node; + const char *name; + struct device *dev; + const struct clkops *ops; + unsigned long rate; + unsigned int cken; + unsigned int delay; + unsigned int enabled; +}; + +#define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \ + { \ + .name = _name, \ + .dev = _dev, \ + .ops = &clk_cken_ops, \ + .rate = _rate, \ + .cken = CKEN_##_cken, \ + .delay = _delay, \ + } + +#define INIT_CK(_name, _cken, _ops, _dev) \ + { \ + .name = _name, \ + .dev = _dev, \ + .ops = _ops, \ + .cken = CKEN_##_cken, \ + } + +extern const struct clkops clk_cken_ops; + +void clk_cken_enable(struct clk *clk); +void clk_cken_disable(struct clk *clk); + +void clks_register(struct clk *clks, size_t num); + diff -uprN linux-2.6.27.4_orig/arch/arm/mach-ixp4xx/Makefile linux-2.6.27.4/arch/arm/mach-ixp4xx/Makefile --- linux-2.6.27.4_orig/arch/arm/mach-ixp4xx/Makefile 2008-10-30 12:01:27.000000000 +0100 +++ linux-2.6.27.4/arch/arm/mach-ixp4xx/Makefile 2008-10-30 12:17:46.000000000 +0100 @@ -17,7 +17,7 @@ obj-pci-$(CONFIG_MACH_GATEWAY7001) += ga obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o obj-pci-$(CONFIG_MACH_FSG) += fsg-pci.o
-obj-y += common.o +obj-y += common.o clock.o
obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o obj-$(CONFIG_MACH_AVILA) += avila-setup.o Miguel Ángel Álvarez -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |