43e04af39e0964e3dccd24e251f484d04a680bc9
[pandora-kernel.git] / drivers / rtc / rtc-armada38x.c
1 /*
2  * RTC driver for the Armada 38x Marvell SoCs
3  *
4  * Copyright (C) 2015 Marvell
5  *
6  * Gregory Clement <gregory.clement@free-electrons.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  */
14
15 #include <linux/delay.h>
16 #include <linux/io.h>
17 #include <linux/module.h>
18 #include <linux/of.h>
19 #include <linux/platform_device.h>
20 #include <linux/rtc.h>
21
22 #define RTC_STATUS          0x0
23 #define RTC_STATUS_ALARM1           BIT(0)
24 #define RTC_STATUS_ALARM2           BIT(1)
25 #define RTC_IRQ1_CONF       0x4
26 #define RTC_IRQ1_AL_EN              BIT(0)
27 #define RTC_IRQ1_FREQ_EN            BIT(1)
28 #define RTC_IRQ1_FREQ_1HZ           BIT(2)
29 #define RTC_TIME            0xC
30 #define RTC_ALARM1          0x10
31
32 #define SOC_RTC_INTERRUPT   0x8
33 #define SOC_RTC_ALARM1          BIT(0)
34 #define SOC_RTC_ALARM2          BIT(1)
35 #define SOC_RTC_ALARM1_MASK     BIT(2)
36 #define SOC_RTC_ALARM2_MASK     BIT(3)
37
38 struct armada38x_rtc {
39         struct rtc_device   *rtc_dev;
40         void __iomem        *regs;
41         void __iomem        *regs_soc;
42         spinlock_t          lock;
43         int                 irq;
44 };
45
46 /*
47  * According to the datasheet, the OS should wait 5us after every
48  * register write to the RTC hard macro so that the required update
49  * can occur without holding off the system bus
50  */
51 static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
52 {
53         writel(val, rtc->regs + offset);
54         udelay(5);
55 }
56
57 static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
58 {
59         struct armada38x_rtc *rtc = dev_get_drvdata(dev);
60         unsigned long time, time_check, flags;
61
62         spin_lock_irqsave(&rtc->lock, flags);
63
64         time = readl(rtc->regs + RTC_TIME);
65         /*
66          * WA for failing time set attempts. As stated in HW ERRATA if
67          * more than one second between two time reads is detected
68          * then read once again.
69          */
70         time_check = readl(rtc->regs + RTC_TIME);
71         if ((time_check - time) > 1)
72                 time_check = readl(rtc->regs + RTC_TIME);
73
74         spin_unlock_irqrestore(&rtc->lock, flags);
75
76         rtc_time_to_tm(time_check, tm);
77
78         return 0;
79 }
80
81 static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
82 {
83         struct armada38x_rtc *rtc = dev_get_drvdata(dev);
84         int ret = 0;
85         unsigned long time, flags;
86
87         ret = rtc_tm_to_time(tm, &time);
88
89         if (ret)
90                 goto out;
91         /*
92          * Setting the RTC time not always succeeds. According to the
93          * errata we need to first write on the status register and
94          * then wait for 100ms before writing to the time register to be
95          * sure that the data will be taken into account.
96          */
97         spin_lock_irqsave(&rtc->lock, flags);
98
99         rtc_delayed_write(0, rtc, RTC_STATUS);
100
101         spin_unlock_irqrestore(&rtc->lock, flags);
102
103         msleep(100);
104
105         spin_lock_irqsave(&rtc->lock, flags);
106
107         rtc_delayed_write(time, rtc, RTC_TIME);
108
109         spin_unlock_irqrestore(&rtc->lock, flags);
110 out:
111         return ret;
112 }
113
114 static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
115 {
116         struct armada38x_rtc *rtc = dev_get_drvdata(dev);
117         unsigned long time, flags;
118         u32 val;
119
120         spin_lock_irqsave(&rtc->lock, flags);
121
122         time = readl(rtc->regs + RTC_ALARM1);
123         val = readl(rtc->regs + RTC_IRQ1_CONF) & RTC_IRQ1_AL_EN;
124
125         spin_unlock_irqrestore(&rtc->lock, flags);
126
127         alrm->enabled = val ? 1 : 0;
128         rtc_time_to_tm(time,  &alrm->time);
129
130         return 0;
131 }
132
133 static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
134 {
135         struct armada38x_rtc *rtc = dev_get_drvdata(dev);
136         unsigned long time, flags;
137         int ret = 0;
138         u32 val;
139
140         ret = rtc_tm_to_time(&alrm->time, &time);
141
142         if (ret)
143                 goto out;
144
145         spin_lock_irqsave(&rtc->lock, flags);
146
147         rtc_delayed_write(time, rtc, RTC_ALARM1);
148
149         if (alrm->enabled) {
150                         rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF);
151                         val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
152                         writel(val | SOC_RTC_ALARM1_MASK,
153                                rtc->regs_soc + SOC_RTC_INTERRUPT);
154         }
155
156         spin_unlock_irqrestore(&rtc->lock, flags);
157
158 out:
159         return ret;
160 }
161
162 static int armada38x_rtc_alarm_irq_enable(struct device *dev,
163                                          unsigned int enabled)
164 {
165         struct armada38x_rtc *rtc = dev_get_drvdata(dev);
166         unsigned long flags;
167
168         spin_lock_irqsave(&rtc->lock, flags);
169
170         if (enabled)
171                 rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF);
172         else
173                 rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
174
175         spin_unlock_irqrestore(&rtc->lock, flags);
176
177         return 0;
178 }
179
180 static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data)
181 {
182         struct armada38x_rtc *rtc = data;
183         u32 val;
184         int event = RTC_IRQF | RTC_AF;
185
186         dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq);
187
188         spin_lock(&rtc->lock);
189
190         val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
191
192         writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT);
193         val = readl(rtc->regs + RTC_IRQ1_CONF);
194         /* disable all the interrupts for alarm 1 */
195         rtc_delayed_write(0, rtc, RTC_IRQ1_CONF);
196         /* Ack the event */
197         rtc_delayed_write(RTC_STATUS_ALARM1, rtc, RTC_STATUS);
198
199         spin_unlock(&rtc->lock);
200
201         if (val & RTC_IRQ1_FREQ_EN) {
202                 if (val & RTC_IRQ1_FREQ_1HZ)
203                         event |= RTC_UF;
204                 else
205                         event |= RTC_PF;
206         }
207
208         rtc_update_irq(rtc->rtc_dev, 1, event);
209
210         return IRQ_HANDLED;
211 }
212
213 static struct rtc_class_ops armada38x_rtc_ops = {
214         .read_time = armada38x_rtc_read_time,
215         .set_time = armada38x_rtc_set_time,
216         .read_alarm = armada38x_rtc_read_alarm,
217         .set_alarm = armada38x_rtc_set_alarm,
218         .alarm_irq_enable = armada38x_rtc_alarm_irq_enable,
219 };
220
221 static __init int armada38x_rtc_probe(struct platform_device *pdev)
222 {
223         struct resource *res;
224         struct armada38x_rtc *rtc;
225         int ret;
226
227         rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc),
228                             GFP_KERNEL);
229         if (!rtc)
230                 return -ENOMEM;
231
232         spin_lock_init(&rtc->lock);
233
234         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
235         rtc->regs = devm_ioremap_resource(&pdev->dev, res);
236         if (IS_ERR(rtc->regs))
237                 return PTR_ERR(rtc->regs);
238         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc");
239         rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res);
240         if (IS_ERR(rtc->regs_soc))
241                 return PTR_ERR(rtc->regs_soc);
242
243         rtc->irq = platform_get_irq(pdev, 0);
244
245         if (rtc->irq < 0) {
246                 dev_err(&pdev->dev, "no irq\n");
247                 return rtc->irq;
248         }
249         if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
250                                 0, pdev->name, rtc) < 0) {
251                 dev_warn(&pdev->dev, "Interrupt not available.\n");
252                 rtc->irq = -1;
253                 /*
254                  * If there is no interrupt available then we can't
255                  * use the alarm
256                  */
257                 armada38x_rtc_ops.set_alarm = NULL;
258                 armada38x_rtc_ops.alarm_irq_enable = NULL;
259         }
260         platform_set_drvdata(pdev, rtc);
261         if (rtc->irq != -1)
262                 device_init_wakeup(&pdev->dev, 1);
263
264         rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
265                                         &armada38x_rtc_ops, THIS_MODULE);
266         if (IS_ERR(rtc->rtc_dev)) {
267                 ret = PTR_ERR(rtc->rtc_dev);
268                 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
269                 return ret;
270         }
271         return 0;
272 }
273
274 #ifdef CONFIG_PM_SLEEP
275 static int armada38x_rtc_suspend(struct device *dev)
276 {
277         if (device_may_wakeup(dev)) {
278                 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
279
280                 return enable_irq_wake(rtc->irq);
281         }
282
283         return 0;
284 }
285
286 static int armada38x_rtc_resume(struct device *dev)
287 {
288         if (device_may_wakeup(dev)) {
289                 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
290
291                 return disable_irq_wake(rtc->irq);
292         }
293
294         return 0;
295 }
296 #endif
297
298 static SIMPLE_DEV_PM_OPS(armada38x_rtc_pm_ops,
299                          armada38x_rtc_suspend, armada38x_rtc_resume);
300
301 #ifdef CONFIG_OF
302 static const struct of_device_id armada38x_rtc_of_match_table[] = {
303         { .compatible = "marvell,armada-380-rtc", },
304         {}
305 };
306 #endif
307
308 static struct platform_driver armada38x_rtc_driver = {
309         .driver         = {
310                 .name   = "armada38x-rtc",
311                 .pm     = &armada38x_rtc_pm_ops,
312                 .of_match_table = of_match_ptr(armada38x_rtc_of_match_table),
313         },
314 };
315
316 module_platform_driver_probe(armada38x_rtc_driver, armada38x_rtc_probe);
317
318 MODULE_DESCRIPTION("Marvell Armada 38x RTC driver");
319 MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
320 MODULE_LICENSE("GPL");