diff options
Diffstat (limited to 'drivers/rtc/rtc-snvs.c')
-rw-r--r-- | drivers/rtc/rtc-snvs.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index b9371f471abe..0263d996b8a8 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -148,10 +148,21 @@ static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable) static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct snvs_rtc_data *data = dev_get_drvdata(dev); - unsigned long time = rtc_read_lp_counter(data); + unsigned long time; + int ret; + + if (data->clk) { + ret = clk_enable(data->clk); + if (ret) + return ret; + } + time = rtc_read_lp_counter(data); rtc_time64_to_tm(time, tm); + if (data->clk) + clk_disable(data->clk); + return 0; } @@ -161,6 +172,12 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm) unsigned long time = rtc_tm_to_time64(tm); int ret; + if (data->clk) { + ret = clk_enable(data->clk); + if (ret) + return ret; + } + /* Disable RTC first */ ret = snvs_rtc_enable(data, false); if (ret) @@ -173,6 +190,9 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm) /* Enable RTC again */ ret = snvs_rtc_enable(data, true); + if (data->clk) + clk_disable(data->clk); + return ret; } @@ -180,6 +200,13 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct snvs_rtc_data *data = dev_get_drvdata(dev); u32 lptar, lpsr; + int ret; + + if (data->clk) { + ret = clk_enable(data->clk); + if (ret) + return ret; + } regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar); rtc_time64_to_tm(lptar, &alrm->time); @@ -187,18 +214,33 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr); alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0; + if (data->clk) + clk_disable(data->clk); + return 0; } static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) { struct snvs_rtc_data *data = dev_get_drvdata(dev); + int ret; + + if (data->clk) { + ret = clk_enable(data->clk); + if (ret) + return ret; + } regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN), enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0); - return rtc_write_sync_lp(data); + ret = rtc_write_sync_lp(data); + + if (data->clk) + clk_disable(data->clk); + + return ret; } static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) @@ -207,6 +249,12 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) unsigned long time = rtc_tm_to_time64(&alrm->time); int ret; + if (data->clk) { + ret = clk_enable(data->clk); + if (ret) + return ret; + } + regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0); ret = rtc_write_sync_lp(data); if (ret) @@ -216,6 +264,9 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) /* Clear alarm interrupt status bit */ regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA); + if (data->clk) + clk_disable(data->clk); + return snvs_rtc_alarm_irq_enable(dev, alrm->enabled); } |