Date:2010-06-06 16:58:19 (13 years 6 months ago)
Author:Lars C.
Commit:f934e4b076ff99c345ba1ab92c0bfef94be7ae8a
Message:RTC: JZ4740: Remove deadlocks which could occur if the HW was broken

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

Change Details

drivers/rtc/rtc-jz4740.c
5454static inline void jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
5555{
5656    uint32_t ctrl;
57    int timeout = 10;
58
5759    do {
5860        ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
59    } while (!(ctrl & JZ_RTC_CTRL_WRDY));
61    } while (!(ctrl & JZ_RTC_CTRL_WRDY) && timeout--);
6062}
6163
6264static inline void jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
...... 
9193{
9294    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
9395    uint32_t secs, secs2;
96    int timeout = 5;
9497
98    /* If the seconds register is read while it is updated, it can contain a
99     * bogus value. This can be avoided by making sure that two consecutive
100     * reads have the same value.
101     */
95102    secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
96103    secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
97104
98    while (secs != secs2) {
105    while (secs != secs2 && timeout--) {
99106        secs = secs2;
100107        secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC);
101108    }
102109
110    if (timeout == 0)
111        return -EIO;
112
103113    rtc_time_to_tm(secs, time);
104114
105115    return rtc_valid_tm(time);
...... 
120130static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
121131{
122132    struct jz4740_rtc *rtc = dev_get_drvdata(dev);
123    uint32_t secs, secs2;
133    uint32_t secs;
124134    uint32_t ctrl;
125135
126136    secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
127    secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
128
129    while (secs != secs2) {
130        secs = secs2;
131        secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM);
132    }
133137
134138    ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);
135139

Archive Download the corresponding diff file



interactive