Lines Matching +full:lpc +full:- +full:ctrl

1 // SPDX-License-Identifier: GPL-2.0-or-later
12 * non-PC systems, and incorporated into ACPI. Modern PC chipsets
15 * are also clones that connect using the LPC bus.
46 /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
112 /*----------------------------------------------------------------*/
179 /*----------------------------------------------------------------*/
216 /*----------------------------------------------------------------*/
227 return -EIO; in cmos_read_time()
258 struct rtc_time *time = p->time; in cmos_read_alarm_callback()
260 time->tm_sec = CMOS_READ(RTC_SECONDS_ALARM); in cmos_read_alarm_callback()
261 time->tm_min = CMOS_READ(RTC_MINUTES_ALARM); in cmos_read_alarm_callback()
262 time->tm_hour = CMOS_READ(RTC_HOURS_ALARM); in cmos_read_alarm_callback()
264 if (p->cmos->day_alrm) { in cmos_read_alarm_callback()
266 time->tm_mday = CMOS_READ(p->cmos->day_alrm) & 0x3f; in cmos_read_alarm_callback()
267 if (!time->tm_mday) in cmos_read_alarm_callback()
268 time->tm_mday = -1; in cmos_read_alarm_callback()
270 if (p->cmos->mon_alrm) { in cmos_read_alarm_callback()
271 time->tm_mon = CMOS_READ(p->cmos->mon_alrm); in cmos_read_alarm_callback()
272 if (!time->tm_mon) in cmos_read_alarm_callback()
273 time->tm_mon = -1; in cmos_read_alarm_callback()
277 p->rtc_control = CMOS_READ(RTC_CONTROL); in cmos_read_alarm_callback()
285 .time = &t->time, in cmos_read_alarm()
289 if (!is_valid_irq(cmos->irq)) in cmos_read_alarm()
290 return -ETIMEDOUT; in cmos_read_alarm()
298 * update is in progress - during this time reads return bogus values in cmos_read_alarm()
306 return -EIO; in cmos_read_alarm()
309 if (((unsigned)t->time.tm_sec) < 0x60) in cmos_read_alarm()
310 t->time.tm_sec = bcd2bin(t->time.tm_sec); in cmos_read_alarm()
312 t->time.tm_sec = -1; in cmos_read_alarm()
313 if (((unsigned)t->time.tm_min) < 0x60) in cmos_read_alarm()
314 t->time.tm_min = bcd2bin(t->time.tm_min); in cmos_read_alarm()
316 t->time.tm_min = -1; in cmos_read_alarm()
317 if (((unsigned)t->time.tm_hour) < 0x24) in cmos_read_alarm()
318 t->time.tm_hour = bcd2bin(t->time.tm_hour); in cmos_read_alarm()
320 t->time.tm_hour = -1; in cmos_read_alarm()
322 if (cmos->day_alrm) { in cmos_read_alarm()
323 if (((unsigned)t->time.tm_mday) <= 0x31) in cmos_read_alarm()
324 t->time.tm_mday = bcd2bin(t->time.tm_mday); in cmos_read_alarm()
326 t->time.tm_mday = -1; in cmos_read_alarm()
328 if (cmos->mon_alrm) { in cmos_read_alarm()
329 if (((unsigned)t->time.tm_mon) <= 0x12) in cmos_read_alarm()
330 t->time.tm_mon = bcd2bin(t->time.tm_mon)-1; in cmos_read_alarm()
332 t->time.tm_mon = -1; in cmos_read_alarm()
337 t->enabled = !!(p.rtc_control & RTC_AIE); in cmos_read_alarm()
338 t->pending = 0; in cmos_read_alarm()
357 rtc_update_irq(cmos->rtc, 1, rtc_intr); in cmos_checkintr()
376 if (cmos->wake_on) in cmos_irq_enable()
377 cmos->wake_on(cmos->dev); in cmos_irq_enable()
394 if (cmos->wake_off) in cmos_irq_disable()
395 cmos->wake_off(cmos->dev); in cmos_irq_disable()
408 if (!cmos->day_alrm) { in cmos_validate_alarm()
413 t_max_date += 24 * 60 * 60 - 1; in cmos_validate_alarm()
414 t_alrm = rtc_tm_to_time64(&t->time); in cmos_validate_alarm()
418 return -EINVAL; in cmos_validate_alarm()
420 } else if (!cmos->mon_alrm) { in cmos_validate_alarm()
437 t_max_date -= 1; in cmos_validate_alarm()
438 t_alrm = rtc_tm_to_time64(&t->time); in cmos_validate_alarm()
442 return -EINVAL; in cmos_validate_alarm()
456 t_max_date -= 1; in cmos_validate_alarm()
457 t_alrm = rtc_tm_to_time64(&t->time); in cmos_validate_alarm()
461 return -EINVAL; in cmos_validate_alarm()
484 cmos_irq_disable(p->cmos, RTC_AIE); in cmos_set_alarm_callback()
487 CMOS_WRITE(p->hrs, RTC_HOURS_ALARM); in cmos_set_alarm_callback()
488 CMOS_WRITE(p->min, RTC_MINUTES_ALARM); in cmos_set_alarm_callback()
489 CMOS_WRITE(p->sec, RTC_SECONDS_ALARM); in cmos_set_alarm_callback()
492 if (p->cmos->day_alrm) { in cmos_set_alarm_callback()
493 CMOS_WRITE(p->mday, p->cmos->day_alrm); in cmos_set_alarm_callback()
494 if (p->cmos->mon_alrm) in cmos_set_alarm_callback()
495 CMOS_WRITE(p->mon, p->cmos->mon_alrm); in cmos_set_alarm_callback()
503 hpet_set_alarm_time(p->t->time.tm_hour, p->t->time.tm_min, in cmos_set_alarm_callback()
504 p->t->time.tm_sec); in cmos_set_alarm_callback()
507 if (p->t->enabled) in cmos_set_alarm_callback()
508 cmos_irq_enable(p->cmos, RTC_AIE); in cmos_set_alarm_callback()
522 if (!is_valid_irq(cmos->irq)) in cmos_set_alarm()
523 return -EIO; in cmos_set_alarm()
529 p.mon = t->time.tm_mon + 1; in cmos_set_alarm()
530 p.mday = t->time.tm_mday; in cmos_set_alarm()
531 p.hrs = t->time.tm_hour; in cmos_set_alarm()
532 p.min = t->time.tm_min; in cmos_set_alarm()
533 p.sec = t->time.tm_sec; in cmos_set_alarm()
550 * update is in progress - during this time writes fail silently. in cmos_set_alarm()
555 return -ETIMEDOUT; in cmos_set_alarm()
557 cmos->alarm_expires = rtc_tm_to_time64(&t->time); in cmos_set_alarm()
591 * (non-RTC) bit; and SQWE is ignored on many current systems. in cmos_procfs()
608 cmos->rtc->irq_freq, in cmos_procfs()
627 /*----------------------------------------------------------------*/
643 for (; count; count--, off++, buf++) { in cmos_nvram_read()
650 return -EIO; in cmos_nvram_read()
668 for (; count; count--, off++, buf++) { in cmos_nvram_write()
670 if (off == cmos->day_alrm in cmos_nvram_write()
671 || off == cmos->mon_alrm in cmos_nvram_write()
672 || off == cmos->century) in cmos_nvram_write()
681 return -EIO; in cmos_nvram_write()
687 /*----------------------------------------------------------------*/
698 * in a non-irq context. in cmos_interrupt()
762 cmos_interrupt(0, (void *)cmos->rtc); in rtc_handler()
772 rtc_update_irq(cmos->rtc, 1, rtc_intr); in rtc_handler()
887 rtc_update_irq(cmos->rtc, 1, mask); in cmos_check_acpi_rtc_status()
941 return -EBUSY; in cmos_do_probe()
944 return -ENODEV; in cmos_do_probe()
948 * REVISIT non-x86 systems may instead use memory space resources in cmos_do_probe()
952 ports = request_region(ports->start, resource_size(ports), in cmos_do_probe()
955 ports = request_mem_region(ports->start, resource_size(ports), in cmos_do_probe()
959 return -EBUSY; in cmos_do_probe()
980 if (can_bank2 && ports->end > (ports->start + 1)) in cmos_do_probe()
986 * some almost-clones) can provide hooks to make that behave. in cmos_do_probe()
993 if (info->flags) in cmos_do_probe()
994 flags = info->flags; in cmos_do_probe()
995 if (info->address_space) in cmos_do_probe()
996 address_space = info->address_space; in cmos_do_probe()
998 cmos_rtc.day_alrm = info->rtc_day_alarm; in cmos_do_probe()
999 cmos_rtc.mon_alrm = info->rtc_mon_alarm; in cmos_do_probe()
1000 cmos_rtc.century = info->rtc_century; in cmos_do_probe()
1002 if (info->wake_on && info->wake_off) { in cmos_do_probe()
1003 cmos_rtc.wake_on = info->wake_on; in cmos_do_probe()
1004 cmos_rtc.wake_off = info->wake_off; in cmos_do_probe()
1029 cmos_rtc.rtc->alarm_offset_max = SECS_PER_YEAR - 1; in cmos_do_probe()
1031 cmos_rtc.rtc->alarm_offset_max = SECS_PER_MONTH - 1; in cmos_do_probe()
1033 cmos_rtc.rtc->alarm_offset_max = SECS_PER_DAY - 1; in cmos_do_probe()
1035 rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); in cmos_do_probe()
1039 retval = -ENXIO; in cmos_do_probe()
1052 cmos_rtc.rtc->irq_freq = 1024; in cmos_do_probe()
1054 hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); in cmos_do_probe()
1067 dev_warn(dev, "only 24-hr supported\n"); in cmos_do_probe()
1068 retval = -ENXIO; in cmos_do_probe()
1091 0, dev_name(&cmos_rtc.rtc->dev), in cmos_do_probe()
1098 clear_bit(RTC_FEATURE_ALARM, cmos_rtc.rtc->features); in cmos_do_probe()
1101 cmos_rtc.rtc->ops = &cmos_rtc_ops; in cmos_do_probe()
1108 cmos_rtc.rtc->set_offset_nsec = NSEC_PER_SEC / 2; in cmos_do_probe()
1111 nvmem_cfg.size = address_space - NVRAM_OFFSET; in cmos_do_probe()
1139 release_region(ports->start, resource_size(ports)); in cmos_do_probe()
1141 release_mem_region(ports->start, resource_size(ports)); in cmos_do_probe()
1158 cmos_do_shutdown(cmos->irq); in cmos_do_remove()
1160 if (is_valid_irq(cmos->irq)) { in cmos_do_remove()
1161 free_irq(cmos->irq, cmos->rtc); in cmos_do_remove()
1169 cmos->rtc = NULL; in cmos_do_remove()
1171 ports = cmos->iomem; in cmos_do_remove()
1173 release_region(ports->start, resource_size(ports)); in cmos_do_remove()
1175 release_mem_region(ports->start, resource_size(ports)); in cmos_do_remove()
1176 cmos->iomem = NULL; in cmos_do_remove()
1178 cmos->dev = NULL; in cmos_do_remove()
1189 if (!cmos->alarm_expires) in cmos_aie_poweroff()
1190 return -EINVAL; in cmos_aie_poweroff()
1198 return -EBUSY; in cmos_aie_poweroff()
1204 * When enabling "RTC wake-up" in BIOS setup, the machine reboots in cmos_aie_poweroff()
1212 if (cmos->alarm_expires == t_now + 1) { in cmos_aie_poweroff()
1216 rtc_time64_to_tm(t_now - 1, &alarm.time); in cmos_aie_poweroff()
1219 } else if (cmos->alarm_expires > t_now + 1) { in cmos_aie_poweroff()
1220 retval = -EBUSY; in cmos_aie_poweroff()
1233 cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); in cmos_suspend()
1250 cmos->enabled_wake = 1; in cmos_suspend()
1251 if (cmos->wake_on) in cmos_suspend()
1252 cmos->wake_on(dev); in cmos_suspend()
1254 enable_irq_wake(cmos->irq); in cmos_suspend()
1257 memset(&cmos->saved_wkalrm, 0, sizeof(struct rtc_wkalrm)); in cmos_suspend()
1258 cmos_read_alarm(dev, &cmos->saved_wkalrm); in cmos_suspend()
1260 dev_dbg(dev, "suspend%s, ctrl %02x\n", in cmos_suspend()
1276 return -ENOSYS; in cmos_poweroff()
1291 if (!(cmos->suspend_ctrl & RTC_AIE)) in cmos_check_wkalrm()
1301 if (t_now >= cmos->alarm_expires && cmos_use_acpi_alarm()) { in cmos_check_wkalrm()
1302 cmos_interrupt(0, (void *)cmos->rtc); in cmos_check_wkalrm()
1309 t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time); in cmos_check_wkalrm()
1311 cmos->saved_wkalrm.enabled != current_alarm.enabled) { in cmos_check_wkalrm()
1312 cmos_set_alarm(dev, &cmos->saved_wkalrm); in cmos_check_wkalrm()
1321 if (cmos->enabled_wake && !cmos_use_acpi_alarm()) { in cmos_resume()
1322 if (cmos->wake_off) in cmos_resume()
1323 cmos->wake_off(dev); in cmos_resume()
1325 disable_irq_wake(cmos->irq); in cmos_resume()
1326 cmos->enabled_wake = 0; in cmos_resume()
1333 tmp = cmos->suspend_ctrl; in cmos_resume()
1334 cmos->suspend_ctrl = 0; in cmos_resume()
1335 /* re-enable any irqs previously active */ in cmos_resume()
1352 /* force one-shot behavior if HPET blocked in cmos_resume()
1355 rtc_update_irq(cmos->rtc, 1, mask); in cmos_resume()
1365 dev_dbg(dev, "resume, ctrl %02x\n", tmp); in cmos_resume()
1372 /*----------------------------------------------------------------*/
1374 /* On non-x86 systems, a "CMOS" RTC lives most naturally on platform_bus.
1375 * ACPI systems always list these as PNPACPI devices, and pre-ACPI PCs
1404 return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq); in cmos_pnp_probe()
1409 cmos_do_remove(&pnp->dev); in cmos_pnp_remove()
1414 struct device *dev = &pnp->dev; in cmos_pnp_shutdown()
1424 cmos_do_shutdown(cmos->irq); in cmos_pnp_shutdown()
1462 struct device_node *node = pdev->dev.of_node; in cmos_of_init()
1468 val = of_get_property(node, "ctrl-reg", NULL); in cmos_of_init()
1472 val = of_get_property(node, "freq-reg", NULL); in cmos_of_init()
1479 /*----------------------------------------------------------------*/
1498 irq = -1; in cmos_platform_probe()
1500 return cmos_do_probe(&pdev->dev, resource, irq); in cmos_platform_probe()
1505 cmos_do_remove(&pdev->dev); in cmos_platform_remove()
1510 struct device *dev = &pdev->dev; in cmos_platform_shutdown()
1520 cmos_do_shutdown(cmos->irq); in cmos_platform_shutdown()
1582 MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs");