Lines Matching +full:cmd +full:- +full:timeout +full:- +full:ms

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
81 * entry Permanent copy of ACPI_WDAT_ENTRY entry (sub-table).
93 * timeout User configured timeout in millisecond or 0 if isn't set.
106 uint64_t timeout; member
133 if (STAILQ_EMPTY(&sc->action[action])) { in wdatwd_action()
134 WDATWD_VERBOSE_PRINTF(sc->dev, in wdatwd_action()
139 STAILQ_FOREACH(wdat, &sc->action[action], next) { in wdatwd_action()
140 ACPI_GENERIC_ADDRESS *gas = &wdat->entry.RegisterRegion; in wdatwd_action()
143 switch (wdat->entry.Instruction in wdatwd_action()
151 x >>= gas->BitOffset; in wdatwd_action()
152 x &= wdat->entry.Mask; in wdatwd_action()
153 *ret = (x == wdat->entry.Value) ? 1 : 0; in wdatwd_action()
161 x >>= gas->BitOffset; in wdatwd_action()
162 x &= wdat->entry.Mask; in wdatwd_action()
166 x = wdat->entry.Value & wdat->entry.Mask; in wdatwd_action()
167 x <<= gas->BitOffset; in wdatwd_action()
168 if (wdat->entry.Instruction in wdatwd_action()
175 y &= ~(wdat->entry.Mask << gas->BitOffset); in wdatwd_action()
185 x = val & wdat->entry.Mask; in wdatwd_action()
186 x <<= gas->BitOffset; in wdatwd_action()
187 if (wdat->entry.Instruction in wdatwd_action()
194 y &= ~(wdat->entry.Mask << gas->BitOffset); in wdatwd_action()
211 device_printf(sc->dev, "action: 0x%02x, %s() returned: %d\n", in wdatwd_action()
229 wdatwd_set_countdown(struct wdatwd_softc *sc, u_int cmd) in wdatwd_set_countdown() argument
231 uint64_t timeout; in wdatwd_set_countdown() local
234 cmd &= WD_INTERVAL; in wdatwd_set_countdown()
235 timeout = ((uint64_t) 1 << cmd) / 1000000 / sc->period; in wdatwd_set_countdown()
236 if (timeout > sc->max) in wdatwd_set_countdown()
237 timeout = sc->max; in wdatwd_set_countdown()
238 else if (timeout < sc->min) in wdatwd_set_countdown()
239 timeout = sc->min; in wdatwd_set_countdown()
241 e = wdatwd_action(sc, ACPI_WDAT_SET_COUNTDOWN, timeout, NULL); in wdatwd_set_countdown()
243 sc->timeout = timeout * sc->period; in wdatwd_set_countdown()
252 wdatwd_get_current_countdown(const struct wdatwd_softc *sc, uint64_t *timeout) in wdatwd_get_current_countdown() argument
254 return wdatwd_action(sc, ACPI_WDAT_GET_CURRENT_COUNTDOWN, 0, timeout); in wdatwd_get_current_countdown()
261 wdatwd_get_countdown(const struct wdatwd_softc *sc, uint64_t *timeout) in wdatwd_get_countdown() argument
263 return wdatwd_action(sc, ACPI_WDAT_GET_COUNTDOWN, 0, timeout); in wdatwd_get_countdown()
276 sc->running = true; in wdatwd_set_running()
290 sc->running = false; in wdatwd_set_stop()
317 wdatwd_event(void *private, u_int cmd, int *error) in wdatwd_event() argument
324 run[0] = sc->running; in wdatwd_event()
331 if ((cmd & WD_INTERVAL) == 0) in wdatwd_event()
334 if (!sc->running) { in wdatwd_event()
336 wdatwd_set_countdown(sc, cmd); in wdatwd_event()
340 * watchdog timeout to a considerably larger value such in wdatwd_event()
344 * triggered for the newly set timeout value to take in wdatwd_event()
347 * set timeout. This failure scenario is seen by first in wdatwd_event()
351 * than 2.4 seconds timeout. in wdatwd_event()
358 run[1] = sc->running; in wdatwd_event()
363 WDATWD_VERBOSE_PRINTF(sc->dev, "cmd: %u, sc->running: " in wdatwd_event()
364 "%d -> %d, cnt: %llu -> %llu, cur: %llu -> %llu\n", cmd, in wdatwd_event()
382 return (-EINVAL); in wdat_set_action()
385 if (entry->Action < nitems(sc->action)) { in wdat_set_action()
387 wdat->entry = *entry; in wdat_set_action()
388 STAILQ_INSERT_TAIL(&sc->action[entry->Action], wdat, next); in wdat_set_action()
399 ACPI_TABLE_WDAT *wdat = sc->wdat; in wdat_parse_action_table()
403 remaining = wdat->Header.Length - sizeof(ACPI_TABLE_WDAT); in wdat_parse_action_table()
405 cp = (char *)wdat + wdat->Header.Length - remaining; in wdat_parse_action_table()
409 device_printf(sc->dev, "inconsistent WDAT table.\n"); in wdat_parse_action_table()
412 remaining -= consumed; in wdat_parse_action_table()
425 if (rr->AccessWidth < 1 || rr->AccessWidth > 4) in wdat_alloc_region()
431 res->start = rr->Address; in wdat_alloc_region()
432 res->end = res->start + (1 << (rr->AccessWidth - 1)); in wdat_alloc_region()
433 res->type = rr->SpaceId; in wdat_alloc_region()
463 if (res1->type != res2->type || res1->start > res2->end in wdat_compare_region()
464 || res1->end < res2->start) in wdat_compare_region()
467 if (res1->start <= res2->start && res1->end >= res2->end) in wdat_compare_region()
469 if (res1->start > res2->start) in wdat_compare_region()
471 if (res1->end < res2->end) in wdat_compare_region()
479 * Try to merge the given newres with the existing sc->res.
487 if (TAILQ_EMPTY(&sc->res)) { in wdat_merge_region()
488 TAILQ_INSERT_HEAD(&sc->res, newres, link); in wdat_merge_region()
494 TAILQ_FOREACH_SAFE(res1, &sc->res, link, res_safe) { in wdat_merge_region()
507 res1->start = newres->start; in wdat_merge_region()
511 if (res1->type != res2->type) { in wdat_merge_region()
514 } else if (res1->start <= res2->end) { in wdat_merge_region()
515 res1->start = res2->start; in wdat_merge_region()
516 TAILQ_REMOVE(&sc->res, res2, link); in wdat_merge_region()
524 res1->end = newres->end; in wdat_merge_region()
528 if (res1->type != res2->type) { in wdat_merge_region()
531 } else if (res1->end >= res2->start) { in wdat_merge_region()
532 res1->end = res2->end; in wdat_merge_region()
533 TAILQ_REMOVE(&sc->res, res2, link); in wdat_merge_region()
544 * Otherwise insert newres into sc->res at appropriate position in wdat_merge_region()
550 TAILQ_FOREACH(res1, &sc->res, link) { in wdat_merge_region()
551 if (newres->type != res1->type) in wdat_merge_region()
553 if (newres->start < res1->start) { in wdat_merge_region()
559 TAILQ_INSERT_TAIL(&sc->res, newres, link); in wdat_merge_region()
576 TAILQ_FOREACH(res, &sc->res, link) in wdat_release_resource()
577 if (res->res != NULL) { in wdat_release_resource()
578 bus_release_resource(dev, res->type, in wdat_release_resource()
579 res->rid, res->res); in wdat_release_resource()
580 bus_delete_resource(dev, res->type, res->rid); in wdat_release_resource()
581 res->res = NULL; in wdat_release_resource()
584 for (i = 0; i < nitems(sc->action); ++i) in wdat_release_resource()
585 while (!STAILQ_EMPTY(&sc->action[i])) { in wdat_release_resource()
586 wdat = STAILQ_FIRST(&sc->action[i]); in wdat_release_resource()
587 STAILQ_REMOVE_HEAD(&sc->action[i], next); in wdat_release_resource()
591 while (!TAILQ_EMPTY(&sc->res)) { in wdat_release_resource()
592 res = TAILQ_FIRST(&sc->res); in wdat_release_resource()
593 TAILQ_REMOVE(&sc->res, res, link); in wdat_release_resource()
616 &((ACPI_WDAT_ENTRY *)(wdat + 1))->RegisterRegion, in wdatwd_probe()
623 WDATWD_VERBOSE_PRINTF(dev, "Flags: 0x%x, TimerPeriod: %d ms/cnt, " in wdatwd_probe()
624 "MaxCount: %d cnt (%d ms), MinCount: %d cnt (%d ms)\n", in wdatwd_probe()
625 (int)wdat->Flags, (int)wdat->TimerPeriod, in wdatwd_probe()
626 (int)wdat->MaxCount, (int)(wdat->MaxCount * wdat->TimerPeriod), in wdatwd_probe()
627 (int)wdat->MinCount, (int)(wdat->MinCount * wdat->TimerPeriod)); in wdatwd_probe()
629 if ((wdat->TimerPeriod < 1) || (wdat->MinCount > wdat->MaxCount)) { in wdatwd_probe()
652 sc->dev = dev; in wdatwd_attach()
654 for (i = 0; i < nitems(sc->action); ++i) in wdatwd_attach()
655 STAILQ_INIT(&sc->action[i]); in wdatwd_attach()
659 (ACPI_TABLE_HEADER **)&sc->wdat); in wdatwd_attach()
664 sc->period = sc->wdat->TimerPeriod; in wdatwd_attach()
665 sc->max = sc->wdat->MaxCount; in wdatwd_attach()
666 sc->min = sc->wdat->MinCount; in wdatwd_attach()
667 sc->stop_in_sleep = (sc->wdat->Flags & ACPI_WDAT_STOPPED) in wdatwd_attach()
672 AcpiPutTable((ACPI_TABLE_HEADER *)sc->wdat); in wdatwd_attach()
676 for (i = 0; i < nitems(sc->action); ++i) in wdatwd_attach()
677 STAILQ_FOREACH(wdat, &sc->action[i], next) { in wdatwd_attach()
681 wdat->entry.RegisterRegion.SpaceId in wdatwd_attach()
684 : wdat->entry.RegisterRegion.SpaceId in wdatwd_attach()
688 wdat->entry.RegisterRegion.AccessWidth == 1 in wdatwd_attach()
690 : wdat->entry.RegisterRegion.AccessWidth == 2 in wdatwd_attach()
692 : wdat->entry.RegisterRegion.AccessWidth == 3 in wdatwd_attach()
694 : wdat->entry.RegisterRegion.AccessWidth == 4 in wdatwd_attach()
698 wdat->entry.RegisterRegion.Address, in wdatwd_attach()
699 wdat->entry.RegisterRegion.BitWidth, in wdatwd_attach()
700 wdat->entry.RegisterRegion.BitOffset); in wdatwd_attach()
705 TAILQ_INIT(&sc->res); in wdatwd_attach()
706 for (i = 0; i < nitems(sc->action); ++i) in wdatwd_attach()
707 STAILQ_FOREACH(wdat, &sc->action[i], next) { in wdatwd_attach()
708 res = wdat_alloc_region(&wdat->entry.RegisterRegion); in wdatwd_attach()
716 TAILQ_FOREACH(res, &sc->res, link) { in wdatwd_attach()
717 switch (res->type) { in wdatwd_attach()
719 res->type = SYS_RES_MEMORY; in wdatwd_attach()
722 res->type = SYS_RES_IOPORT; in wdatwd_attach()
728 res->rid = rid++; in wdatwd_attach()
729 bus_set_resource(dev, res->type, res->rid, in wdatwd_attach()
730 res->start, res->end - res->start); in wdatwd_attach()
731 res->res = bus_alloc_resource_any( in wdatwd_attach()
732 dev, res->type, &res->rid, RF_ACTIVE); in wdatwd_attach()
733 if (res->res == NULL) { in wdatwd_attach()
734 bus_delete_resource(dev, res->type, res->rid); in wdatwd_attach()
737 res->type == SYS_RES_MEMORY ? "mem" : "io ", in wdatwd_attach()
738 (unsigned long long )res->start, in wdatwd_attach()
739 (unsigned long long )(res->end - res->start)); in wdatwd_attach()
744 res->type == SYS_RES_MEMORY ? "mem" : "io ", in wdatwd_attach()
745 (unsigned long long )res->start, in wdatwd_attach()
746 (unsigned long long) (res->end - res->start)); in wdatwd_attach()
756 if ((e = wdatwd_get_countdown(sc, &sc->default_timeout)) in wdatwd_attach()
766 sc->default_timeout * sc->period, in wdatwd_attach()
767 "The default watchdog timeout in millisecond."); in wdatwd_attach()
770 STAILQ_EMPTY(&sc->action[ACPI_WDAT_SET_COUNTDOWN]) ? false : true, in wdatwd_attach()
771 "Whether the watchdog timeout is configurable or not."); in wdatwd_attach()
773 "timeout", CTLFLAG_RD, &sc->timeout, 0, in wdatwd_attach()
774 "The current watchdog timeout in millisecond. " in wdatwd_attach()
775 "If 0, the default timeout is used."); in wdatwd_attach()
777 "running", CTLFLAG_RD, &sc->running, 0, in wdatwd_attach()
780 sc->ev_tag = EVENTHANDLER_REGISTER(watchdog_list, wdatwd_event, sc, in wdatwd_attach()
800 EVENTHANDLER_DEREGISTER(watchdog_list, sc->ev_tag); in wdatwd_detach()
814 if (!sc->stop_in_sleep) in wdatwd_suspend()
827 if (!sc->stop_in_sleep) in wdatwd_resume()