static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm) { u32 status; unsigned long read_time; struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); status = readl(xrtcdev->reg_base + RTC_INT_STS); if (status & RTC_INT_SEC) { /* * RTC has updated the CURRENT_TIME with the time written into * SET_TIME_WRITE register. */ rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm); } else { /* * Time written in SET_TIME_WRITE has not yet updated into * the seconds read register, so read the time from the * SET_TIME_WRITE instead of CURRENT_TIME register. * Since we add +1 sec while writing, we need to -1 sec while * reading. */ read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1; rtc_time64_to_tm(read_time, tm); } return rtc_valid_tm(tm); }
static void gregorian_to_rockchip(struct rtc_time *tm) { time64_t extra_days = nov2dec_transitions(tm); time64_t time = rtc_tm_to_time64(tm); rtc_time64_to_tm(time - extra_days * 86400, tm); /* Compensate if we went back over Nov 31st (will work up to 2381) */ if (nov2dec_transitions(tm) < extra_days) { if (tm->tm_mon + 1 == 11) tm->tm_mday++; /* This may result in 31! */ else rtc_time64_to_tm(time - (extra_days - 1) * 86400, tm); } }
/* * Read alarm time and date in RTC */ static int wm831x_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev); int ret; u16 data[2]; u32 time; ret = wm831x_bulk_read(wm831x_rtc->wm831x, WM831X_RTC_ALARM_1, 2, data); if (ret != 0) { dev_err(dev, "Failed to read alarm time: %d\n", ret); return ret; } time = (data[0] << 16) | data[1]; rtc_time64_to_tm(time, &alrm->time); ret = wm831x_reg_read(wm831x_rtc->wm831x, WM831X_RTC_CONTROL); if (ret < 0) { dev_err(dev, "Failed to read RTC control: %d\n", ret); return ret; } if (ret & WM831X_RTC_ALM_ENA) alrm->enabled = 1; else alrm->enabled = 0; return 0; }
static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); rtc_time64_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time); return 0; }
/* Read alarm time from RTC. */ static int cros_ec_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; int ret; u32 current_time, alarm_offset; /* * The EC host command for getting the alarm is relative (i.e. 5 * seconds from now) whereas rtc_wkalrm is absolute. Get the current * RTC time first so we can calculate the relative time. */ ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, ¤t_time); if (ret < 0) { dev_err(dev, "error getting time: %d\n", ret); return ret; } ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_ALARM, &alarm_offset); if (ret < 0) { dev_err(dev, "error getting alarm: %d\n", ret); return ret; } rtc_time64_to_tm(current_time + alarm_offset, &alrm->time); return 0; }
static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days1, days2; if (!priv->valid) return -ENODATA; do { int ret; ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); if (ret) return ret; ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds); if (ret) return ret; ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2); if (ret) return ret; } while (days1 != days2); rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm); return 0; }
static int test_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct rtc_test_data *rtd = dev_get_drvdata(dev); rtc_time64_to_tm(ktime_get_real_seconds() + rtd->offset, tm); return 0; }
static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time); alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM; return 0; }
static int ds2404_read_time(struct device *dev, struct rtc_time *dt) { unsigned long time = 0; ds2404_read_memory(dev, 0x203, 4, (u8 *)&time); time = le32_to_cpu(time); rtc_time64_to_tm(time, dt); return 0; }
void mpc8xx_get_rtc_time(struct rtc_time *tm) { unsigned long data; sit8xx_t __iomem *sys_tmr = immr_map(im_sit); /* Get time from the RTC. */ data = in_be32(&sys_tmr->sit_rtc); rtc_time64_to_tm(data, tm); immr_unmap(sys_tmr); return; }
/* Time read/write */ static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) { int ret; struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); ret = stmp3xxx_wait_time(rtc_data); if (ret) return ret; rtc_time64_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); return 0; }
/* * Convert ktime to rtc_time */ struct rtc_time rtc_ktime_to_tm(ktime_t kt) { struct timespec64 ts; struct rtc_time ret; ts = ktime_to_timespec64(kt); /* Round up any ns */ if (ts.tv_nsec) ts.tv_sec++; rtc_time64_to_tm(ts.tv_sec, &ret); return ret; }
static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) { struct pdc_tod tod_data; memset(tm, 0, sizeof(*tm)); if (pdc_tod_read(&tod_data) < 0) return -EOPNOTSUPP; /* we treat tod_sec as unsigned, so this can work until year 2106 */ rtc_time64_to_tm(tod_data.tod_sec, tm); return rtc_valid_tm(tm); }
static int test_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rtc_test_data *rtd = dev_get_drvdata(dev); time64_t alarm; alarm = (rtd->alarm.expires - jiffies) / HZ; alarm += ktime_get_real_seconds() + rtd->offset; rtc_time64_to_tm(alarm, &alrm->time); alrm->enabled = rtd->alarm_en; return 0; }
static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm) { union evm_time time; int status; int tries = 0; do { /* * Read LSB(0) to MSB(3) bytes. Defend against the counter * rolling over by re-reading until the value is stable, * and assuming the four reads take at most a few seconds. */ status = dm355evm_msp_read(DM355EVM_MSP_RTC_0); if (status < 0) return status; if (tries && time.bytes[0] == status) break; time.bytes[0] = status; status = dm355evm_msp_read(DM355EVM_MSP_RTC_1); if (status < 0) return status; if (tries && time.bytes[1] == status) break; time.bytes[1] = status; status = dm355evm_msp_read(DM355EVM_MSP_RTC_2); if (status < 0) return status; if (tries && time.bytes[2] == status) break; time.bytes[2] = status; status = dm355evm_msp_read(DM355EVM_MSP_RTC_3); if (status < 0) return status; if (tries && time.bytes[3] == status) break; time.bytes[3] = status; } while (++tries < 5); dev_dbg(dev, "read timestamp %08x\n", time.value); rtc_time64_to_tm(le32_to_cpu(time.value), tm); return 0; }
/* * Read current time and date in RTC */ static int wm831x_rtc_readtime(struct device *dev, struct rtc_time *tm) { struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev); struct wm831x *wm831x = wm831x_rtc->wm831x; u16 time1[2], time2[2]; int ret; int count = 0; /* Has the RTC been programmed? */ ret = wm831x_reg_read(wm831x, WM831X_RTC_CONTROL); if (ret < 0) { dev_err(dev, "Failed to read RTC control: %d\n", ret); return ret; } if (!(ret & WM831X_RTC_VALID)) { dev_dbg(dev, "RTC not yet configured\n"); return -EINVAL; } /* Read twice to make sure we don't read a corrupt, partially * incremented, value. */ do { ret = wm831x_bulk_read(wm831x, WM831X_RTC_TIME_1, 2, time1); if (ret != 0) continue; ret = wm831x_bulk_read(wm831x, WM831X_RTC_TIME_1, 2, time2); if (ret != 0) continue; if (memcmp(time1, time2, sizeof(time1)) == 0) { u32 time = (time1[0] << 16) | time1[1]; rtc_time64_to_tm(time, tm); return 0; } } while (++count < WM831X_GET_TIME_RETRIES); dev_err(dev, "Timed out reading current time\n"); return -EIO; }
/* Read the current time from the EC. */ static int cros_ec_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; int ret; u32 time; ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, &time); if (ret) { dev_err(dev, "error getting time: %d\n", ret); return ret; } rtc_time64_to_tm(time, tm); return 0; }
static int cmos_aie_poweroff(struct device *dev) { struct cmos_rtc *cmos = dev_get_drvdata(dev); struct rtc_time now; time64_t t_now; int retval = 0; unsigned char rtc_control; if (!cmos->alarm_expires) return -EINVAL; spin_lock_irq(&rtc_lock); rtc_control = CMOS_READ(RTC_CONTROL); spin_unlock_irq(&rtc_lock); /* We only care about the situation where AIE is disabled. */ if (rtc_control & RTC_AIE) return -EBUSY; cmos_read_time(dev, &now); t_now = rtc_tm_to_time64(&now); /* * When enabling "RTC wake-up" in BIOS setup, the machine reboots * automatically right after shutdown on some buggy boxes. * This automatic rebooting issue won't happen when the alarm * time is larger than now+1 seconds. * * If the alarm time is equal to now+1 seconds, the issue can be * prevented by cancelling the alarm. */ if (cmos->alarm_expires == t_now + 1) { struct rtc_wkalrm alarm; /* Cancel the AIE timer by configuring the past time. */ rtc_time64_to_tm(t_now - 1, &alarm.time); alarm.enabled = 0; retval = cmos_set_alarm(dev, &alarm); } else if (cmos->alarm_expires > t_now + 1) { retval = -EBUSY; } return retval; }
static void rtc_subtract_offset(struct rtc_device *rtc, struct rtc_time *tm) { time64_t secs; if (!rtc->offset_secs) return; secs = rtc_tm_to_time64(tm); /* * If the setting time values are in the valid range of RTC hardware * device, then no need to subtract the offset when setting time to RTC * device. Otherwise we need to subtract the offset to make the time * values are valid for RTC hardware device. */ if (secs >= rtc->range_min && secs <= rtc->range_max) return; rtc_time64_to_tm(secs - rtc->offset_secs, tm); }
static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned seconds, days; time64_t s1970; int enabled, pending; int ret; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds); if (unlikely(ret)) goto out; if (seconds >= SEC_PER_DAY) { ret = -ENODATA; goto out; } ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days); if (unlikely(ret)) goto out; ret = mc13xxx_irq_status(priv->mc13xxx, MC13XXX_IRQ_TODA, &enabled, &pending); out: mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; alarm->enabled = enabled; alarm->pending = pending; s1970 = (time64_t)days * SEC_PER_DAY + seconds; rtc_time64_to_tm(s1970, &alarm->time); dev_dbg(dev, "%s: %lld\n", __func__, (long long)s1970); return 0; }
static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct imx_sc_msg_timer_get_rtc_time msg; struct imx_sc_rpc_msg *hdr = &msg.hdr; int ret; hdr->ver = IMX_SC_RPC_VERSION; hdr->svc = IMX_SC_RPC_SVC_TIMER; hdr->func = IMX_SC_TIMER_FUNC_GET_RTC_SEC1970; hdr->size = 1; ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true); if (ret) { dev_err(dev, "read rtc time failed, ret %d\n", ret); return ret; } rtc_time64_to_tm(msg.time, tm); return 0; }
static void rtc_add_offset(struct rtc_device *rtc, struct rtc_time *tm) { time64_t secs; if (!rtc->offset_secs) return; secs = rtc_tm_to_time64(tm); /* * Since the reading time values from RTC device are always in the RTC * original valid range, but we need to skip the overlapped region * between expanded range and original range, which is no need to add * the offset. */ if ((rtc->start_secs > rtc->range_min && secs >= rtc->start_secs) || (rtc->start_secs < rtc->range_min && secs <= (rtc->start_secs + rtc->range_max - rtc->range_min))) return; rtc_time64_to_tm(secs + rtc->offset_secs, tm); }
static int st_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct st_rtc *rtc = dev_get_drvdata(dev); unsigned long lpt_lsb, lpt_msb; unsigned long long lpt; unsigned long flags; spin_lock_irqsave(&rtc->lock, flags); do { lpt_msb = readl_relaxed(rtc->ioaddr + LPC_LPT_MSB_OFF); lpt_lsb = readl_relaxed(rtc->ioaddr + LPC_LPT_LSB_OFF); } while (readl_relaxed(rtc->ioaddr + LPC_LPT_MSB_OFF) != lpt_msb); spin_unlock_irqrestore(&rtc->lock, flags); lpt = ((unsigned long long)lpt_msb << 32) | lpt_lsb; do_div(lpt, rtc->clkrate); rtc_time64_to_tm(lpt, tm); return 0; }
static int test_rtc_read_time(struct device *dev, struct rtc_time *tm) { rtc_time64_to_tm(ktime_get_real_seconds(), tm); return 0; }
static ssize_t wakealarm_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) { ssize_t retval; time64_t now, alarm; time64_t push = 0; struct rtc_wkalrm alm; struct rtc_device *rtc = to_rtc_device(dev); const char *buf_ptr; int adjust = 0; /* Only request alarms that trigger in the future. Disable them * by writing another time, e.g. 0 meaning Jan 1 1970 UTC. */ retval = rtc_read_time(rtc, &alm.time); if (retval < 0) return retval; now = rtc_tm_to_time64(&alm.time); buf_ptr = buf; if (*buf_ptr == '+') { buf_ptr++; if (*buf_ptr == '=') { buf_ptr++; push = 1; } else adjust = 1; } retval = kstrtos64(buf_ptr, 0, &alarm); if (retval) return retval; if (adjust) { alarm += now; } if (alarm > now || push) { /* Avoid accidentally clobbering active alarms; we can't * entirely prevent that here, without even the minimal * locking from the /dev/rtcN api. */ retval = rtc_read_alarm(rtc, &alm); if (retval < 0) return retval; if (alm.enabled) { if (push) { push = rtc_tm_to_time64(&alm.time); alarm += push; } else return -EBUSY; } else if (push) return -EINVAL; alm.enabled = 1; } else { alm.enabled = 0; /* Provide a valid future alarm time. Linux isn't EFI, * this time won't be ignored when disabling the alarm. */ alarm = now + 300; } rtc_time64_to_tm(alarm, &alm.time); retval = rtc_set_alarm(rtc, &alm); return (retval < 0) ? retval : n; }
int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { int err; struct rtc_time before, now; int first_time = 1; time64_t t_now, t_alm; enum { none, day, month, year } missing = none; unsigned days; /* The lower level RTC driver may return -1 in some fields, * creating invalid alarm->time values, for reasons like: * * - The hardware may not be capable of filling them in; * many alarms match only on time-of-day fields, not * day/month/year calendar data. * * - Some hardware uses illegal values as "wildcard" match * values, which non-Linux firmware (like a BIOS) may try * to set up as e.g. "alarm 15 minutes after each hour". * Linux uses only oneshot alarms. * * When we see that here, we deal with it by using values from * a current RTC timestamp for any missing (-1) values. The * RTC driver prevents "periodic alarm" modes. * * But this can be racey, because some fields of the RTC timestamp * may have wrapped in the interval since we read the RTC alarm, * which would lead to us inserting inconsistent values in place * of the -1 fields. * * Reading the alarm and timestamp in the reverse sequence * would have the same race condition, and not solve the issue. * * So, we must first read the RTC timestamp, * then read the RTC alarm value, * and then read a second RTC timestamp. * * If any fields of the second timestamp have changed * when compared with the first timestamp, then we know * our timestamp may be inconsistent with that used by * the low-level rtc_read_alarm_internal() function. * * So, when the two timestamps disagree, we just loop and do * the process again to get a fully consistent set of values. * * This could all instead be done in the lower level driver, * but since more than one lower level RTC implementation needs it, * then it's probably best best to do it here instead of there.. */ /* Get the "before" timestamp */ err = rtc_read_time(rtc, &before); if (err < 0) return err; do { if (!first_time) memcpy(&before, &now, sizeof(struct rtc_time)); first_time = 0; /* get the RTC alarm values, which may be incomplete */ err = rtc_read_alarm_internal(rtc, alarm); if (err) return err; /* full-function RTCs won't have such missing fields */ if (rtc_valid_tm(&alarm->time) == 0) { rtc_add_offset(rtc, &alarm->time); return 0; } /* get the "after" timestamp, to detect wrapped fields */ err = rtc_read_time(rtc, &now); if (err < 0) return err; /* note that tm_sec is a "don't care" value here: */ } while ( before.tm_min != now.tm_min || before.tm_hour != now.tm_hour || before.tm_mon != now.tm_mon || before.tm_year != now.tm_year); /* Fill in the missing alarm fields using the timestamp; we * know there's at least one since alarm->time is invalid. */ if (alarm->time.tm_sec == -1) alarm->time.tm_sec = now.tm_sec; if (alarm->time.tm_min == -1) alarm->time.tm_min = now.tm_min; if (alarm->time.tm_hour == -1) alarm->time.tm_hour = now.tm_hour; /* For simplicity, only support date rollover for now */ if (alarm->time.tm_mday < 1 || alarm->time.tm_mday > 31) { alarm->time.tm_mday = now.tm_mday; missing = day; } if ((unsigned)alarm->time.tm_mon >= 12) { alarm->time.tm_mon = now.tm_mon; if (missing == none) missing = month; } if (alarm->time.tm_year == -1) { alarm->time.tm_year = now.tm_year; if (missing == none) missing = year; } /* Can't proceed if alarm is still invalid after replacing * missing fields. */ err = rtc_valid_tm(&alarm->time); if (err) goto done; /* with luck, no rollover is needed */ t_now = rtc_tm_to_time64(&now); t_alm = rtc_tm_to_time64(&alarm->time); if (t_now < t_alm) goto done; switch (missing) { /* 24 hour rollover ... if it's now 10am Monday, an alarm that * that will trigger at 5am will do so at 5am Tuesday, which * could also be in the next month or year. This is a common * case, especially for PCs. */ case day: dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day"); t_alm += 24 * 60 * 60; rtc_time64_to_tm(t_alm, &alarm->time); break; /* Month rollover ... if it's the 31th, an alarm on the 3rd will * be next month. An alarm matching on the 30th, 29th, or 28th * may end up in the month after that! Many newer PCs support * this type of alarm. */ case month: dev_dbg(&rtc->dev, "alarm rollover: %s\n", "month"); do { if (alarm->time.tm_mon < 11) alarm->time.tm_mon++; else { alarm->time.tm_mon = 0; alarm->time.tm_year++; } days = rtc_month_days(alarm->time.tm_mon, alarm->time.tm_year); } while (days < alarm->time.tm_mday); break; /* Year rollover ... easy except for leap years! */ case year: dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); do { alarm->time.tm_year++; } while (!is_leap_year(alarm->time.tm_year + 1900) && rtc_valid_tm(&alarm->time) != 0); break; default: dev_warn(&rtc->dev, "alarm rollover not handled\n"); } err = rtc_valid_tm(&alarm->time); done: if (err) { dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n", alarm->time.tm_year + 1900, alarm->time.tm_mon + 1, alarm->time.tm_mday, alarm->time.tm_hour, alarm->time.tm_min, alarm->time.tm_sec); } return err; }
static void rockchip_to_gregorian(struct rtc_time *tm) { /* If it's Nov 31st, rtc_tm_to_time64() will count that like Dec 1st */ time64_t time = rtc_tm_to_time64(tm); rtc_time64_to_tm(time + nov2dec_transitions(tm) * 86400, tm); }