aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-w90x900/Makefile2
-rw-r--r--arch/arm/mach-w90x900/clock.c77
-rw-r--r--arch/arm/mach-w90x900/clock.h36
-rw-r--r--arch/arm/mach-w90x900/cpu.h2
-rw-r--r--arch/arm/mach-w90x900/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-w90x900/mach-w90p910evb.c2
-rw-r--r--arch/arm/mach-w90x900/w90p910.c41
8 files changed, 164 insertions, 4 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 013993c6ceea..7d544944ec13 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -490,6 +490,7 @@ config ARCH_W90X900
490 select CPU_ARM926T 490 select CPU_ARM926T
491 select ARCH_REQUIRE_GPIOLIB 491 select ARCH_REQUIRE_GPIOLIB
492 select GENERIC_GPIO 492 select GENERIC_GPIO
493 select COMMON_CLKDEV
493 help 494 help
494 Support for Nuvoton (Winbond logic dept.) ARM9 processor,You 495 Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
495 can login www.mcuos.com or www.nuvoton.com to know more. 496 can login www.mcuos.com or www.nuvoton.com to know more.
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile
index 6287268cde4c..d50c94f4dbdf 100644
--- a/arch/arm/mach-w90x900/Makefile
+++ b/arch/arm/mach-w90x900/Makefile
@@ -4,7 +4,7 @@
4 4
5# Object file lists. 5# Object file lists.
6 6
7obj-y := irq.o time.o mfp-w90p910.o gpio.o 7obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o
8 8
9# W90X900 CPU support files 9# W90X900 CPU support files
10 10
diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c
new file mode 100644
index 000000000000..f420613cd395
--- /dev/null
+++ b/arch/arm/mach-w90x900/clock.c
@@ -0,0 +1,77 @@
1/*
2 * linux/arch/arm/mach-w90x900/clock.c
3 *
4 * Copyright (c) 2008 Nuvoton technology corporation
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/list.h>
16#include <linux/errno.h>
17#include <linux/err.h>
18#include <linux/string.h>
19#include <linux/clk.h>
20#include <linux/spinlock.h>
21#include <linux/platform_device.h>
22#include <linux/io.h>
23
24#include <mach/hardware.h>
25
26#include "clock.h"
27
28static DEFINE_SPINLOCK(clocks_lock);
29
30int clk_enable(struct clk *clk)
31{
32 unsigned long flags;
33
34 spin_lock_irqsave(&clocks_lock, flags);
35 if (clk->enabled++ == 0)
36 (clk->enable)(clk, 1);
37 spin_unlock_irqrestore(&clocks_lock, flags);
38
39 return 0;
40}
41EXPORT_SYMBOL(clk_enable);
42
43void clk_disable(struct clk *clk)
44{
45 unsigned long flags;
46
47 WARN_ON(clk->enabled == 0);
48
49 spin_lock_irqsave(&clocks_lock, flags);
50 if (--clk->enabled == 0)
51 (clk->enable)(clk, 0);
52 spin_unlock_irqrestore(&clocks_lock, flags);
53}
54EXPORT_SYMBOL(clk_disable);
55
56void w90x900_clk_enable(struct clk *clk, int enable)
57{
58 unsigned int clocks = clk->cken;
59 unsigned long clken;
60
61 clken = __raw_readl(W90X900_VA_CLKPWR);
62
63 if (enable)
64 clken |= clocks;
65 else
66 clken &= ~clocks;
67
68 __raw_writel(clken, W90X900_VA_CLKPWR);
69}
70
71void clks_register(struct clk_lookup *clks, size_t num)
72{
73 int i;
74
75 for (i = 0; i < num; i++)
76 clkdev_add(&clks[i]);
77}
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h
new file mode 100644
index 000000000000..4f27bda76d56
--- /dev/null
+++ b/arch/arm/mach-w90x900/clock.h
@@ -0,0 +1,36 @@
1/*
2 * linux/arch/arm/mach-w90x900/clock.h
3 *
4 * Copyright (c) 2008 Nuvoton technology corporation
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License.
11 */
12
13#include <asm/clkdev.h>
14
15void w90x900_clk_enable(struct clk *clk, int enable);
16void clks_register(struct clk_lookup *clks, size_t num);
17
18struct clk {
19 unsigned long cken;
20 unsigned int enabled;
21 void (*enable)(struct clk *, int enable);
22};
23
24#define DEFINE_CLK(_name, _ctrlbit) \
25struct clk clk_##_name = { \
26 .enable = w90x900_clk_enable, \
27 .cken = (1 << _ctrlbit), \
28 }
29
30#define DEF_CLKLOOK(_clk, _devname, _conname) \
31 { \
32 .clk = _clk, \
33 .dev_id = _devname, \
34 .con_id = _conname, \
35 }
36
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
index de29ddcb9459..57b5dbabeb41 100644
--- a/arch/arm/mach-w90x900/cpu.h
+++ b/arch/arm/mach-w90x900/cpu.h
@@ -41,7 +41,7 @@ struct sys_timer;
41extern void w90x900_init_irq(void); 41extern void w90x900_init_irq(void);
42extern void w90p910_init_io(struct map_desc *mach_desc, int size); 42extern void w90p910_init_io(struct map_desc *mach_desc, int size);
43extern void w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no); 43extern void w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no);
44extern void w90p910_init_clocks(int xtal); 44extern void w90p910_init_clocks(void);
45extern void w90p910_map_io(struct map_desc *mach_desc, int size); 45extern void w90p910_map_io(struct map_desc *mach_desc, int size);
46extern struct platform_device w90p910_serial_device; 46extern struct platform_device w90p910_serial_device;
47extern struct sys_timer w90x900_timer; 47extern struct sys_timer w90x900_timer;
diff --git a/arch/arm/mach-w90x900/include/mach/clkdev.h b/arch/arm/mach-w90x900/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/clkdev.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do { } while (0)
6
7#endif
diff --git a/arch/arm/mach-w90x900/mach-w90p910evb.c b/arch/arm/mach-w90x900/mach-w90p910evb.c
index 1968ed428b72..7a62bd348e80 100644
--- a/arch/arm/mach-w90x900/mach-w90p910evb.c
+++ b/arch/arm/mach-w90x900/mach-w90p910evb.c
@@ -247,7 +247,7 @@ static struct platform_device *w90p910evb_dev[] __initdata = {
247static void __init w90p910evb_map_io(void) 247static void __init w90p910evb_map_io(void)
248{ 248{
249 w90p910_map_io(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc)); 249 w90p910_map_io(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc));
250 w90p910_init_clocks(0); 250 w90p910_init_clocks();
251} 251}
252 252
253static void __init w90p910evb_init(void) 253static void __init w90p910evb_init(void)
diff --git a/arch/arm/mach-w90x900/w90p910.c b/arch/arm/mach-w90x900/w90p910.c
index 87214b8896e7..1c97e4930b7a 100644
--- a/arch/arm/mach-w90x900/w90p910.c
+++ b/arch/arm/mach-w90x900/w90p910.c
@@ -34,6 +34,7 @@
34#include <mach/regs-serial.h> 34#include <mach/regs-serial.h>
35 35
36#include "cpu.h" 36#include "cpu.h"
37#include "clock.h"
37 38
38/* Initial IO mappings */ 39/* Initial IO mappings */
39 40
@@ -52,6 +53,43 @@ static struct map_desc w90p910_iodesc[] __initdata = {
52 /*IODESC_ENT(LCD),*/ 53 /*IODESC_ENT(LCD),*/
53}; 54};
54 55
56/* Initial clock declarations. */
57static DEFINE_CLK(lcd, 0);
58static DEFINE_CLK(audio, 1);
59static DEFINE_CLK(fmi, 4);
60static DEFINE_CLK(dmac, 5);
61static DEFINE_CLK(atapi, 6);
62static DEFINE_CLK(emc, 7);
63static DEFINE_CLK(usbd, 8);
64static DEFINE_CLK(usbh, 9);
65static DEFINE_CLK(g2d, 10);;
66static DEFINE_CLK(pwm, 18);
67static DEFINE_CLK(ps2, 24);
68static DEFINE_CLK(kpi, 25);
69static DEFINE_CLK(wdt, 26);
70static DEFINE_CLK(gdma, 27);
71static DEFINE_CLK(adc, 28);
72static DEFINE_CLK(usi, 29);
73
74static struct clk_lookup w90p910_clkregs[] = {
75 DEF_CLKLOOK(&clk_lcd, "w90p910-lcd", NULL),
76 DEF_CLKLOOK(&clk_audio, "w90p910-audio", NULL),
77 DEF_CLKLOOK(&clk_fmi, "w90p910-fmi", NULL),
78 DEF_CLKLOOK(&clk_dmac, "w90p910-dmac", NULL),
79 DEF_CLKLOOK(&clk_atapi, "w90p910-atapi", NULL),
80 DEF_CLKLOOK(&clk_emc, "w90p910-emc", NULL),
81 DEF_CLKLOOK(&clk_usbd, "w90p910-usbd", NULL),
82 DEF_CLKLOOK(&clk_usbh, "w90p910-usbh", NULL),
83 DEF_CLKLOOK(&clk_g2d, "w90p910-g2d", NULL),
84 DEF_CLKLOOK(&clk_pwm, "w90p910-pwm", NULL),
85 DEF_CLKLOOK(&clk_ps2, "w90p910-ps2", NULL),
86 DEF_CLKLOOK(&clk_kpi, "w90p910-kpi", NULL),
87 DEF_CLKLOOK(&clk_wdt, "w90p910-wdt", NULL),
88 DEF_CLKLOOK(&clk_gdma, "w90p910-gdma", NULL),
89 DEF_CLKLOOK(&clk_adc, "w90p910-adc", NULL),
90 DEF_CLKLOOK(&clk_usi, "w90p910-usi", NULL),
91};
92
55/* Initial serial platform data */ 93/* Initial serial platform data */
56 94
57struct plat_serial8250_port w90p910_uart_data[] = { 95struct plat_serial8250_port w90p910_uart_data[] = {
@@ -81,8 +119,9 @@ void __init w90p910_map_io(struct map_desc *mach_desc, int mach_size)
81 119
82/*Init W90P910 clock*/ 120/*Init W90P910 clock*/
83 121
84void __init w90p910_init_clocks(int xtal) 122void __init w90p910_init_clocks(void)
85{ 123{
124 clks_register(w90p910_clkregs, ARRAY_SIZE(w90p910_clkregs));
86} 125}
87 126
88static int __init w90p910_init_cpu(void) 127static int __init w90p910_init_cpu(void)