aboutsummaryrefslogtreecommitdiff
path: root/drivers/rtc/rtc-mrst.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-mrst.c')
-rw-r--r--drivers/rtc/rtc-mrst.c61
1 files changed, 25 insertions, 36 deletions
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
index b2f096871a9..e2436d14017 100644
--- a/drivers/rtc/rtc-mrst.c
+++ b/drivers/rtc/rtc-mrst.c
@@ -38,8 +38,8 @@
#include <asm-generic/rtc.h>
#include <asm/intel_scu_ipc.h>
-#include <asm/mrst.h>
-#include <asm/mrst-vrtc.h>
+#include <asm/intel-mid.h>
+#include <asm/intel_mid_vrtc.h>
struct mrst_rtc {
struct rtc_device *rtc;
@@ -76,12 +76,15 @@ static inline unsigned char vrtc_is_updating(void)
/*
* rtc_time's year contains the increment over 1900, but vRTC's YEAR
* register can't be programmed to value larger than 0x64, so vRTC
- * driver chose to use 1960 (1970 is UNIX time start point) as the base,
+ * driver chose to use 1972 (1970 is UNIX time start point) as the base,
* and does the translation at read/write time.
*
- * Why not just use 1970 as the offset? it's because using 1960 will
+ * Why not just use 1970 as the offset? it's because using 1972 will
* make it consistent in leap year setting for both vrtc and low-level
- * physical rtc devices.
+ * physical rtc devices. Then why not use 1960 as the offset? If we use
+ * 1960, for a device's first use, its YEAR register is 0 and the system
+ * year will be parsed as 1960 which is not a valid UNIX time and will
+ * cause many applications to fail mysteriously.
*/
static int mrst_read_time(struct device *dev, struct rtc_time *time)
{
@@ -99,10 +102,10 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
time->tm_year = vrtc_cmos_read(RTC_YEAR);
spin_unlock_irqrestore(&rtc_lock, flags);
- /* Adjust for the 1960/1900 */
- time->tm_year += 60;
+ /* Adjust for the 1972/1900 */
+ time->tm_year += 72;
time->tm_mon--;
- return RTC_24H;
+ return rtc_valid_tm(time);
}
static int mrst_set_time(struct device *dev, struct rtc_time *time)
@@ -119,9 +122,9 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time)
min = time->tm_min;
sec = time->tm_sec;
- if (yrs < 70 || yrs > 138)
+ if (yrs < 72 || yrs > 138)
return -EINVAL;
- yrs -= 60;
+ yrs -= 72;
spin_lock_irqsave(&rtc_lock, flags);
@@ -319,8 +322,8 @@ static irqreturn_t mrst_rtc_irq(int irq, void *p)
return IRQ_NONE;
}
-static int __devinit
-vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
+static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem,
+ int rtc_irq)
{
int retval = 0;
unsigned char rtc_control;
@@ -332,9 +335,8 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
if (!iomem)
return -ENODEV;
- iomem = request_mem_region(iomem->start,
- iomem->end + 1 - iomem->start,
- driver_name);
+ iomem = request_mem_region(iomem->start, resource_size(iomem),
+ driver_name);
if (!iomem) {
dev_dbg(dev, "i/o mem already in use.\n");
return -EBUSY;
@@ -364,7 +366,7 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
if (rtc_irq) {
retval = request_irq(rtc_irq, mrst_rtc_irq,
- IRQF_DISABLED, dev_name(&mrst_rtc.rtc->dev),
+ 0, dev_name(&mrst_rtc.rtc->dev),
mrst_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use, err %d\n",
@@ -378,9 +380,8 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
cleanup1:
rtc_device_unregister(mrst_rtc.rtc);
cleanup0:
- dev_set_drvdata(dev, NULL);
mrst_rtc.dev = NULL;
- release_region(iomem->start, iomem->end + 1 - iomem->start);
+ release_mem_region(iomem->start, resource_size(iomem));
dev_err(dev, "rtc-mrst: unable to initialise\n");
return retval;
}
@@ -392,7 +393,7 @@ static void rtc_mrst_do_shutdown(void)
spin_unlock_irq(&rtc_lock);
}
-static void __devexit rtc_mrst_do_remove(struct device *dev)
+static void rtc_mrst_do_remove(struct device *dev)
{
struct mrst_rtc *mrst = dev_get_drvdata(dev);
struct resource *iomem;
@@ -406,11 +407,10 @@ static void __devexit rtc_mrst_do_remove(struct device *dev)
mrst->rtc = NULL;
iomem = mrst->iomem;
- release_region(iomem->start, iomem->end + 1 - iomem->start);
+ release_mem_region(iomem->start, resource_size(iomem));
mrst->iomem = NULL;
mrst->dev = NULL;
- dev_set_drvdata(dev, NULL);
}
#ifdef CONFIG_PM
@@ -501,14 +501,14 @@ static inline int mrst_poweroff(struct device *dev)
#endif
-static int __devinit vrtc_mrst_platform_probe(struct platform_device *pdev)
+static int vrtc_mrst_platform_probe(struct platform_device *pdev)
{
return vrtc_mrst_do_probe(&pdev->dev,
platform_get_resource(pdev, IORESOURCE_MEM, 0),
platform_get_irq(pdev, 0));
}
-static int __devexit vrtc_mrst_platform_remove(struct platform_device *pdev)
+static int vrtc_mrst_platform_remove(struct platform_device *pdev)
{
rtc_mrst_do_remove(&pdev->dev);
return 0;
@@ -526,7 +526,7 @@ MODULE_ALIAS("platform:vrtc_mrst");
static struct platform_driver vrtc_mrst_platform_driver = {
.probe = vrtc_mrst_platform_probe,
- .remove = __devexit_p(vrtc_mrst_platform_remove),
+ .remove = vrtc_mrst_platform_remove,
.shutdown = vrtc_mrst_platform_shutdown,
.driver = {
.name = (char *) driver_name,
@@ -535,18 +535,7 @@ static struct platform_driver vrtc_mrst_platform_driver = {
}
};
-static int __init vrtc_mrst_init(void)
-{
- return platform_driver_register(&vrtc_mrst_platform_driver);
-}
-
-static void __exit vrtc_mrst_exit(void)
-{
- platform_driver_unregister(&vrtc_mrst_platform_driver);
-}
-
-module_init(vrtc_mrst_init);
-module_exit(vrtc_mrst_exit);
+module_platform_driver(vrtc_mrst_platform_driver);
MODULE_AUTHOR("Jacob Pan; Feng Tang");
MODULE_DESCRIPTION("Driver for Moorestown virtual RTC");