Commit c88db0ef authored by Johan Hovold's avatar Johan Hovold Committed by Alexandre Belloni

rtc: pm8xxx: fix set-alarm race

Make sure to disable the alarm before updating the four alarm time
registers to avoid spurious alarms during the update.

Note that the disable needs to be done outside of the ctrl_reg_lock
section to prevent a racing alarm interrupt from disabling the newly set
alarm when the lock is released.

Fixes: 9a9a54ad ("drivers/rtc: add support for Qualcomm PMIC8xxx RTC")
Cc: stable@vger.kernel.org      # 3.1
Signed-off-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Reviewed-by: default avatarDavid Collins <quic_collinsd@quicinc.com>
Link: https://lore.kernel.org/r/20230202155448.6715-2-johan+linaro@kernel.orgSigned-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent 6a22a5db
......@@ -221,7 +221,6 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
int rc, i;
u8 value[NUM_8_BIT_RTC_REGS];
unsigned int ctrl_reg;
unsigned long secs, irq_flags;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
......@@ -233,6 +232,11 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
secs >>= 8;
}
rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl,
regs->alarm_en, 0);
if (rc)
return rc;
spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value,
......@@ -242,19 +246,11 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
goto rtc_rw_fail;
}
rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
if (alarm->enabled) {
rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl,
regs->alarm_en, regs->alarm_en);
if (rc)
goto rtc_rw_fail;
if (alarm->enabled)
ctrl_reg |= regs->alarm_en;
else
ctrl_reg &= ~regs->alarm_en;
rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
if (rc) {
dev_err(dev, "Write to RTC alarm control register failed\n");
goto rtc_rw_fail;
}
dev_dbg(dev, "Alarm Set for h:m:s=%ptRt, y-m-d=%ptRdr\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment