Commit 97d654f8 authored by Russell King's avatar Russell King Committed by Russell King

[ARM] Convert SA1111 to use clock architecture

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 824b5b5e
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -36,10 +37,6 @@ ...@@ -36,10 +37,6 @@
#include <asm/hardware/sa1111.h> #include <asm/hardware/sa1111.h>
#ifdef CONFIG_ARCH_PXA
#include <asm/arch/pxa-regs.h>
#endif
extern void __init sa1110_mb_enable(void); extern void __init sa1110_mb_enable(void);
/* /*
...@@ -51,6 +48,7 @@ extern void __init sa1110_mb_enable(void); ...@@ -51,6 +48,7 @@ extern void __init sa1110_mb_enable(void);
*/ */
struct sa1111 { struct sa1111 {
struct device *dev; struct device *dev;
struct clk *clk;
unsigned long phys; unsigned long phys;
int irq; int irq;
spinlock_t lock; spinlock_t lock;
...@@ -451,19 +449,7 @@ static void sa1111_wake(struct sa1111 *sachip) ...@@ -451,19 +449,7 @@ static void sa1111_wake(struct sa1111 *sachip)
spin_lock_irqsave(&sachip->lock, flags); spin_lock_irqsave(&sachip->lock, flags);
#ifdef CONFIG_ARCH_SA1100 clk_enable(sachip->clk);
/*
* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
* (SA-1110 Developer's Manual, section 9.1.2.1)
*/
GAFR |= GPIO_32_768kHz;
GPDR |= GPIO_32_768kHz;
TUCR = TUCR_3_6864MHz;
#elif CONFIG_ARCH_PXA
pxa_gpio_mode(GPIO11_3_6MHz_MD);
#else
#error missing clock setup
#endif
/* /*
* Turn VCO on, and disable PLL Bypass. * Turn VCO on, and disable PLL Bypass.
...@@ -641,6 +627,12 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) ...@@ -641,6 +627,12 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
memset(sachip, 0, sizeof(struct sa1111)); memset(sachip, 0, sizeof(struct sa1111));
sachip->clk = clk_get(me, "GPIO27_CLK");
if (!sachip->clk) {
ret = PTR_ERR(sachip->clk);
goto err_free;
}
spin_lock_init(&sachip->lock); spin_lock_init(&sachip->lock);
sachip->dev = me; sachip->dev = me;
...@@ -656,7 +648,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) ...@@ -656,7 +648,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
sachip->base = ioremap(mem->start, PAGE_SIZE * 2); sachip->base = ioremap(mem->start, PAGE_SIZE * 2);
if (!sachip->base) { if (!sachip->base) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto err_clkput;
} }
/* /*
...@@ -666,7 +658,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) ...@@ -666,7 +658,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id); printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
ret = -ENODEV; ret = -ENODEV;
goto unmap; goto err_unmap;
} }
printk(KERN_INFO "SA1111 Microprocessor Companion Chip: " printk(KERN_INFO "SA1111 Microprocessor Companion Chip: "
...@@ -726,9 +718,11 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) ...@@ -726,9 +718,11 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
return 0; return 0;
unmap: err_unmap:
iounmap(sachip->base); iounmap(sachip->base);
out: err_clkput:
clk_put(sachip->clk);
err_free:
kfree(sachip); kfree(sachip);
return ret; return ret;
} }
...@@ -751,6 +745,8 @@ static void __sa1111_remove(struct sa1111 *sachip) ...@@ -751,6 +745,8 @@ static void __sa1111_remove(struct sa1111 *sachip)
sa1111_writel(0, irqbase + SA1111_WAKEEN0); sa1111_writel(0, irqbase + SA1111_WAKEEN0);
sa1111_writel(0, irqbase + SA1111_WAKEEN1); sa1111_writel(0, irqbase + SA1111_WAKEEN1);
clk_disable(sachip->clk);
if (sachip->irq != NO_IRQ) { if (sachip->irq != NO_IRQ) {
set_irq_chained_handler(sachip->irq, NULL); set_irq_chained_handler(sachip->irq, NULL);
set_irq_data(sachip->irq, NULL); set_irq_data(sachip->irq, NULL);
...@@ -759,6 +755,7 @@ static void __sa1111_remove(struct sa1111 *sachip) ...@@ -759,6 +755,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
} }
iounmap(sachip->base); iounmap(sachip->base);
clk_put(sachip->clk);
kfree(sachip); kfree(sachip);
} }
...@@ -857,6 +854,8 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) ...@@ -857,6 +854,8 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
sa1111_writel(0, sachip->base + SA1111_SKPWM0); sa1111_writel(0, sachip->base + SA1111_SKPWM0);
sa1111_writel(0, sachip->base + SA1111_SKPWM1); sa1111_writel(0, sachip->base + SA1111_SKPWM1);
clk_disable(sachip->clk);
spin_unlock_irqrestore(&sachip->lock, flags); spin_unlock_irqrestore(&sachip->lock, flags);
return 0; return 0;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
# Common support (must be linked before board specific support) # Common support (must be linked before board specific support)
obj-y += generic.o irq.o dma.o time.o obj-y += clock.o generic.o irq.o dma.o time.o
obj-$(CONFIG_PXA25x) += pxa25x.o obj-$(CONFIG_PXA25x) += pxa25x.o
obj-$(CONFIG_PXA27x) += pxa27x.o obj-$(CONFIG_PXA27x) += pxa27x.o
......
/*
* 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 <asm/arch/pxa-regs.h>
#include <asm/hardware.h>
#include <asm/semaphore.h>
struct clk {
struct list_head node;
unsigned long rate;
struct module *owner;
const char *name;
unsigned int enabled;
void (*enable)(void);
void (*disable)(void);
};
static LIST_HEAD(clocks);
static DECLARE_MUTEX(clocks_sem);
static DEFINE_SPINLOCK(clocks_lock);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
down(&clocks_sem);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
up(&clocks_sem);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
int clk_enable(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clocks_lock, flags);
if (clk->enabled++ == 0)
clk->enable();
spin_unlock_irqrestore(&clocks_lock, flags);
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->disable();
spin_unlock_irqrestore(&clocks_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
static void clk_gpio27_enable(void)
{
pxa_gpio_mode(GPIO11_3_6MHz_MD);
}
static void clk_gpio27_disable(void)
{
}
static struct clk clk_gpio27 = {
.name = "GPIO27_CLK",
.rate = 3686400,
.enable = clk_gpio27_enable,
.disable = clk_gpio27_disable,
};
int clk_register(struct clk *clk)
{
down(&clocks_sem);
list_add(&clk->node, &clocks);
up(&clocks_sem);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
down(&clocks_sem);
list_del(&clk->node);
up(&clocks_sem);
}
EXPORT_SYMBOL(clk_unregister);
static int __init clk_init(void)
{
clk_register(&clk_gpio27);
return 0;
}
arch_initcall(clk_init);
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
# Common support # Common support
obj-y := generic.o irq.o dma.o time.o obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o
obj-m := obj-m :=
obj-n := obj-n :=
obj- := obj- :=
......
/*
* 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 <asm/hardware.h>
#include <asm/semaphore.h>
struct clk {
struct list_head node;
unsigned long rate;
struct module *owner;
const char *name;
unsigned int enabled;
void (*enable)(void);
void (*disable)(void);
};
static LIST_HEAD(clocks);
static DECLARE_MUTEX(clocks_sem);
static DEFINE_SPINLOCK(clocks_lock);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
down(&clocks_sem);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
up(&clocks_sem);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
int clk_enable(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clocks_lock, flags);
if (clk->enabled++ == 0)
clk->enable();
spin_unlock_irqrestore(&clocks_lock, flags);
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->disable();
spin_unlock_irqrestore(&clocks_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
static void clk_gpio27_enable(void)
{
/*
* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
* (SA-1110 Developer's Manual, section 9.1.2.1)
*/
GAFR |= GPIO_32_768kHz;
GPDR |= GPIO_32_768kHz;
TUCR = TUCR_3_6864MHz;
}
static void clk_gpio27_disable(void)
{
TUCR = 0;
GPDR &= ~GPIO_32_768kHz;
GAFR &= ~GPIO_32_768kHz;
}
static struct clk clk_gpio27 = {
.name = "GPIO27_CLK",
.rate = 3686400,
.enable = clk_gpio27_enable,
.disable = clk_gpio27_disable,
};
int clk_register(struct clk *clk)
{
down(&clocks_sem);
list_add(&clk->node, &clocks);
up(&clocks_sem);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
down(&clocks_sem);
list_del(&clk->node);
up(&clocks_sem);
}
EXPORT_SYMBOL(clk_unregister);
static int __init clk_init(void)
{
clk_register(&clk_gpio27);
return 0;
}
arch_initcall(clk_init);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment