Root/drivers/rtc/rtc-jz4740.c

1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * Copyright (C) 2010, Paul Cercueil <paul@crapouillou.net>
4 * JZ4740 SoC RTC driver
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * You should have received a copy of the GNU General Public License along
12 * with this program; if not, write to the Free Software Foundation, Inc.,
13 * 675 Mass Ave, Cambridge, MA 02139, USA.
14 *
15 */
16
17#include <linux/clk.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/rtc.h>
22#include <linux/slab.h>
23#include <linux/spinlock.h>
24
25#define JZ_REG_RTC_CTRL 0x00
26#define JZ_REG_RTC_SEC 0x04
27#define JZ_REG_RTC_SEC_ALARM 0x08
28#define JZ_REG_RTC_REGULATOR 0x0C
29#define JZ_REG_RTC_HIBERNATE 0x20
30#define JZ_REG_RTC_SCRATCHPAD 0x34
31
32#define JZ_RTC_CTRL_WRDY BIT(7)
33#define JZ_RTC_CTRL_1HZ BIT(6)
34#define JZ_RTC_CTRL_1HZ_IRQ BIT(5)
35#define JZ_RTC_CTRL_AF BIT(4)
36#define JZ_RTC_CTRL_AF_IRQ BIT(3)
37#define JZ_RTC_CTRL_AE BIT(2)
38#define JZ_RTC_CTRL_ENABLE BIT(0)
39
40struct jz4740_rtc {
41    struct resource *mem;
42    void __iomem *base;
43
44    struct rtc_device *rtc;
45
46    unsigned int irq;
47
48    spinlock_t lock;
49};
50
51static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg)
52{
53    return readl(rtc->base + reg);
54}
55
56static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
57{
58    uint32_t ctrl;
59    int timeout = 1000;
60
61    do {
62        ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
63    } while (!(ctrl & JZ_RTC_CTRL_WRDY) && --timeout);
64
65    return timeout ? 0 : -EIO;
66}
67
68static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
69    uint32_t val)
70{
71    int ret;
72    ret = jz4740_rtc_wait_write_ready(rtc);
73    if (ret == 0)
74        writel(val, rtc->base + reg);
75
76    return ret;
77}
78
79static int jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask,
80    bool set)
81{
82    int ret;
83    unsigned long flags;
84    uint32_t ctrl;
85
86    spin_lock_irqsave(&rtc->lock, flags);
87
88    ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
89
90    /* Don't clear interrupt flags by accident */
91    ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF;
92
93    if (set)
94        ctrl |= mask;
95    else
96        ctrl &= ~mask;
97
98    ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl);
99
100    spin_unlock_irqrestore(&rtc->lock, flags);
101
102    return ret;
103}
104
105static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time)
106{
107    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
108    uint32_t secs, secs2;
109    int timeout = 5;
110
111    /* If the seconds register is read while it is updated, it can contain a
112     * bogus value. This can be avoided by making sure that two consecutive
113     * reads have the same value.
114     */
115    secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
116    secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
117
118    while (secs != secs2 && --timeout) {
119        secs = secs2;
120        secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
121    }
122
123    if (timeout == 0)
124        return -EIO;
125
126    rtc_time_to_tm(secs, time);
127
128    return rtc_valid_tm(time);
129}
130
131static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs)
132{
133    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
134
135    return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs);
136}
137
138static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
139{
140    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
141    uint32_t secs;
142    uint32_t ctrl;
143
144    secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
145
146    ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
147
148    alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE);
149    alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF);
150
151    rtc_time_to_tm(secs, &alrm->time);
152
153    return rtc_valid_tm(&alrm->time);
154}
155
156static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
157{
158    int ret;
159    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
160    unsigned long secs;
161
162    rtc_tm_to_time(&alrm->time, &secs);
163
164    ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs);
165    if (!ret)
166        ret = jz4740_rtc_ctrl_set_bits(rtc,
167            JZ_RTC_CTRL_AE | JZ_RTC_CTRL_AF_IRQ, alrm->enabled);
168
169    return ret;
170}
171
172static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
173{
174    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
175    return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, enable);
176}
177
178static struct rtc_class_ops jz4740_rtc_ops = {
179    .read_time = jz4740_rtc_read_time,
180    .set_mmss = jz4740_rtc_set_mmss,
181    .read_alarm = jz4740_rtc_read_alarm,
182    .set_alarm = jz4740_rtc_set_alarm,
183    .alarm_irq_enable = jz4740_rtc_alarm_irq_enable,
184};
185
186static irqreturn_t jz4740_rtc_irq(int irq, void *data)
187{
188    struct jz4740_rtc *rtc = data;
189    uint32_t ctrl;
190    unsigned long events = 0;
191
192    ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
193
194    if (ctrl & JZ_RTC_CTRL_1HZ)
195        events |= (RTC_UF | RTC_IRQF);
196
197    if (ctrl & JZ_RTC_CTRL_AF)
198        events |= (RTC_AF | RTC_IRQF);
199
200    rtc_update_irq(rtc->rtc, 1, events);
201
202    jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, false);
203
204    return IRQ_HANDLED;
205}
206
207void jz4740_rtc_poweroff(struct device *dev)
208{
209    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
210    jz4740_rtc_reg_write(rtc, JZ_REG_RTC_HIBERNATE, 1);
211}
212EXPORT_SYMBOL_GPL(jz4740_rtc_poweroff);
213
214static int __devinit jz4740_rtc_probe(struct platform_device *pdev)
215{
216    int ret;
217    struct jz4740_rtc *rtc;
218    uint32_t scratchpad;
219    struct clk *rtc_clk;
220
221    rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
222    if (!rtc)
223        return -ENOMEM;
224
225    rtc->irq = platform_get_irq(pdev, 0);
226    if (rtc->irq < 0) {
227        ret = -ENOENT;
228        dev_err(&pdev->dev, "Failed to get platform irq\n");
229        goto err_free;
230    }
231
232    rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
233    if (!rtc->mem) {
234        ret = -ENOENT;
235        dev_err(&pdev->dev, "Failed to get platform mmio memory\n");
236        goto err_free;
237    }
238
239    rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem),
240                    pdev->name);
241    if (!rtc->mem) {
242        ret = -EBUSY;
243        dev_err(&pdev->dev, "Failed to request mmio memory region\n");
244        goto err_free;
245    }
246
247    rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem));
248    if (!rtc->base) {
249        ret = -EBUSY;
250        dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
251        goto err_release_mem_region;
252    }
253
254    spin_lock_init(&rtc->lock);
255
256    platform_set_drvdata(pdev, rtc);
257
258    device_init_wakeup(&pdev->dev, 1);
259
260    rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops,
261                    THIS_MODULE);
262    if (IS_ERR(rtc->rtc)) {
263        ret = PTR_ERR(rtc->rtc);
264        dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret);
265        goto err_iounmap;
266    }
267
268    ret = request_irq(rtc->irq, jz4740_rtc_irq, 0,
269                pdev->name, rtc);
270    if (ret) {
271        dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret);
272        goto err_unregister_rtc;
273    }
274
275    scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD);
276    if (scratchpad != 0x12345678) {
277        ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678);
278        ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0);
279        if (ret) {
280            dev_err(&pdev->dev, "Could not write write to RTC registers\n");
281            goto err_free_irq;
282        }
283    }
284
285    rtc_clk = clk_get(&pdev->dev, "rtc");
286    if (IS_ERR(rtc_clk)) {
287        dev_err(&pdev->dev, "Failed to get RTC clock\n");
288        goto err_free_irq;
289    }
290
291    /* TODO: initialize the ADJC bits (25:16) to fine-tune
292     * the accuracy of the RTC */
293    ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_REGULATOR,
294                (clk_get_rate(rtc_clk) - 1) & 0xffff);
295    clk_put(rtc_clk);
296
297    if (ret)
298        dev_warn(&pdev->dev, "Could not update RTC regulator register\n");
299
300    return 0;
301
302err_free_irq:
303    free_irq(rtc->irq, rtc);
304err_unregister_rtc:
305    rtc_device_unregister(rtc->rtc);
306err_iounmap:
307    platform_set_drvdata(pdev, NULL);
308    iounmap(rtc->base);
309err_release_mem_region:
310    release_mem_region(rtc->mem->start, resource_size(rtc->mem));
311err_free:
312    kfree(rtc);
313
314    return ret;
315}
316
317static int __devexit jz4740_rtc_remove(struct platform_device *pdev)
318{
319    struct jz4740_rtc *rtc = platform_get_drvdata(pdev);
320
321    free_irq(rtc->irq, rtc);
322
323    rtc_device_unregister(rtc->rtc);
324
325    iounmap(rtc->base);
326    release_mem_region(rtc->mem->start, resource_size(rtc->mem));
327
328    kfree(rtc);
329
330    platform_set_drvdata(pdev, NULL);
331
332    return 0;
333}
334
335
336#ifdef CONFIG_PM
337static int jz4740_rtc_suspend(struct device *dev)
338{
339    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
340
341    if (device_may_wakeup(dev))
342        enable_irq_wake(rtc->irq);
343    return 0;
344}
345
346static int jz4740_rtc_resume(struct device *dev)
347{
348    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
349
350    if (device_may_wakeup(dev))
351        disable_irq_wake(rtc->irq);
352    return 0;
353}
354
355static const struct dev_pm_ops jz4740_pm_ops = {
356    .suspend = jz4740_rtc_suspend,
357    .resume = jz4740_rtc_resume,
358};
359#define JZ4740_RTC_PM_OPS (&jz4740_pm_ops)
360
361#else
362#define JZ4740_RTC_PM_OPS NULL
363#endif /* CONFIG_PM */
364
365static struct platform_driver jz4740_rtc_driver = {
366    .probe = jz4740_rtc_probe,
367    .remove = __devexit_p(jz4740_rtc_remove),
368    .driver = {
369        .name = "jz4740-rtc",
370        .owner = THIS_MODULE,
371        .pm = JZ4740_RTC_PM_OPS,
372    },
373};
374
375module_platform_driver(jz4740_rtc_driver);
376
377MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
378MODULE_LICENSE("GPL");
379MODULE_DESCRIPTION("RTC driver for the JZ4740 SoC\n");
380MODULE_ALIAS("platform:jz4740-rtc");
381

Archive Download this file



interactive