From 61598093bbdd283a7edc367d900f223070ead8d2 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 07:43:03 +0000 Subject: [PATCH] add ax88772C AX88772C_eeprom_tools --- kernel/drivers/rtc/rtc-sc27xx.c | 74 +++++++++++++++++++++---------------- 1 files changed, 42 insertions(+), 32 deletions(-) diff --git a/kernel/drivers/rtc/rtc-sc27xx.c b/kernel/drivers/rtc/rtc-sc27xx.c index deea5c3..36810dd 100644 --- a/kernel/drivers/rtc/rtc-sc27xx.c +++ b/kernel/drivers/rtc/rtc-sc27xx.c @@ -129,19 +129,6 @@ SPRD_RTC_ALM_INT_MASK); } -static int sprd_rtc_disable_ints(struct sprd_rtc *rtc) -{ - int ret; - - ret = regmap_update_bits(rtc->regmap, rtc->base + SPRD_RTC_INT_EN, - SPRD_RTC_INT_MASK, 0); - if (ret) - return ret; - - return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR, - SPRD_RTC_INT_MASK); -} - static int sprd_rtc_lock_alarm(struct sprd_rtc *rtc, bool lock) { int ret; @@ -151,7 +138,7 @@ if (ret) return ret; - val &= ~(SPRD_RTC_ALMLOCK_MASK | SPRD_RTC_POWEROFF_ALM_FLAG); + val &= ~SPRD_RTC_ALMLOCK_MASK; if (lock) val |= SPRD_RTC_ALM_LOCK; else @@ -172,7 +159,8 @@ return ret; } - return 0; + return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR, + SPRD_RTC_SPG_UPD_EN); } static int sprd_rtc_get_secs(struct sprd_rtc *rtc, enum sprd_rtc_reg_types type, @@ -427,10 +415,14 @@ u32 val; /* - * If aie_timer is enabled, we should get the normal alarm time. + * Before RTC device is registered, it will check to see if there is an + * alarm already set in RTC hardware, and we always read the normal + * alarm at this time. + * + * Or if aie_timer is enabled, we should get the normal alarm time. * Otherwise we should get auxiliary alarm time. */ - if (rtc->rtc && rtc->rtc->aie_timer.enabled == 0) + if (rtc->rtc && rtc->rtc->registered && rtc->rtc->aie_timer.enabled == 0) return sprd_rtc_read_aux_alarm(dev, alrm); ret = sprd_rtc_get_secs(rtc, SPRD_RTC_ALARM, &secs); @@ -575,6 +567,32 @@ return 0; } +static int sprd_rtc_check_alarm_int(struct sprd_rtc *rtc) +{ + u32 val; + int ret; + + ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_SPG_VALUE, &val); + if (ret) + return ret; + + /* + * The SPRD_RTC_INT_EN register is not put in always-power-on region + * supplied by VDDRTC, so we should check if we need enable the alarm + * interrupt when system booting. + * + * If we have set SPRD_RTC_POWEROFF_ALM_FLAG which is saved in + * always-power-on region, that means we have set one alarm last time, + * so we should enable the alarm interrupt to help RTC core to see if + * there is an alarm already set in RTC hardware. + */ + if (!(val & SPRD_RTC_POWEROFF_ALM_FLAG)) + return 0; + + return regmap_update_bits(rtc->regmap, rtc->base + SPRD_RTC_INT_EN, + SPRD_RTC_ALARM_EN, SPRD_RTC_ALARM_EN); +} + static int sprd_rtc_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -596,10 +614,8 @@ } rtc->irq = platform_get_irq(pdev, 0); - if (rtc->irq < 0) { - dev_err(&pdev->dev, "failed to get RTC irq number\n"); + if (rtc->irq < 0) return rtc->irq; - } rtc->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc->rtc)) @@ -608,10 +624,10 @@ rtc->dev = &pdev->dev; platform_set_drvdata(pdev, rtc); - /* clear all RTC interrupts and disable all RTC interrupts */ - ret = sprd_rtc_disable_ints(rtc); + /* check if we need set the alarm interrupt */ + ret = sprd_rtc_check_alarm_int(rtc); if (ret) { - dev_err(&pdev->dev, "failed to disable RTC interrupts\n"); + dev_err(&pdev->dev, "failed to check RTC alarm interrupt\n"); return ret; } @@ -631,22 +647,17 @@ return ret; } + device_init_wakeup(&pdev->dev, 1); + rtc->rtc->ops = &sprd_rtc_ops; rtc->rtc->range_min = 0; rtc->rtc->range_max = 5662310399LL; ret = rtc_register_device(rtc->rtc); if (ret) { - dev_err(&pdev->dev, "failed to register rtc device\n"); + device_init_wakeup(&pdev->dev, 0); return ret; } - device_init_wakeup(&pdev->dev, 1); - return 0; -} - -static int sprd_rtc_remove(struct platform_device *pdev) -{ - device_init_wakeup(&pdev->dev, 0); return 0; } @@ -662,7 +673,6 @@ .of_match_table = sprd_rtc_of_match, }, .probe = sprd_rtc_probe, - .remove = sprd_rtc_remove, }; module_platform_driver(sprd_rtc_driver); -- Gitblit v1.6.2