diff options
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
| -rw-r--r-- | drivers/rtc/rtc-cmos.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index dc2a0ba969ce..911e75cdc125 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> |
| @@ -1057,6 +1059,47 @@ static struct pnp_driver cmos_pnp_driver = { | |||
| 1057 | 1059 | ||
| 1058 | #endif /* CONFIG_PNP */ | 1060 | #endif /* CONFIG_PNP */ |
| 1059 | 1061 | ||
| 1062 | #ifdef CONFIG_OF | ||
| 1063 | static const struct of_device_id of_cmos_match[] = { | ||
| 1064 | { | ||
| 1065 | .compatible = "motorola,mc146818", | ||
| 1066 | }, | ||
| 1067 | { }, | ||
| 1068 | }; | ||
| 1069 | MODULE_DEVICE_TABLE(of, of_cmos_match); | ||
| 1070 | |||
| 1071 | static __init void cmos_of_init(struct platform_device *pdev) | ||
| 1072 | { | ||
| 1073 | struct device_node *node = pdev->dev.of_node; | ||
| 1074 | struct rtc_time time; | ||
| 1075 | int ret; | ||
| 1076 | const __be32 *val; | ||
| 1077 | |||
| 1078 | if (!node) | ||
| 1079 | return; | ||
| 1080 | |||
| 1081 | val = of_get_property(node, "ctrl-reg", NULL); | ||
| 1082 | if (val) | ||
| 1083 | CMOS_WRITE(be32_to_cpup(val), RTC_CONTROL); | ||
| 1084 | |||
| 1085 | val = of_get_property(node, "freq-reg", NULL); | ||
| 1086 | if (val) | ||
| 1087 | CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); | ||
| 1088 | |||
| 1089 | get_rtc_time(&time); | ||
| 1090 | ret = rtc_valid_tm(&time); | ||
| 1091 | if (ret) { | ||
| 1092 | struct rtc_time def_time = { | ||
| 1093 | .tm_year = 1, | ||
| 1094 | .tm_mday = 1, | ||
| 1095 | }; | ||
| 1096 | set_rtc_time(&def_time); | ||
| 1097 | } | ||
| 1098 | } | ||
| 1099 | #else | ||
| 1100 | static inline void cmos_of_init(struct platform_device *pdev) {} | ||
| 1101 | #define of_cmos_match NULL | ||
| 1102 | #endif | ||
| 1060 | /*----------------------------------------------------------------*/ | 1103 | /*----------------------------------------------------------------*/ |
| 1061 | 1104 | ||
| 1062 | /* Platform setup should have set up an RTC device, when PNP is | 1105 | /* Platform setup should have set up an RTC device, when PNP is |
| @@ -1065,6 +1108,7 @@ static struct pnp_driver cmos_pnp_driver = { | |||
| 1065 | 1108 | ||
| 1066 | static int __init cmos_platform_probe(struct platform_device *pdev) | 1109 | static int __init cmos_platform_probe(struct platform_device *pdev) |
| 1067 | { | 1110 | { |
| 1111 | cmos_of_init(pdev); | ||
| 1068 | cmos_wake_setup(&pdev->dev); | 1112 | cmos_wake_setup(&pdev->dev); |
| 1069 | return cmos_do_probe(&pdev->dev, | 1113 | return cmos_do_probe(&pdev->dev, |
| 1070 | platform_get_resource(pdev, IORESOURCE_IO, 0), | 1114 | platform_get_resource(pdev, IORESOURCE_IO, 0), |
| @@ -1096,6 +1140,7 @@ static struct platform_driver cmos_platform_driver = { | |||
| 1096 | #ifdef CONFIG_PM | 1140 | #ifdef CONFIG_PM |
| 1097 | .pm = &cmos_pm_ops, | 1141 | .pm = &cmos_pm_ops, |
| 1098 | #endif | 1142 | #endif |
| 1143 | .of_match_table = of_cmos_match, | ||
| 1099 | } | 1144 | } |
| 1100 | }; | 1145 | }; |
| 1101 | 1146 | ||
