diff options
Diffstat (limited to 'drivers/rtc/rtc-sun6i.c')
-rw-r--r-- | drivers/rtc/rtc-sun6i.c | 47 |
1 files changed, 21 insertions, 26 deletions
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 852f5f3b3592..e2b8b150bcb4 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -108,7 +108,6 @@ * driver, even though it is somewhat limited. */ #define SUN6I_YEAR_MIN 1970 -#define SUN6I_YEAR_MAX 2033 #define SUN6I_YEAR_OFF (SUN6I_YEAR_MIN - 1900) /* @@ -250,19 +249,17 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, writel(reg, rtc->base + SUN6I_LOSC_CTRL); } - /* Switch to the external, more precise, oscillator */ - reg |= SUN6I_LOSC_CTRL_EXT_OSC; - if (rtc->data->has_losc_en) - reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN; + /* Switch to the external, more precise, oscillator, if present */ + if (of_get_property(node, "clocks", NULL)) { + reg |= SUN6I_LOSC_CTRL_EXT_OSC; + if (rtc->data->has_losc_en) + reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN; + } writel(reg, rtc->base + SUN6I_LOSC_CTRL); /* Yes, I know, this is ugly. */ sun6i_rtc = rtc; - /* Deal with old DTs */ - if (!of_get_property(node, "clocks", NULL)) - goto err; - /* Only read IOSC name from device tree if it is exported */ if (rtc->data->export_iosc) of_property_read_string_index(node, "clock-output-names", 2, @@ -279,11 +276,13 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, } parents[0] = clk_hw_get_name(rtc->int_osc); + /* If there is no external oscillator, this will be NULL and ... */ parents[1] = of_clk_get_parent_name(node, 0); rtc->hw.init = &init; init.parent_names = parents; + /* ... number of clock parents will be 1. */ init.num_parents = of_clk_get_parent_count(node) + 1; of_property_read_string_index(node, "clock-output-names", 0, &init.name); @@ -499,7 +498,7 @@ static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm) wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN); wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN); - rtc_time_to_tm(chip->alarm, &wkalrm->time); + rtc_time64_to_tm(chip->alarm, &wkalrm->time); return 0; } @@ -520,8 +519,8 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) return -EINVAL; } - rtc_tm_to_time(alrm_tm, &time_set); - rtc_tm_to_time(&tm_now, &time_now); + time_set = rtc_tm_to_time64(alrm_tm); + time_now = rtc_tm_to_time64(&tm_now); if (time_set <= time_now) { dev_err(dev, "Date to set in the past\n"); return -EINVAL; @@ -569,14 +568,6 @@ static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) struct sun6i_rtc_dev *chip = dev_get_drvdata(dev); u32 date = 0; u32 time = 0; - int year; - - year = rtc_tm->tm_year + 1900; - if (year < SUN6I_YEAR_MIN || year > SUN6I_YEAR_MAX) { - dev_err(dev, "rtc only supports year in range %d - %d\n", - SUN6I_YEAR_MIN, SUN6I_YEAR_MAX); - return -EINVAL; - } rtc_tm->tm_year -= SUN6I_YEAR_OFF; rtc_tm->tm_mon += 1; @@ -585,7 +576,7 @@ static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year); - if (is_leap_year(year)) + if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN)) date |= SUN6I_LEAP_SET_VALUE(1); time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) | @@ -726,12 +717,16 @@ static int sun6i_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i", - &sun6i_rtc_ops, THIS_MODULE); - if (IS_ERR(chip->rtc)) { - dev_err(&pdev->dev, "unable to register device\n"); + chip->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(chip->rtc)) return PTR_ERR(chip->rtc); - } + + chip->rtc->ops = &sun6i_rtc_ops; + chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */ + + ret = rtc_register_device(chip->rtc); + if (ret) + return ret; dev_info(&pdev->dev, "RTC enabled\n"); |