aboutsummaryrefslogtreecommitdiff
path: root/drivers/rtc/rtc-wm8350.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-wm8350.c')
-rw-r--r--drivers/rtc/rtc-wm8350.c115
1 files changed, 43 insertions, 72 deletions
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index 5c5e3aa9138..fa247deb9cf 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -122,7 +122,7 @@ static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm)
do {
rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
schedule_timeout_uninterruptible(msecs_to_jiffies(1));
- } while (retries-- && !(rtc_ctrl & WM8350_RTC_STS));
+ } while (--retries && !(rtc_ctrl & WM8350_RTC_STS));
if (!retries) {
dev_err(dev, "timed out on set confirmation\n");
@@ -236,6 +236,17 @@ static int wm8350_rtc_start_alarm(struct wm8350 *wm8350)
return 0;
}
+static int wm8350_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ struct wm8350 *wm8350 = dev_get_drvdata(dev);
+
+ if (enabled)
+ return wm8350_rtc_start_alarm(wm8350);
+ else
+ return wm8350_rtc_stop_alarm(wm8350);
+}
+
static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct wm8350 *wm8350 = dev_get_drvdata(dev);
@@ -291,37 +302,9 @@ static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
}
-/*
- * Handle commands from user-space
- */
-static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd,
- unsigned long arg)
-{
- struct wm8350 *wm8350 = dev_get_drvdata(dev);
-
- switch (cmd) {
- case RTC_AIE_OFF:
- return wm8350_rtc_stop_alarm(wm8350);
- case RTC_AIE_ON:
- return wm8350_rtc_start_alarm(wm8350);
-
- case RTC_UIE_OFF:
- wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
- break;
- case RTC_UIE_ON:
- wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC);
- break;
-
- default:
- return -ENOIOCTLCMD;
- }
-
- return 0;
-}
-
-static void wm8350_rtc_alarm_handler(struct wm8350 *wm8350, int irq,
- void *data)
+static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data)
{
+ struct wm8350 *wm8350 = data;
struct rtc_device *rtc = wm8350->rtc.rtc;
int ret;
@@ -334,27 +317,32 @@ static void wm8350_rtc_alarm_handler(struct wm8350 *wm8350, int irq,
dev_err(&(wm8350->rtc.pdev->dev),
"Failed to disable alarm: %d\n", ret);
}
+
+ return IRQ_HANDLED;
}
-static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq,
- void *data)
+static irqreturn_t wm8350_rtc_update_handler(int irq, void *data)
{
+ struct wm8350 *wm8350 = data;
struct rtc_device *rtc = wm8350->rtc.rtc;
rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF);
+
+ return IRQ_HANDLED;
}
static const struct rtc_class_ops wm8350_rtc_ops = {
- .ioctl = wm8350_rtc_ioctl,
.read_time = wm8350_rtc_readtime,
.set_time = wm8350_rtc_settime,
.read_alarm = wm8350_rtc_readalarm,
.set_alarm = wm8350_rtc_setalarm,
+ .alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
};
-#ifdef CONFIG_PM
-static int wm8350_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int wm8350_rtc_suspend(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
int ret = 0;
u16 reg;
@@ -372,8 +360,9 @@ static int wm8350_rtc_suspend(struct platform_device *pdev, pm_message_t state)
return ret;
}
-static int wm8350_rtc_resume(struct platform_device *pdev)
+static int wm8350_rtc_resume(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
int ret;
@@ -386,10 +375,6 @@ static int wm8350_rtc_resume(struct platform_device *pdev)
return 0;
}
-
-#else
-#define wm8350_rtc_suspend NULL
-#define wm8350_rtc_resume NULL
#endif
static int wm8350_rtc_probe(struct platform_device *pdev)
@@ -440,7 +425,7 @@ static int wm8350_rtc_probe(struct platform_device *pdev)
do {
timectl = wm8350_reg_read(wm8350,
WM8350_RTC_TIME_CONTROL);
- } while (timectl & WM8350_RTC_STS && retries--);
+ } while (timectl & WM8350_RTC_STS && --retries);
if (retries == 0) {
dev_err(&pdev->dev, "failed to start: timeout\n");
@@ -450,63 +435,49 @@ static int wm8350_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
- wm_rtc->rtc = rtc_device_register("wm8350", &pdev->dev,
- &wm8350_rtc_ops, THIS_MODULE);
+ wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350",
+ &wm8350_rtc_ops, THIS_MODULE);
if (IS_ERR(wm_rtc->rtc)) {
ret = PTR_ERR(wm_rtc->rtc);
dev_err(&pdev->dev, "failed to register RTC: %d\n", ret);
return ret;
}
- wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
- wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_PER);
-
wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC,
- wm8350_rtc_update_handler, NULL);
+ wm8350_rtc_update_handler, 0,
+ "RTC Seconds", wm8350);
+ wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM,
- wm8350_rtc_alarm_handler, NULL);
- wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_ALM);
+ wm8350_rtc_alarm_handler, 0,
+ "RTC Alarm", wm8350);
return 0;
}
-static int __devexit wm8350_rtc_remove(struct platform_device *pdev)
+static int wm8350_rtc_remove(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
- struct wm8350_rtc *wm_rtc = &wm8350->rtc;
- wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
-
- wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC);
- wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM);
-
- rtc_device_unregister(wm_rtc->rtc);
+ wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350);
return 0;
}
+static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend,
+ wm8350_rtc_resume);
+
static struct platform_driver wm8350_rtc_driver = {
.probe = wm8350_rtc_probe,
- .remove = __devexit_p(wm8350_rtc_remove),
- .suspend = wm8350_rtc_suspend,
- .resume = wm8350_rtc_resume,
+ .remove = wm8350_rtc_remove,
.driver = {
.name = "wm8350-rtc",
+ .pm = &wm8350_rtc_pm_ops,
},
};
-static int __init wm8350_rtc_init(void)
-{
- return platform_driver_register(&wm8350_rtc_driver);
-}
-module_init(wm8350_rtc_init);
-
-static void __exit wm8350_rtc_exit(void)
-{
- platform_driver_unregister(&wm8350_rtc_driver);
-}
-module_exit(wm8350_rtc_exit);
+module_platform_driver(wm8350_rtc_driver);
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_DESCRIPTION("RTC driver for the WM8350");