summaryrefslogtreecommitdiff
path: root/drivers/rtc/rtc-ds1511.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-ds1511.c')
-rw-r--r--drivers/rtc/rtc-ds1511.c52
1 files changed, 23 insertions, 29 deletions
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 4ac8988d4124..b0dfdda2c8fc 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -178,35 +178,15 @@ static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
return 0;
}
-/*
- * write the alarm register settings
- *
- * we only have the use to interrupt every second, otherwise
- * known as the update interrupt, or the interrupt if the whole
- * date/hours/mins/secs matches. the ds1511 has many more
- * permutations, but the kernel doesn't.
- */
-static void ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
+static void ds1511_rtc_alarm_enable(unsigned int enabled)
{
- unsigned long flags;
-
- spin_lock_irqsave(&pdata->lock, flags);
- rtc_write(pdata->alrm_mday < 0 ? 0x80 : bin2bcd(pdata->alrm_mday) & 0x3f,
- DS1511_AM4_DATE);
- rtc_write(pdata->alrm_hour < 0 ? 0x80 : bin2bcd(pdata->alrm_hour) & 0x3f,
- DS1511_AM3_HOUR);
- rtc_write(pdata->alrm_min < 0 ? 0x80 : bin2bcd(pdata->alrm_min) & 0x7f,
- DS1511_AM2_MIN);
- rtc_write(pdata->alrm_sec < 0 ? 0x80 : bin2bcd(pdata->alrm_sec) & 0x7f,
- DS1511_AM1_SEC);
- rtc_write(rtc_read(DS1511_CONTROL_B) | (pdata->irqen ? DS1511_TIE : 0), DS1511_CONTROL_B);
- rtc_read(DS1511_CONTROL_A); /* clear interrupts */
- spin_unlock_irqrestore(&pdata->lock, flags);
+ rtc_write(rtc_read(DS1511_CONTROL_B) | (enabled ? DS1511_TIE : 0), DS1511_CONTROL_B);
}
static int ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
+ unsigned long flags;
if (pdata->irq <= 0)
return -EINVAL;
@@ -218,7 +198,20 @@ static int ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (alrm->enabled)
pdata->irqen |= RTC_AF;
- ds1511_rtc_update_alarm(pdata);
+ spin_lock_irqsave(&pdata->lock, flags);
+ rtc_write(pdata->alrm_mday < 0 ? 0x80 : bin2bcd(pdata->alrm_mday) & 0x3f,
+ DS1511_AM4_DATE);
+ rtc_write(pdata->alrm_hour < 0 ? 0x80 : bin2bcd(pdata->alrm_hour) & 0x3f,
+ DS1511_AM3_HOUR);
+ rtc_write(pdata->alrm_min < 0 ? 0x80 : bin2bcd(pdata->alrm_min) & 0x7f,
+ DS1511_AM2_MIN);
+ rtc_write(pdata->alrm_sec < 0 ? 0x80 : bin2bcd(pdata->alrm_sec) & 0x7f,
+ DS1511_AM1_SEC);
+ ds1511_rtc_alarm_enable(alrm->enabled);
+
+ rtc_read(DS1511_CONTROL_A); /* clear interrupts */
+ spin_unlock_irqrestore(&pdata->lock, flags);
+
return 0;
}
@@ -258,14 +251,15 @@ static irqreturn_t ds1511_interrupt(int irq, void *dev_id)
static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct rtc_plat_data *pdata = dev_get_drvdata(dev);
+ unsigned long flags;
if (pdata->irq <= 0)
return -EINVAL;
- if (enabled)
- pdata->irqen |= RTC_AF;
- else
- pdata->irqen &= ~RTC_AF;
- ds1511_rtc_update_alarm(pdata);
+
+ spin_lock_irqsave(&pdata->lock, flags);
+ ds1511_rtc_alarm_enable(enabled);
+ spin_unlock_irqrestore(&pdata->lock, flags);
+
return 0;
}