diff options
Diffstat (limited to 'drivers/rtc/rtc-at91rm9200.c')
-rw-r--r-- | drivers/rtc/rtc-at91rm9200.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 3281c90691c3..44fe83ee9bee 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -48,6 +48,7 @@ struct at91_rtc_config { | |||
48 | 48 | ||
49 | static const struct at91_rtc_config *at91_rtc_config; | 49 | static const struct at91_rtc_config *at91_rtc_config; |
50 | static DECLARE_COMPLETION(at91_rtc_updated); | 50 | static DECLARE_COMPLETION(at91_rtc_updated); |
51 | static DECLARE_COMPLETION(at91_rtc_upd_rdy); | ||
51 | static unsigned int at91_alarm_year = AT91_RTC_EPOCH; | 52 | static unsigned int at91_alarm_year = AT91_RTC_EPOCH; |
52 | static void __iomem *at91_rtc_regs; | 53 | static void __iomem *at91_rtc_regs; |
53 | static int irq; | 54 | static int irq; |
@@ -161,6 +162,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
161 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 162 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
162 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 163 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
163 | 164 | ||
165 | wait_for_completion(&at91_rtc_upd_rdy); | ||
166 | |||
164 | /* Stop Time/Calendar from counting */ | 167 | /* Stop Time/Calendar from counting */ |
165 | cr = at91_rtc_read(AT91_RTC_CR); | 168 | cr = at91_rtc_read(AT91_RTC_CR); |
166 | at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); | 169 | at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); |
@@ -183,7 +186,9 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
183 | 186 | ||
184 | /* Restart Time/Calendar */ | 187 | /* Restart Time/Calendar */ |
185 | cr = at91_rtc_read(AT91_RTC_CR); | 188 | cr = at91_rtc_read(AT91_RTC_CR); |
189 | at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_SECEV); | ||
186 | at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); | 190 | at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); |
191 | at91_rtc_write_ier(AT91_RTC_SECEV); | ||
187 | 192 | ||
188 | return 0; | 193 | return 0; |
189 | } | 194 | } |
@@ -290,8 +295,10 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
290 | if (rtsr) { /* this interrupt is shared! Is it ours? */ | 295 | if (rtsr) { /* this interrupt is shared! Is it ours? */ |
291 | if (rtsr & AT91_RTC_ALARM) | 296 | if (rtsr & AT91_RTC_ALARM) |
292 | events |= (RTC_AF | RTC_IRQF); | 297 | events |= (RTC_AF | RTC_IRQF); |
293 | if (rtsr & AT91_RTC_SECEV) | 298 | if (rtsr & AT91_RTC_SECEV) { |
294 | events |= (RTC_UF | RTC_IRQF); | 299 | complete(&at91_rtc_upd_rdy); |
300 | at91_rtc_write_idr(AT91_RTC_SECEV); | ||
301 | } | ||
295 | if (rtsr & AT91_RTC_ACKUPD) | 302 | if (rtsr & AT91_RTC_ACKUPD) |
296 | complete(&at91_rtc_updated); | 303 | complete(&at91_rtc_updated); |
297 | 304 | ||
@@ -413,6 +420,11 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
413 | return PTR_ERR(rtc); | 420 | return PTR_ERR(rtc); |
414 | platform_set_drvdata(pdev, rtc); | 421 | platform_set_drvdata(pdev, rtc); |
415 | 422 | ||
423 | /* enable SECEV interrupt in order to initialize at91_rtc_upd_rdy | ||
424 | * completion. | ||
425 | */ | ||
426 | at91_rtc_write_ier(AT91_RTC_SECEV); | ||
427 | |||
416 | dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n"); | 428 | dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n"); |
417 | return 0; | 429 | return 0; |
418 | } | 430 | } |