aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2011-02-22 15:07:46 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-02-23 16:27:55 -0500
commit3bcbaf6e08d8d82cde781997bd2c56dda87049b5 (patch)
tree20e53770f1aabf3023867ba1d2fe6ec3ecc54b3c
parent1fa4163bdc199a0b80f9e333d718b3f65e901593 (diff)
rtc: cmos: Add OF bindings
This allows to load the OF driver based informations from the device tree. Systems without BIOS may need to perform some initialization. PowerPC creates a PNP device from the OF information and performs this kind of initialization in their private PCI quirk. This looks more generic. This patch also avoids registering the platform RTC driver on X86 if we have a device tree blob. Otherwise we would setup the device based on the hardcoded information in arch/x86 rather than the device tree based one. [ tglx: Changed "int of_have_populated_dt()" to bool as recommended by Grant ] Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Cc: sodaville@linutronix.de Cc: devicetree-discuss@lists.ozlabs.org Cc: rtc-linux@googlegroups.com Cc: Alessandro Zummo <a.zummo@towertech.it> LKML-Reference: <1298405266-1624-12-git-send-email-bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-cmos.txt28
-rw-r--r--arch/x86/kernel/rtc.c3
-rw-r--r--drivers/rtc/rtc-cmos.c45
-rw-r--r--include/linux/of.h12
4 files changed, 88 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/rtc/rtc-cmos.txt b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt
new file mode 100644
index 000000000000..7382989b3052
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt
@@ -0,0 +1,28 @@
1 Motorola mc146818 compatible RTC
2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
4Required properties:
5 - compatible : "motorola,mc146818"
6 - reg : should contain registers location and length.
7
8Optional properties:
9 - interrupts : should contain interrupt.
10 - interrupt-parent : interrupt source phandle.
11 - ctrl-reg : Contains the initial value of the control register also
12 called "Register B".
13 - freq-reg : Contains the initial value of the frequency register also
14 called "Regsiter A".
15
16"Register A" and "B" are usually initialized by the firmware (BIOS for
17instance). If this is not done, it can be performed by the driver.
18
19ISA Example:
20
21 rtc@70 {
22 compatible = "motorola,mc146818";
23 interrupts = <8 3>;
24 interrupt-parent = <&ioapic1>;
25 ctrl-reg = <2>;
26 freq-reg = <0x26>;
27 reg = <1 0x70 2>;
28 };
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 6f39cab052d5..3f2ad2640d85 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -6,6 +6,7 @@
6#include <linux/acpi.h> 6#include <linux/acpi.h>
7#include <linux/bcd.h> 7#include <linux/bcd.h>
8#include <linux/pnp.h> 8#include <linux/pnp.h>
9#include <linux/of.h>
9 10
10#include <asm/vsyscall.h> 11#include <asm/vsyscall.h>
11#include <asm/x86_init.h> 12#include <asm/x86_init.h>
@@ -236,6 +237,8 @@ static __init int add_rtc_cmos(void)
236 } 237 }
237 } 238 }
238#endif 239#endif
240 if (of_have_populated_dt())
241 return 0;
239 242
240 platform_device_register(&rtc_device); 243 platform_device_register(&rtc_device);
241 dev_info(&rtc_device.dev, 244 dev_info(&rtc_device.dev,
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index c7ff8df347e7..159b95e4b420 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -37,6 +37,8 @@
37#include <linux/mod_devicetable.h> 37#include <linux/mod_devicetable.h>
38#include <linux/log2.h> 38#include <linux/log2.h>
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/of.h>
41#include <linux/of_platform.h>
40 42
41/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ 43/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
42#include <asm-generic/rtc.h> 44#include <asm-generic/rtc.h>
@@ -1123,6 +1125,47 @@ static struct pnp_driver cmos_pnp_driver = {
1123 1125
1124#endif /* CONFIG_PNP */ 1126#endif /* CONFIG_PNP */
1125 1127
1128#ifdef CONFIG_OF
1129static const struct of_device_id of_cmos_match[] = {
1130 {
1131 .compatible = "motorola,mc146818",
1132 },
1133 { },
1134};
1135MODULE_DEVICE_TABLE(of, of_cmos_match);
1136
1137static __init void cmos_of_init(struct platform_device *pdev)
1138{
1139 struct device_node *node = pdev->dev.of_node;
1140 struct rtc_time time;
1141 int ret;
1142 const __be32 *val;
1143
1144 if (!node)
1145 return;
1146
1147 val = of_get_property(node, "ctrl-reg", NULL);
1148 if (val)
1149 CMOS_WRITE(be32_to_cpup(val), RTC_CONTROL);
1150
1151 val = of_get_property(node, "freq-reg", NULL);
1152 if (val)
1153 CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT);
1154
1155 get_rtc_time(&time);
1156 ret = rtc_valid_tm(&time);
1157 if (ret) {
1158 struct rtc_time def_time = {
1159 .tm_year = 1,
1160 .tm_mday = 1,
1161 };
1162 set_rtc_time(&def_time);
1163 }
1164}
1165#else
1166static inline void cmos_of_init(struct platform_device *pdev) {}
1167#define of_cmos_match NULL
1168#endif
1126/*----------------------------------------------------------------*/ 1169/*----------------------------------------------------------------*/
1127 1170
1128/* Platform setup should have set up an RTC device, when PNP is 1171/* Platform setup should have set up an RTC device, when PNP is
@@ -1131,6 +1174,7 @@ static struct pnp_driver cmos_pnp_driver = {
1131 1174
1132static int __init cmos_platform_probe(struct platform_device *pdev) 1175static int __init cmos_platform_probe(struct platform_device *pdev)
1133{ 1176{
1177 cmos_of_init(pdev);
1134 cmos_wake_setup(&pdev->dev); 1178 cmos_wake_setup(&pdev->dev);
1135 return cmos_do_probe(&pdev->dev, 1179 return cmos_do_probe(&pdev->dev,
1136 platform_get_resource(pdev, IORESOURCE_IO, 0), 1180 platform_get_resource(pdev, IORESOURCE_IO, 0),
@@ -1162,6 +1206,7 @@ static struct platform_driver cmos_platform_driver = {
1162#ifdef CONFIG_PM 1206#ifdef CONFIG_PM
1163 .pm = &cmos_pm_ops, 1207 .pm = &cmos_pm_ops,
1164#endif 1208#endif
1209 .of_match_table = of_cmos_match,
1165 } 1210 }
1166}; 1211};
1167 1212
diff --git a/include/linux/of.h b/include/linux/of.h
index d9dd664a6a9c..266db1d0baa9 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -70,6 +70,11 @@ extern struct device_node *allnodes;
70extern struct device_node *of_chosen; 70extern struct device_node *of_chosen;
71extern rwlock_t devtree_lock; 71extern rwlock_t devtree_lock;
72 72
73static inline bool of_have_populated_dt(void)
74{
75 return allnodes != NULL;
76}
77
73static inline bool of_node_is_root(const struct device_node *node) 78static inline bool of_node_is_root(const struct device_node *node)
74{ 79{
75 return node && (node->parent == NULL); 80 return node && (node->parent == NULL);
@@ -222,5 +227,12 @@ extern void of_attach_node(struct device_node *);
222extern void of_detach_node(struct device_node *); 227extern void of_detach_node(struct device_node *);
223#endif 228#endif
224 229
230#else
231
232static inline bool of_have_populated_dt(void)
233{
234 return false;
235}
236
225#endif /* CONFIG_OF */ 237#endif /* CONFIG_OF */
226#endif /* _LINUX_OF_H */ 238#endif /* _LINUX_OF_H */