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 /*----------------------------------------------------------------*/
758 cmos_interrupt(0, (void *)cmos->rtc); in rtc_handler()
768 rtc_update_irq(cmos->rtc, 1, rtc_intr); in rtc_handler()
883 rtc_update_irq(cmos->rtc, 1, mask); in cmos_check_acpi_rtc_status()
937 return -EBUSY; in cmos_do_probe()
940 return -ENODEV; in cmos_do_probe()
944 * REVISIT non-x86 systems may instead use memory space resources in cmos_do_probe()
948 ports = request_region(ports->start, resource_size(ports), in cmos_do_probe()
951 ports = request_mem_region(ports->start, resource_size(ports), in cmos_do_probe()
955 return -EBUSY; in cmos_do_probe()
976 if (can_bank2 && ports->end > (ports->start + 1)) in cmos_do_probe()
982 * some almost-clones) can provide hooks to make that behave. in cmos_do_probe()
989 if (info->flags) in cmos_do_probe()
990 flags = info->flags; in cmos_do_probe()
991 if (info->address_space) in cmos_do_probe()
992 address_space = info->address_space; in cmos_do_probe()
994 cmos_rtc.day_alrm = info->rtc_day_alarm; in cmos_do_probe()
995 cmos_rtc.mon_alrm = info->rtc_mon_alarm; in cmos_do_probe()
996 cmos_rtc.century = info->rtc_century; in cmos_do_probe()
998 if (info->wake_on && info->wake_off) { in cmos_do_probe()
999 cmos_rtc.wake_on = info->wake_on; in cmos_do_probe()
1000 cmos_rtc.wake_off = info->wake_off; in cmos_do_probe()
1025 cmos_rtc.rtc->alarm_offset_max = SECS_PER_YEAR - 1; in cmos_do_probe()
1027 cmos_rtc.rtc->alarm_offset_max = SECS_PER_MONTH - 1; in cmos_do_probe()
1029 cmos_rtc.rtc->alarm_offset_max = SECS_PER_DAY - 1; in cmos_do_probe()
1031 rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); in cmos_do_probe()
1035 retval = -ENXIO; in cmos_do_probe()
1048 cmos_rtc.rtc->irq_freq = 1024; in cmos_do_probe()
1050 hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); in cmos_do_probe()
1063 dev_warn(dev, "only 24-hr supported\n"); in cmos_do_probe()
1064 retval = -ENXIO; in cmos_do_probe()
1087 0, dev_name(&cmos_rtc.rtc->dev), in cmos_do_probe()
1094 clear_bit(RTC_FEATURE_ALARM, cmos_rtc.rtc->features); in cmos_do_probe()
1097 cmos_rtc.rtc->ops = &cmos_rtc_ops; in cmos_do_probe()
1104 cmos_rtc.rtc->set_offset_nsec = NSEC_PER_SEC / 2; in cmos_do_probe()
1107 nvmem_cfg.size = address_space - NVRAM_OFFSET; in cmos_do_probe()
1135 release_region(ports->start, resource_size(ports)); in cmos_do_probe()
1137 release_mem_region(ports->start, resource_size(ports)); in cmos_do_probe()
1154 cmos_do_shutdown(cmos->irq); in cmos_do_remove()
1156 if (is_valid_irq(cmos->irq)) { in cmos_do_remove()
1157 free_irq(cmos->irq, cmos->rtc); in cmos_do_remove()
1165 cmos->rtc = NULL; in cmos_do_remove()
1167 ports = cmos->iomem; in cmos_do_remove()
1169 release_region(ports->start, resource_size(ports)); in cmos_do_remove()
1171 release_mem_region(ports->start, resource_size(ports)); in cmos_do_remove()
1172 cmos->iomem = NULL; in cmos_do_remove()
1174 cmos->dev = NULL; in cmos_do_remove()
1185 if (!cmos->alarm_expires) in cmos_aie_poweroff()
1186 return -EINVAL; in cmos_aie_poweroff()
1194 return -EBUSY; in cmos_aie_poweroff()
1200 * When enabling "RTC wake-up" in BIOS setup, the machine reboots in cmos_aie_poweroff()
1208 if (cmos->alarm_expires == t_now + 1) { in cmos_aie_poweroff()
1212 rtc_time64_to_tm(t_now - 1, &alarm.time); in cmos_aie_poweroff()
1215 } else if (cmos->alarm_expires > t_now + 1) { in cmos_aie_poweroff()
1216 retval = -EBUSY; in cmos_aie_poweroff()
1229 cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); in cmos_suspend()
1246 cmos->enabled_wake = 1; in cmos_suspend()
1247 if (cmos->wake_on) in cmos_suspend()
1248 cmos->wake_on(dev); in cmos_suspend()
1250 enable_irq_wake(cmos->irq); in cmos_suspend()
1253 memset(&cmos->saved_wkalrm, 0, sizeof(struct rtc_wkalrm)); in cmos_suspend()
1254 cmos_read_alarm(dev, &cmos->saved_wkalrm); in cmos_suspend()
1256 dev_dbg(dev, "suspend%s, ctrl %02x\n", in cmos_suspend()
1272 return -ENOSYS; in cmos_poweroff()
1287 if (!(cmos->suspend_ctrl & RTC_AIE)) in cmos_check_wkalrm()
1297 if (t_now >= cmos->alarm_expires && cmos_use_acpi_alarm()) { in cmos_check_wkalrm()
1299 cmos_interrupt(0, (void *)cmos->rtc); in cmos_check_wkalrm()
1307 t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time); in cmos_check_wkalrm()
1309 cmos->saved_wkalrm.enabled != current_alarm.enabled) { in cmos_check_wkalrm()
1310 cmos_set_alarm(dev, &cmos->saved_wkalrm); in cmos_check_wkalrm()
1319 if (cmos->enabled_wake && !cmos_use_acpi_alarm()) { in cmos_resume()
1320 if (cmos->wake_off) in cmos_resume()
1321 cmos->wake_off(dev); in cmos_resume()
1323 disable_irq_wake(cmos->irq); in cmos_resume()
1324 cmos->enabled_wake = 0; in cmos_resume()
1331 tmp = cmos->suspend_ctrl; in cmos_resume()
1332 cmos->suspend_ctrl = 0; in cmos_resume()
1333 /* re-enable any irqs previously active */ in cmos_resume()
1350 /* force one-shot behavior if HPET blocked in cmos_resume()
1353 rtc_update_irq(cmos->rtc, 1, mask); in cmos_resume()
1363 dev_dbg(dev, "resume, ctrl %02x\n", tmp); in cmos_resume()
1370 /*----------------------------------------------------------------*/
1372 /* On non-x86 systems, a "CMOS" RTC lives most naturally on platform_bus.
1373 * ACPI systems always list these as PNPACPI devices, and pre-ACPI PCs
1402 return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq); in cmos_pnp_probe()
1407 cmos_do_remove(&pnp->dev); in cmos_pnp_remove()
1412 struct device *dev = &pnp->dev; in cmos_pnp_shutdown()
1422 cmos_do_shutdown(cmos->irq); in cmos_pnp_shutdown()
1460 struct device_node *node = pdev->dev.of_node; in cmos_of_init()
1466 val = of_get_property(node, "ctrl-reg", NULL); in cmos_of_init()
1470 val = of_get_property(node, "freq-reg", NULL); in cmos_of_init()
1477 /*----------------------------------------------------------------*/
1496 irq = -1; in cmos_platform_probe()
1498 return cmos_do_probe(&pdev->dev, resource, irq); in cmos_platform_probe()
1503 cmos_do_remove(&pdev->dev); in cmos_platform_remove()
1508 struct device *dev = &pdev->dev; in cmos_platform_shutdown()
1518 cmos_do_shutdown(cmos->irq); in cmos_platform_shutdown()
1580 MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs");