aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-zynqmp.c
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2025-11-16 14:34:50 +0000
committersaturneric <[email protected]>2025-11-16 14:34:50 +0000
commit690862a8d74fee1e07f33dad44b761753f101779 (patch)
treef81bdcab8cd5a640518dba5056de6c62bd071eaf /drivers/rtc/rtc-zynqmp.c
parentMerge tag 'v6.17.7' into linux-6.17.y (diff)
parentLinux 6.17.8 (diff)
downloadkernel-linux-6.17.y.tar.gz
kernel-linux-6.17.y.zip
Merge tag 'v6.17.8' into linux-6.17.ylinux-6.17.y
This is the 6.17.8 stable release
Diffstat (limited to 'drivers/rtc/rtc-zynqmp.c')
-rw-r--r--drivers/rtc/rtc-zynqmp.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
index f39102b66eac..3baa2b481d9f 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -277,6 +277,10 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
static int xlnx_rtc_probe(struct platform_device *pdev)
{
struct xlnx_rtc_dev *xrtcdev;
+ bool is_alarm_set = false;
+ u32 pending_alrm_irq;
+ u32 current_time;
+ u32 alarm_time;
int ret;
xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
@@ -296,6 +300,17 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
if (IS_ERR(xrtcdev->reg_base))
return PTR_ERR(xrtcdev->reg_base);
+ /* Clear any pending alarm interrupts from previous kernel/boot */
+ pending_alrm_irq = readl(xrtcdev->reg_base + RTC_INT_STS) & RTC_INT_ALRM;
+ if (pending_alrm_irq)
+ writel(pending_alrm_irq, xrtcdev->reg_base + RTC_INT_STS);
+
+ /* Check if a valid alarm is already set from previous kernel/boot */
+ alarm_time = readl(xrtcdev->reg_base + RTC_ALRM);
+ current_time = readl(xrtcdev->reg_base + RTC_CUR_TM);
+ if (alarm_time > current_time && alarm_time != 0)
+ is_alarm_set = true;
+
xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");
if (xrtcdev->alarm_irq < 0)
return xrtcdev->alarm_irq;
@@ -337,6 +352,10 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
xlnx_init_rtc(xrtcdev);
+ /* Re-enable alarm interrupt if a valid alarm was found */
+ if (is_alarm_set)
+ writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN);
+
device_init_wakeup(&pdev->dev, true);
return devm_rtc_register_device(xrtcdev->rtc);