Lines Matching +full:cmos +full:- +full:compatible
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * RTC class driver for "CMOS RTC": PCs, ACPI, etc
10 * The original "cmos clock" chip was an MC146818 chip, now obsolete.
12 * non-PC systems, and incorporated into ACPI. Modern PC chipsets
46 /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
112 /*----------------------------------------------------------------*/
184 /*----------------------------------------------------------------*/
221 /*----------------------------------------------------------------*/
232 return -EIO; in cmos_read_time()
253 struct cmos_rtc *cmos; member
263 struct rtc_time *time = p->time; in cmos_read_alarm_callback()
265 time->tm_sec = CMOS_READ(RTC_SECONDS_ALARM); in cmos_read_alarm_callback()
266 time->tm_min = CMOS_READ(RTC_MINUTES_ALARM); in cmos_read_alarm_callback()
267 time->tm_hour = CMOS_READ(RTC_HOURS_ALARM); in cmos_read_alarm_callback()
269 if (p->cmos->day_alrm) { in cmos_read_alarm_callback()
271 time->tm_mday = CMOS_READ(p->cmos->day_alrm) & 0x3f; in cmos_read_alarm_callback()
272 if (!time->tm_mday) in cmos_read_alarm_callback()
273 time->tm_mday = -1; in cmos_read_alarm_callback()
275 if (p->cmos->mon_alrm) { in cmos_read_alarm_callback()
276 time->tm_mon = CMOS_READ(p->cmos->mon_alrm); in cmos_read_alarm_callback()
277 if (!time->tm_mon) in cmos_read_alarm_callback()
278 time->tm_mon = -1; in cmos_read_alarm_callback()
282 p->rtc_control = CMOS_READ(RTC_CONTROL); in cmos_read_alarm_callback()
287 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_read_alarm() local
289 .cmos = cmos, in cmos_read_alarm()
290 .time = &t->time, in cmos_read_alarm()
294 if (!is_valid_irq(cmos->irq)) in cmos_read_alarm()
295 return -ETIMEDOUT; in cmos_read_alarm()
303 * update is in progress - during this time reads return bogus values in cmos_read_alarm()
311 return -EIO; in cmos_read_alarm()
314 if (((unsigned)t->time.tm_sec) < 0x60) in cmos_read_alarm()
315 t->time.tm_sec = bcd2bin(t->time.tm_sec); in cmos_read_alarm()
317 t->time.tm_sec = -1; in cmos_read_alarm()
318 if (((unsigned)t->time.tm_min) < 0x60) in cmos_read_alarm()
319 t->time.tm_min = bcd2bin(t->time.tm_min); in cmos_read_alarm()
321 t->time.tm_min = -1; in cmos_read_alarm()
322 if (((unsigned)t->time.tm_hour) < 0x24) in cmos_read_alarm()
323 t->time.tm_hour = bcd2bin(t->time.tm_hour); in cmos_read_alarm()
325 t->time.tm_hour = -1; in cmos_read_alarm()
327 if (cmos->day_alrm) { in cmos_read_alarm()
328 if (((unsigned)t->time.tm_mday) <= 0x31) in cmos_read_alarm()
329 t->time.tm_mday = bcd2bin(t->time.tm_mday); in cmos_read_alarm()
331 t->time.tm_mday = -1; in cmos_read_alarm()
333 if (cmos->mon_alrm) { in cmos_read_alarm()
334 if (((unsigned)t->time.tm_mon) <= 0x12) in cmos_read_alarm()
335 t->time.tm_mon = bcd2bin(t->time.tm_mon)-1; in cmos_read_alarm()
337 t->time.tm_mon = -1; in cmos_read_alarm()
342 t->enabled = !!(p.rtc_control & RTC_AIE); in cmos_read_alarm()
343 t->pending = 0; in cmos_read_alarm()
348 static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control) in cmos_checkintr() argument
362 rtc_update_irq(cmos->rtc, 1, rtc_intr); in cmos_checkintr()
365 static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask) in cmos_irq_enable() argument
373 cmos_checkintr(cmos, rtc_control); in cmos_irq_enable()
381 if (cmos->wake_on) in cmos_irq_enable()
382 cmos->wake_on(cmos->dev); in cmos_irq_enable()
385 cmos_checkintr(cmos, rtc_control); in cmos_irq_enable()
388 static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) in cmos_irq_disable() argument
399 if (cmos->wake_off) in cmos_irq_disable()
400 cmos->wake_off(cmos->dev); in cmos_irq_disable()
403 cmos_checkintr(cmos, rtc_control); in cmos_irq_disable()
408 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_validate_alarm() local
413 if (!cmos->day_alrm) { in cmos_validate_alarm()
418 t_max_date += 24 * 60 * 60 - 1; in cmos_validate_alarm()
419 t_alrm = rtc_tm_to_time64(&t->time); in cmos_validate_alarm()
423 return -EINVAL; in cmos_validate_alarm()
425 } else if (!cmos->mon_alrm) { in cmos_validate_alarm()
442 t_max_date -= 1; in cmos_validate_alarm()
443 t_alrm = rtc_tm_to_time64(&t->time); in cmos_validate_alarm()
447 return -EINVAL; in cmos_validate_alarm()
461 t_max_date -= 1; in cmos_validate_alarm()
462 t_alrm = rtc_tm_to_time64(&t->time); in cmos_validate_alarm()
466 return -EINVAL; in cmos_validate_alarm()
474 struct cmos_rtc *cmos; member
489 cmos_irq_disable(p->cmos, RTC_AIE); in cmos_set_alarm_callback()
492 CMOS_WRITE(p->hrs, RTC_HOURS_ALARM); in cmos_set_alarm_callback()
493 CMOS_WRITE(p->min, RTC_MINUTES_ALARM); in cmos_set_alarm_callback()
494 CMOS_WRITE(p->sec, RTC_SECONDS_ALARM); in cmos_set_alarm_callback()
497 if (p->cmos->day_alrm) { in cmos_set_alarm_callback()
498 CMOS_WRITE(p->mday, p->cmos->day_alrm); in cmos_set_alarm_callback()
499 if (p->cmos->mon_alrm) in cmos_set_alarm_callback()
500 CMOS_WRITE(p->mon, p->cmos->mon_alrm); in cmos_set_alarm_callback()
508 hpet_set_alarm_time(p->t->time.tm_hour, p->t->time.tm_min, in cmos_set_alarm_callback()
509 p->t->time.tm_sec); in cmos_set_alarm_callback()
512 if (p->t->enabled) in cmos_set_alarm_callback()
513 cmos_irq_enable(p->cmos, RTC_AIE); in cmos_set_alarm_callback()
518 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_set_alarm() local
520 .cmos = cmos, in cmos_set_alarm()
527 if (!is_valid_irq(cmos->irq)) in cmos_set_alarm()
528 return -EIO; in cmos_set_alarm()
534 p.mon = t->time.tm_mon + 1; in cmos_set_alarm()
535 p.mday = t->time.tm_mday; in cmos_set_alarm()
536 p.hrs = t->time.tm_hour; in cmos_set_alarm()
537 p.min = t->time.tm_min; in cmos_set_alarm()
538 p.sec = t->time.tm_sec; in cmos_set_alarm()
555 * update is in progress - during this time writes fail silently. in cmos_set_alarm()
560 return -ETIMEDOUT; in cmos_set_alarm()
562 cmos->alarm_expires = rtc_tm_to_time64(&t->time); in cmos_set_alarm()
569 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_alarm_irq_enable() local
575 cmos_irq_enable(cmos, RTC_AIE); in cmos_alarm_irq_enable()
577 cmos_irq_disable(cmos, RTC_AIE); in cmos_alarm_irq_enable()
587 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_procfs() local
596 * (non-RTC) bit; and SQWE is ignored on many current systems. in cmos_procfs()
613 cmos->rtc->irq_freq, in cmos_procfs()
632 /*----------------------------------------------------------------*/
649 for (; count; count--, off++) { in cmos_nvram_read()
659 return count ? -EIO : 0; in cmos_nvram_read()
665 struct cmos_rtc *cmos = priv; in cmos_nvram_write() local
675 for (; count; count--, off++) { in cmos_nvram_write()
677 if (off == cmos->day_alrm in cmos_nvram_write()
678 || off == cmos->mon_alrm in cmos_nvram_write()
679 || off == cmos->century) in cmos_nvram_write()
690 return count ? -EIO : 0; in cmos_nvram_write()
693 /*----------------------------------------------------------------*/
752 struct cmos_rtc *cmos = dev_get_drvdata(dev); in rtc_handler() local
764 cmos_interrupt(0, (void *)cmos->rtc); in rtc_handler()
774 rtc_update_irq(cmos->rtc, 1, rtc_intr); in rtc_handler()
874 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_check_acpi_rtc_status() local
889 rtc_update_irq(cmos->rtc, 1, mask); in cmos_check_acpi_rtc_status()
943 return -EBUSY; in cmos_do_probe()
946 return -ENODEV; in cmos_do_probe()
950 * REVISIT non-x86 systems may instead use memory space resources in cmos_do_probe()
954 ports = request_region(ports->start, resource_size(ports), in cmos_do_probe()
957 ports = request_mem_region(ports->start, resource_size(ports), in cmos_do_probe()
961 return -EBUSY; in cmos_do_probe()
982 if (can_bank2 && ports->end > (ports->start + 1)) in cmos_do_probe()
988 * some almost-clones) can provide hooks to make that behave. in cmos_do_probe()
995 if (info->flags) in cmos_do_probe()
996 flags = info->flags; in cmos_do_probe()
997 if (info->address_space) in cmos_do_probe()
998 address_space = info->address_space; in cmos_do_probe()
1000 cmos_rtc.day_alrm = info->rtc_day_alarm; in cmos_do_probe()
1001 cmos_rtc.mon_alrm = info->rtc_mon_alarm; in cmos_do_probe()
1002 cmos_rtc.century = info->rtc_century; in cmos_do_probe()
1004 if (info->wake_on && info->wake_off) { in cmos_do_probe()
1005 cmos_rtc.wake_on = info->wake_on; in cmos_do_probe()
1006 cmos_rtc.wake_off = info->wake_off; in cmos_do_probe()
1031 cmos_rtc.rtc->alarm_offset_max = SECS_PER_YEAR - 1; in cmos_do_probe()
1033 cmos_rtc.rtc->alarm_offset_max = SECS_PER_MONTH - 1; in cmos_do_probe()
1035 cmos_rtc.rtc->alarm_offset_max = SECS_PER_DAY - 1; in cmos_do_probe()
1037 rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); in cmos_do_probe()
1041 retval = -ENXIO; in cmos_do_probe()
1048 /* force periodic irq to CMOS reset default of 1024Hz; in cmos_do_probe()
1054 cmos_rtc.rtc->irq_freq = 1024; in cmos_do_probe()
1056 hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); in cmos_do_probe()
1069 dev_warn(dev, "only 24-hr supported\n"); in cmos_do_probe()
1070 retval = -ENXIO; in cmos_do_probe()
1093 0, dev_name(&cmos_rtc.rtc->dev), in cmos_do_probe()
1100 clear_bit(RTC_FEATURE_ALARM, cmos_rtc.rtc->features); in cmos_do_probe()
1103 cmos_rtc.rtc->ops = &cmos_rtc_ops; in cmos_do_probe()
1110 cmos_rtc.rtc->set_offset_nsec = NSEC_PER_SEC / 2; in cmos_do_probe()
1113 nvmem_cfg.size = address_space - NVRAM_OFFSET; in cmos_do_probe()
1141 release_region(ports->start, resource_size(ports)); in cmos_do_probe()
1143 release_mem_region(ports->start, resource_size(ports)); in cmos_do_probe()
1157 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_do_remove() local
1160 cmos_do_shutdown(cmos->irq); in cmos_do_remove()
1162 if (is_valid_irq(cmos->irq)) { in cmos_do_remove()
1163 free_irq(cmos->irq, cmos->rtc); in cmos_do_remove()
1171 cmos->rtc = NULL; in cmos_do_remove()
1173 ports = cmos->iomem; in cmos_do_remove()
1175 release_region(ports->start, resource_size(ports)); in cmos_do_remove()
1177 release_mem_region(ports->start, resource_size(ports)); in cmos_do_remove()
1178 cmos->iomem = NULL; in cmos_do_remove()
1180 cmos->dev = NULL; in cmos_do_remove()
1185 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_aie_poweroff() local
1191 if (!cmos->alarm_expires) in cmos_aie_poweroff()
1192 return -EINVAL; in cmos_aie_poweroff()
1200 return -EBUSY; in cmos_aie_poweroff()
1206 * When enabling "RTC wake-up" in BIOS setup, the machine reboots in cmos_aie_poweroff()
1214 if (cmos->alarm_expires == t_now + 1) { in cmos_aie_poweroff()
1218 rtc_time64_to_tm(t_now - 1, &alarm.time); in cmos_aie_poweroff()
1221 } else if (cmos->alarm_expires > t_now + 1) { in cmos_aie_poweroff()
1222 retval = -EBUSY; in cmos_aie_poweroff()
1230 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_suspend() local
1235 cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); in cmos_suspend()
1247 cmos_checkintr(cmos, tmp); in cmos_suspend()
1252 cmos->enabled_wake = 1; in cmos_suspend()
1253 if (cmos->wake_on) in cmos_suspend()
1254 cmos->wake_on(dev); in cmos_suspend()
1256 enable_irq_wake(cmos->irq); in cmos_suspend()
1259 memset(&cmos->saved_wkalrm, 0, sizeof(struct rtc_wkalrm)); in cmos_suspend()
1260 cmos_read_alarm(dev, &cmos->saved_wkalrm); in cmos_suspend()
1278 return -ENOSYS; in cmos_poweroff()
1285 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_check_wkalrm() local
1293 if (!(cmos->suspend_ctrl & RTC_AIE)) in cmos_check_wkalrm()
1303 if (t_now >= cmos->alarm_expires && cmos_use_acpi_alarm()) { in cmos_check_wkalrm()
1305 cmos_interrupt(0, (void *)cmos->rtc); in cmos_check_wkalrm()
1313 t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time); in cmos_check_wkalrm()
1315 cmos->saved_wkalrm.enabled != current_alarm.enabled) { in cmos_check_wkalrm()
1316 cmos_set_alarm(dev, &cmos->saved_wkalrm); in cmos_check_wkalrm()
1322 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_resume() local
1325 if (cmos->enabled_wake && !cmos_use_acpi_alarm()) { in cmos_resume()
1326 if (cmos->wake_off) in cmos_resume()
1327 cmos->wake_off(dev); in cmos_resume()
1329 disable_irq_wake(cmos->irq); in cmos_resume()
1330 cmos->enabled_wake = 0; in cmos_resume()
1337 tmp = cmos->suspend_ctrl; in cmos_resume()
1338 cmos->suspend_ctrl = 0; in cmos_resume()
1339 /* re-enable any irqs previously active */ in cmos_resume()
1356 /* force one-shot behavior if HPET blocked in cmos_resume()
1359 rtc_update_irq(cmos->rtc, 1, mask); in cmos_resume()
1376 /*----------------------------------------------------------------*/
1378 /* On non-x86 systems, a "CMOS" RTC lives most naturally on platform_bus.
1379 * ACPI systems always list these as PNPACPI devices, and pre-ACPI PCs
1408 return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq); in cmos_pnp_probe()
1413 cmos_do_remove(&pnp->dev); in cmos_pnp_remove()
1418 struct device *dev = &pnp->dev; in cmos_pnp_shutdown()
1419 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_pnp_shutdown() local
1428 cmos_do_shutdown(cmos->irq); in cmos_pnp_shutdown()
1458 .compatible = "motorola,mc146818",
1466 struct device_node *node = pdev->dev.of_node; in cmos_of_init()
1472 val = of_get_property(node, "ctrl-reg", NULL); in cmos_of_init()
1476 val = of_get_property(node, "freq-reg", NULL); in cmos_of_init()
1483 /*----------------------------------------------------------------*/
1502 irq = -1; in cmos_platform_probe()
1504 return cmos_do_probe(&pdev->dev, resource, irq); in cmos_platform_probe()
1509 cmos_do_remove(&pdev->dev); in cmos_platform_remove()
1514 struct device *dev = &pdev->dev; in cmos_platform_shutdown()
1515 struct cmos_rtc *cmos = dev_get_drvdata(dev); in cmos_platform_shutdown() local
1524 cmos_do_shutdown(cmos->irq); in cmos_platform_shutdown()
1586 MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs");