From b68d0098b23e111097b3b308136de8212e15ecdf Mon Sep 17 00:00:00 2001 From: Xiao Lin Date: Fri, 11 Jul 2025 10:11:55 +0800 Subject: [PATCH] rtc: s35390a: fix the issue where the alarm clock interruption cannot be triggered The alarm clock failed to register the interrupt handling function properly, resulting in the alarm clock being unable to report the alarm event to the framework layer Change-Id: Ie683776238255740badb1dcd83b56390c79dff05 Signed-off-by: Xiao Lin --- drivers/rtc/rtc-s35390a.c | 51 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index fb0e0c36131c..dc3248ffa3cc 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -468,6 +468,45 @@ static const struct rtc_class_ops s35390a_rtc_ops = { .ioctl = s35390a_rtc_ioctl, }; +static irqreturn_t s35390a_irq(int irq, void *dev_id) +{ + int err; + char sts = 0; + char status1; + struct s35390a *s35390a = (struct s35390a *)dev_id; + struct i2c_client *client = s35390a->client[0]; + + rtc_lock(s35390a->rtc); + + err = s35390a_read_status(s35390a, &status1); + if (err < 0) { + dev_err(&client->dev, "read status failure\n"); + goto out; + } + + if (status1 & S35390A_FLAG_INT2) { + /* clear pending interrupt (in STATUS1 only), if any */ + err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts)); + if (err < 0) { + dev_err(&client->dev, "read S35390A_CMD_STATUS1 failure\n"); + goto out; + } + + sts = S35390A_INT2_MODE_NOINTR | S35390A_INT2_MODE_32K; + + /* disable interrupt */ + err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); + if (err < 0) { + dev_err(&client->dev, "clear interrupt failure\n"); + goto out; + } + rtc_update_irq(s35390a->rtc, 1, RTC_AF); + } +out: + rtc_unlock(s35390a->rtc); + return IRQ_HANDLED; +} + static int s35390a_probe(struct i2c_client *client) { int err, err_read; @@ -546,6 +585,18 @@ static int s35390a_probe(struct i2c_client *client) set_bit(RTC_FEATURE_ALARM_RES_MINUTE, s35390a->rtc->features); clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, s35390a->rtc->features ); + if (client->irq > 0) { + err = devm_request_threaded_irq(&client->dev, client->irq, + NULL, s35390a_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + client->name, s35390a); + if (err < 0) { + dev_err(&client->dev, "irq %d request failed, %d\n", + client->irq, err); + return err; + } + } + if (status1 & S35390A_FLAG_INT2) rtc_update_irq(s35390a->rtc, 1, RTC_AF);