diff options
author | Zhiwu Song <zhiwu.song@csr.com> | 2011-08-30 22:20:34 -0400 |
---|---|---|
committer | Barry Song <21cnbao@gmail.com> | 2011-09-10 21:17:53 -0400 |
commit | 684f741446f7a3108b4c167faf20214c42b7eeac (patch) | |
tree | 7d6b2d4919640170f61aaaf5460e9b2a6dbb24cd /arch/arm | |
parent | 858ba703e842f4ece6680b45862ee9e6e6297d1e (diff) |
ARM: CSR: add rtc i/o bridge interface for SiRFprimaII
The module is a bridge between the RTC clock domain and the CPU interface
clock domain. ARM access the register of SYSRTC, GPSRTC and PWRC through
this module.
Signed-off-by: Zhiwu Song <zhiwu.song@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Reviewed-by: Jamie Iles <jamie@jamieiles.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/boot/dts/prima2-cb.dts | 2 | ||||
-rw-r--r-- | arch/arm/mach-prima2/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-prima2/rtciobrg.c | 139 |
3 files changed, 141 insertions, 1 deletions
diff --git a/arch/arm/boot/dts/prima2-cb.dts b/arch/arm/boot/dts/prima2-cb.dts index af86931bdcc6..17b6737c4ee5 100644 --- a/arch/arm/boot/dts/prima2-cb.dts +++ b/arch/arm/boot/dts/prima2-cb.dts | |||
@@ -363,7 +363,7 @@ | |||
363 | }; | 363 | }; |
364 | 364 | ||
365 | rtc-iobg { | 365 | rtc-iobg { |
366 | compatible = "sirf,prima2-rtciobg", "simple-bus"; | 366 | compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus"; |
367 | #address-cells = <1>; | 367 | #address-cells = <1>; |
368 | #size-cells = <1>; | 368 | #size-cells = <1>; |
369 | reg = <0x80030000 0x10000>; | 369 | reg = <0x80030000 0x10000>; |
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile index 7af7fc05d565..f49d70b86854 100644 --- a/arch/arm/mach-prima2/Makefile +++ b/arch/arm/mach-prima2/Makefile | |||
@@ -3,5 +3,6 @@ obj-y += irq.o | |||
3 | obj-y += clock.o | 3 | obj-y += clock.o |
4 | obj-y += rstc.o | 4 | obj-y += rstc.o |
5 | obj-y += prima2.o | 5 | obj-y += prima2.o |
6 | obj-y += rtciobrg.o | ||
6 | obj-$(CONFIG_DEBUG_LL) += lluart.o | 7 | obj-$(CONFIG_DEBUG_LL) += lluart.o |
7 | obj-$(CONFIG_CACHE_L2X0) += l2x0.o | 8 | obj-$(CONFIG_CACHE_L2X0) += l2x0.o |
diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c new file mode 100644 index 000000000000..9d80f1e20a98 --- /dev/null +++ b/arch/arm/mach-prima2/rtciobrg.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * RTC I/O Bridge interfaces for CSR SiRFprimaII | ||
3 | * ARM access the registers of SYSRTC, GPSRTC and PWRC through this module | ||
4 | * | ||
5 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
6 | * | ||
7 | * Licensed under GPLv2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/of.h> | ||
14 | #include <linux/of_address.h> | ||
15 | #include <linux/of_device.h> | ||
16 | #include <linux/of_platform.h> | ||
17 | |||
18 | #define SIRFSOC_CPUIOBRG_CTRL 0x00 | ||
19 | #define SIRFSOC_CPUIOBRG_WRBE 0x04 | ||
20 | #define SIRFSOC_CPUIOBRG_ADDR 0x08 | ||
21 | #define SIRFSOC_CPUIOBRG_DATA 0x0c | ||
22 | |||
23 | /* | ||
24 | * suspend asm codes will access this address to make system deepsleep | ||
25 | * after DRAM becomes self-refresh | ||
26 | */ | ||
27 | void __iomem *sirfsoc_rtciobrg_base; | ||
28 | static DEFINE_SPINLOCK(rtciobrg_lock); | ||
29 | |||
30 | /* | ||
31 | * symbols without lock are only used by suspend asm codes | ||
32 | * and these symbols are not exported too | ||
33 | */ | ||
34 | void sirfsoc_rtc_iobrg_wait_sync(void) | ||
35 | { | ||
36 | while (readl_relaxed(sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL)) | ||
37 | cpu_relax(); | ||
38 | } | ||
39 | |||
40 | void sirfsoc_rtc_iobrg_besyncing(void) | ||
41 | { | ||
42 | unsigned long flags; | ||
43 | |||
44 | spin_lock_irqsave(&rtciobrg_lock, flags); | ||
45 | |||
46 | sirfsoc_rtc_iobrg_wait_sync(); | ||
47 | |||
48 | spin_unlock_irqrestore(&rtciobrg_lock, flags); | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_besyncing); | ||
51 | |||
52 | u32 __sirfsoc_rtc_iobrg_readl(u32 addr) | ||
53 | { | ||
54 | sirfsoc_rtc_iobrg_wait_sync(); | ||
55 | |||
56 | writel_relaxed(0x00, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_WRBE); | ||
57 | writel_relaxed(addr, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_ADDR); | ||
58 | writel_relaxed(0x01, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL); | ||
59 | |||
60 | sirfsoc_rtc_iobrg_wait_sync(); | ||
61 | |||
62 | return readl_relaxed(sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_DATA); | ||
63 | } | ||
64 | |||
65 | u32 sirfsoc_rtc_iobrg_readl(u32 addr) | ||
66 | { | ||
67 | unsigned long flags, val; | ||
68 | |||
69 | spin_lock_irqsave(&rtciobrg_lock, flags); | ||
70 | |||
71 | val = __sirfsoc_rtc_iobrg_readl(addr); | ||
72 | |||
73 | spin_unlock_irqrestore(&rtciobrg_lock, flags); | ||
74 | |||
75 | return val; | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_readl); | ||
78 | |||
79 | void sirfsoc_rtc_iobrg_pre_writel(u32 val, u32 addr) | ||
80 | { | ||
81 | sirfsoc_rtc_iobrg_wait_sync(); | ||
82 | |||
83 | writel_relaxed(0xf1, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_WRBE); | ||
84 | writel_relaxed(addr, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_ADDR); | ||
85 | |||
86 | writel_relaxed(val, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_DATA); | ||
87 | } | ||
88 | |||
89 | void sirfsoc_rtc_iobrg_writel(u32 val, u32 addr) | ||
90 | { | ||
91 | unsigned long flags; | ||
92 | |||
93 | spin_lock_irqsave(&rtciobrg_lock, flags); | ||
94 | |||
95 | sirfsoc_rtc_iobrg_pre_writel(val, addr); | ||
96 | |||
97 | writel_relaxed(0x01, sirfsoc_rtciobrg_base + SIRFSOC_CPUIOBRG_CTRL); | ||
98 | |||
99 | sirfsoc_rtc_iobrg_wait_sync(); | ||
100 | |||
101 | spin_unlock_irqrestore(&rtciobrg_lock, flags); | ||
102 | } | ||
103 | EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_writel); | ||
104 | |||
105 | static const struct of_device_id rtciobrg_ids[] = { | ||
106 | { .compatible = "sirf,prima2-rtciobg" }, | ||
107 | {} | ||
108 | }; | ||
109 | |||
110 | static int __devinit sirfsoc_rtciobrg_probe(struct platform_device *op) | ||
111 | { | ||
112 | struct device_node *np = op->dev.of_node; | ||
113 | |||
114 | sirfsoc_rtciobrg_base = of_iomap(np, 0); | ||
115 | if (!sirfsoc_rtciobrg_base) | ||
116 | panic("unable to map rtc iobrg registers\n"); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static struct platform_driver sirfsoc_rtciobrg_driver = { | ||
122 | .probe = sirfsoc_rtciobrg_probe, | ||
123 | .driver = { | ||
124 | .name = "sirfsoc-rtciobrg", | ||
125 | .owner = THIS_MODULE, | ||
126 | .of_match_table = rtciobrg_ids, | ||
127 | }, | ||
128 | }; | ||
129 | |||
130 | static int __init sirfsoc_rtciobrg_init(void) | ||
131 | { | ||
132 | return platform_driver_register(&sirfsoc_rtciobrg_driver); | ||
133 | } | ||
134 | postcore_initcall(sirfsoc_rtciobrg_init); | ||
135 | |||
136 | MODULE_AUTHOR("Zhiwu Song <zhiwu.song@csr.com>, " | ||
137 | "Barry Song <baohua.song@csr.com>"); | ||
138 | MODULE_DESCRIPTION("CSR SiRFprimaII rtc io bridge"); | ||
139 | MODULE_LICENSE("GPL"); | ||