diff options
Diffstat (limited to 'drivers/rtc/rtc-s3c.c')
| -rw-r--r-- | drivers/rtc/rtc-s3c.c | 75 |
1 files changed, 34 insertions, 41 deletions
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index fb994e9ddc1..4958a363b2c 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -29,9 +29,8 @@ #include <linux/uaccess.h> #include <linux/io.h> -#include <mach/hardware.h> #include <asm/irq.h> -#include <plat/regs-rtc.h> +#include "rtc-s3c.h" enum s3c_cpu_type { TYPE_S3C2410, @@ -49,9 +48,8 @@ struct s3c_rtc_drv_data { static struct clk *rtc_clk; static void __iomem *s3c_rtc_base; -static int s3c_rtc_alarmno = NO_IRQ; -static int s3c_rtc_tickno = NO_IRQ; -static bool wake_en; +static int s3c_rtc_alarmno; +static int s3c_rtc_tickno; static enum s3c_cpu_type s3c_rtc_cpu_type; static DEFINE_SPINLOCK(s3c_rtc_pie_lock); @@ -423,13 +421,9 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) static int s3c_rtc_remove(struct platform_device *dev) { - struct rtc_device *rtc = platform_get_drvdata(dev); - - platform_set_drvdata(dev, NULL); - rtc_device_unregister(rtc); - s3c_rtc_setaie(&dev->dev, 0); + clk_unprepare(rtc_clk); rtc_clk = NULL; return 0; @@ -481,11 +475,6 @@ static int s3c_rtc_probe(struct platform_device *pdev) /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "failed to get memory region resource\n"); - return -ENOENT; - } - s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(s3c_rtc_base)) return PTR_ERR(s3c_rtc_base); @@ -498,7 +487,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) return ret; } - clk_enable(rtc_clk); + clk_prepare_enable(rtc_clk); /* check to see if everything is setup correctly */ @@ -511,7 +500,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) /* register RTC and exit */ - rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops, + rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, THIS_MODULE); if (IS_ERR(rtc)) { @@ -558,72 +547,78 @@ static int s3c_rtc_probe(struct platform_device *pdev) 0, "s3c2410-rtc alarm", rtc); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); - goto err_alarm_irq; + goto err_nortc; } ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq, 0, "s3c2410-rtc tick", rtc); if (ret) { dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); - goto err_alarm_irq; + goto err_nortc; } clk_disable(rtc_clk); return 0; - err_alarm_irq: - platform_set_drvdata(pdev, NULL); - rtc_device_unregister(rtc); - err_nortc: s3c_rtc_enable(pdev, 0); - clk_disable(rtc_clk); + clk_disable_unprepare(rtc_clk); return ret; } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP /* RTC Power management control */ static int ticnt_save, ticnt_en_save; +static bool wake_en; -static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) +static int s3c_rtc_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); + clk_enable(rtc_clk); /* save TICNT for anyone using periodic interrupts */ - ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); if (s3c_rtc_cpu_type == TYPE_S3C64XX) { ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON); ticnt_en_save &= S3C64XX_RTCCON_TICEN; + ticnt_save = readl(s3c_rtc_base + S3C2410_TICNT); + } else { + ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); } s3c_rtc_enable(pdev, 0); - if (device_may_wakeup(&pdev->dev) && !wake_en) { + if (device_may_wakeup(dev) && !wake_en) { if (enable_irq_wake(s3c_rtc_alarmno) == 0) wake_en = true; else - dev_err(&pdev->dev, "enable_irq_wake failed\n"); + dev_err(dev, "enable_irq_wake failed\n"); } clk_disable(rtc_clk); return 0; } -static int s3c_rtc_resume(struct platform_device *pdev) +static int s3c_rtc_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); unsigned int tmp; clk_enable(rtc_clk); s3c_rtc_enable(pdev, 1); - writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); - if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { - tmp = readw(s3c_rtc_base + S3C2410_RTCCON); - writew(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + writel(ticnt_save, s3c_rtc_base + S3C2410_TICNT); + if (ticnt_en_save) { + tmp = readw(s3c_rtc_base + S3C2410_RTCCON); + writew(tmp | ticnt_en_save, + s3c_rtc_base + S3C2410_RTCCON); + } + } else { + writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); } - if (device_may_wakeup(&pdev->dev) && wake_en) { + if (device_may_wakeup(dev) && wake_en) { disable_irq_wake(s3c_rtc_alarmno); wake_en = false; } @@ -631,11 +626,10 @@ static int s3c_rtc_resume(struct platform_device *pdev) return 0; } -#else -#define s3c_rtc_suspend NULL -#define s3c_rtc_resume NULL #endif +static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); + #ifdef CONFIG_OF static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = { [TYPE_S3C2410] = { TYPE_S3C2410 }, @@ -685,12 +679,11 @@ MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); static struct platform_driver s3c_rtc_driver = { .probe = s3c_rtc_probe, .remove = s3c_rtc_remove, - .suspend = s3c_rtc_suspend, - .resume = s3c_rtc_resume, .id_table = s3c_rtc_driver_ids, .driver = { .name = "s3c-rtc", .owner = THIS_MODULE, + .pm = &s3c_rtc_pm_ops, .of_match_table = of_match_ptr(s3c_rtc_dt_match), }, }; |
