Date:2010-06-28 01:30:56 (13 years 9 months ago)
Author:Lars C.
Commit:3deecc1845ad830cb640d439b23e78824324e153
Message:RTC: jz4740: Propergate write errors in jz4740_rtc_reg_write up to its callers

Files: drivers/rtc/rtc-jz4740.c (10 diffs)

Change Details

drivers/rtc/rtc-jz4740.c
11/*
22 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC RTC driver
3 * JZ4740 SoC RTC driver
44 *
55 * This program is free software; you can redistribute it and/or modify it
66 * under the terms of the GNU General Public License as published by the
...... 
5151    return readl(rtc->base + reg);
5252}
5353
54static inline void jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
54static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
5555{
5656    uint32_t ctrl;
57    int timeout = 10;
57    int timeout = 1000;
5858
5959    do {
6060        ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
61    } while (!(ctrl & JZ_RTC_CTRL_WRDY) && timeout--);
61    } while (!(ctrl & JZ_RTC_CTRL_WRDY) && --timeout);
62
63    return timeout ? 0 : -EIO;
6264}
6365
64static inline void jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
66static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
6567    uint32_t val)
6668{
67    jz4740_rtc_wait_write_ready(rtc);
68    writel(val, rtc->base + reg);
69    int ret;
70    ret = jz4740_rtc_wait_write_ready(rtc);
71    if (ret == 0)
72        writel(val, rtc->base + reg);
73
74    return ret;
6975}
7076
71static void jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask,
72    uint32_t val)
77static int jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask,
78    bool set)
7379{
80    int ret;
7481    unsigned long flags;
7582    uint32_t ctrl;
7683
...... 
8188    /* Don't clear interrupt flags by accident */
8289    ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF;
8390
84    ctrl &= ~mask;
85    ctrl |= val;
91    if (set)
92        ctrl |= mask;
93    else
94        ctrl &= ~mask;
8695
87    jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl);
96    ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl);
8897
8998    spin_unlock_irqrestore(&rtc->lock, flags);
99
100    return ret;
90101}
91102
92103static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time)
...... 
102113    secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
103114    secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
104115
105    while (secs != secs2 && timeout--) {
116    while (secs != secs2 && --timeout) {
106117        secs = secs2;
107118        secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
108119    }
...... 
119130{
120131    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
121132
122    if ((uint32_t)secs != secs)
123        return -EINVAL;
124
125    jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs);
126
127    return 0;
133    return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs);
128134}
129135
130136static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
...... 
147153
148154static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
149155{
156    int ret;
150157    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
151158    unsigned long secs;
152159
153160    rtc_tm_to_time(&alrm->time, &secs);
154161
155    if ((uint32_t)secs != secs)
156        return -EINVAL;
157
158    jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, (uint32_t)secs);
159    jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE,
160                    alrm->enabled ? JZ_RTC_CTRL_AE : 0);
162    ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs);
163    if (!ret)
164        ret = jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE, alrm->enabled);
161165
162    return 0;
163}
164
165static inline int jz4740_irq_enable(struct device *dev, int irq, unsigned int enable)
166{
167    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
168    jz4740_rtc_ctrl_set_bits(rtc, irq, enable ? irq : 0);
169
170    return 0;
166    return ret;
171167}
172168
173169static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enable)
174170{
175    return jz4740_irq_enable(dev, JZ_RTC_CTRL_1HZ_IRQ, enable);
171    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
172    return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ, enable);
176173}
177174
178175static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
179176{
180    return jz4740_irq_enable(dev, JZ_RTC_CTRL_AF_IRQ, enable);
177    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
178    return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, enable);
181179}
182180
183181static struct rtc_class_ops jz4740_rtc_ops = {
...... 
194192    struct jz4740_rtc *rtc = data;
195193    uint32_t ctrl;
196194    unsigned long events = 0;
195
197196    ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
198197
199198    if (ctrl & JZ_RTC_CTRL_1HZ)
...... 
204203
205204    rtc_update_irq(rtc->rtc, 1, events);
206205
207    jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, 0);
206    jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, false);
208207
209208    return IRQ_HANDLED;
210209}
...... 
276275
277276    scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD);
278277    if (scratchpad != 0x12345678) {
279        jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678);
280        jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0);
278        ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678);
279        ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0);
280        if (ret) {
281            dev_err(&pdev->dev, "Could not write write to RTC registers\n");
282            goto err_free_irq;
283        }
281284    }
282285
283286    return 0;
284287
288err_free_irq:
289    free_irq(rtc->irq, rtc);
285290err_unregister_rtc:
286291    rtc_device_unregister(rtc->rtc);
287292err_iounmap:
...... 
336341
337342MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
338343MODULE_LICENSE("GPL");
339MODULE_DESCRIPTION("RTC driver for the JZ4720/JZ4740 SoC\n");
344MODULE_DESCRIPTION("RTC driver for the JZ4740 SoC\n");
340345MODULE_ALIAS("platform:jz4740-rtc");

Archive Download the corresponding diff file



interactive