aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-cmos.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-03-18 05:38:53 -0400
committerIngo Molnar <mingo@elte.hu>2011-03-18 05:39:00 -0400
commit8dd8997d2c56c9f248294805e129e1fc69444380 (patch)
tree3b030a04295fc031db98746c4074c2df1ed6a19f /drivers/rtc/rtc-cmos.c
parent1eda75c131ea42ec173323b6c34aeed78ae637c1 (diff)
parent016aa2ed1cc9cf704cf76d8df07751b6daa9750f (diff)
Merge branch 'linus' into x86/urgent
Merge reason: Merge upstream commits to avoid conflicts in upcoming patches. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
-rw-r--r--drivers/rtc/rtc-cmos.c111
1 files changed, 45 insertions, 66 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index c7ff8df347e7..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>
@@ -375,50 +377,6 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
375 return 0; 377 return 0;
376} 378}
377 379
378static int cmos_irq_set_freq(struct device *dev, int freq)
379{
380 struct cmos_rtc *cmos = dev_get_drvdata(dev);
381 int f;
382 unsigned long flags;
383
384 if (!is_valid_irq(cmos->irq))
385 return -ENXIO;
386
387 if (!is_power_of_2(freq))
388 return -EINVAL;
389 /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */
390 f = ffs(freq);
391 if (f-- > 16)
392 return -EINVAL;
393 f = 16 - f;
394
395 spin_lock_irqsave(&rtc_lock, flags);
396 hpet_set_periodic_freq(freq);
397 CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT);
398 spin_unlock_irqrestore(&rtc_lock, flags);
399
400 return 0;
401}
402
403static int cmos_irq_set_state(struct device *dev, int enabled)
404{
405 struct cmos_rtc *cmos = dev_get_drvdata(dev);
406 unsigned long flags;
407
408 if (!is_valid_irq(cmos->irq))
409 return -ENXIO;
410
411 spin_lock_irqsave(&rtc_lock, flags);
412
413 if (enabled)
414 cmos_irq_enable(cmos, RTC_PIE);
415 else
416 cmos_irq_disable(cmos, RTC_PIE);
417
418 spin_unlock_irqrestore(&rtc_lock, flags);
419 return 0;
420}
421
422static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) 380static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
423{ 381{
424 struct cmos_rtc *cmos = dev_get_drvdata(dev); 382 struct cmos_rtc *cmos = dev_get_drvdata(dev);
@@ -438,25 +396,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
438 return 0; 396 return 0;
439} 397}
440 398
441static int cmos_update_irq_enable(struct device *dev, unsigned int enabled)
442{
443 struct cmos_rtc *cmos = dev_get_drvdata(dev);
444 unsigned long flags;
445
446 if (!is_valid_irq(cmos->irq))
447 return -EINVAL;
448
449 spin_lock_irqsave(&rtc_lock, flags);
450
451 if (enabled)
452 cmos_irq_enable(cmos, RTC_UIE);
453 else
454 cmos_irq_disable(cmos, RTC_UIE);
455
456 spin_unlock_irqrestore(&rtc_lock, flags);
457 return 0;
458}
459
460#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) 399#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
461 400
462static int cmos_procfs(struct device *dev, struct seq_file *seq) 401static int cmos_procfs(struct device *dev, struct seq_file *seq)
@@ -501,10 +440,7 @@ static const struct rtc_class_ops cmos_rtc_ops = {
501 .read_alarm = cmos_read_alarm, 440 .read_alarm = cmos_read_alarm,
502 .set_alarm = cmos_set_alarm, 441 .set_alarm = cmos_set_alarm,
503 .proc = cmos_procfs, 442 .proc = cmos_procfs,
504 .irq_set_freq = cmos_irq_set_freq,
505 .irq_set_state = cmos_irq_set_state,
506 .alarm_irq_enable = cmos_alarm_irq_enable, 443 .alarm_irq_enable = cmos_alarm_irq_enable,
507 .update_irq_enable = cmos_update_irq_enable,
508}; 444};
509 445
510/*----------------------------------------------------------------*/ 446/*----------------------------------------------------------------*/
@@ -1123,6 +1059,47 @@ static struct pnp_driver cmos_pnp_driver = {
1123 1059
1124#endif /* CONFIG_PNP */ 1060#endif /* CONFIG_PNP */
1125 1061
1062#ifdef CONFIG_OF
1063static const struct of_device_id of_cmos_match[] = {
1064 {
1065 .compatible = "motorola,mc146818",
1066 },
1067 { },
1068};
1069MODULE_DEVICE_TABLE(of, of_cmos_match);
1070
1071static __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
1100static inline void cmos_of_init(struct platform_device *pdev) {}
1101#define of_cmos_match NULL
1102#endif
1126/*----------------------------------------------------------------*/ 1103/*----------------------------------------------------------------*/
1127 1104
1128/* 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
@@ -1131,6 +1108,7 @@ static struct pnp_driver cmos_pnp_driver = {
1131 1108
1132static int __init cmos_platform_probe(struct platform_device *pdev) 1109static int __init cmos_platform_probe(struct platform_device *pdev)
1133{ 1110{
1111 cmos_of_init(pdev);
1134 cmos_wake_setup(&pdev->dev); 1112 cmos_wake_setup(&pdev->dev);
1135 return cmos_do_probe(&pdev->dev, 1113 return cmos_do_probe(&pdev->dev,
1136 platform_get_resource(pdev, IORESOURCE_IO, 0), 1114 platform_get_resource(pdev, IORESOURCE_IO, 0),
@@ -1162,6 +1140,7 @@ static struct platform_driver cmos_platform_driver = {
1162#ifdef CONFIG_PM 1140#ifdef CONFIG_PM
1163 .pm = &cmos_pm_ops, 1141 .pm = &cmos_pm_ops,
1164#endif 1142#endif
1143 .of_match_table = of_cmos_match,
1165 } 1144 }
1166}; 1145};
1167 1146