summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/npcx/hwtimer.c18
-rw-r--r--chip/npcx/hwtimer_chip.h3
-rw-r--r--chip/npcx/lpc.c19
3 files changed, 34 insertions, 6 deletions
diff --git a/chip/npcx/hwtimer.c b/chip/npcx/hwtimer.c
index f12e22e908..d4bb3a15f0 100644
--- a/chip/npcx/hwtimer.c
+++ b/chip/npcx/hwtimer.c
@@ -267,6 +267,24 @@ void __hw_clock_source_irq(void)
}
DECLARE_IRQ(NPCX_IRQ_ITIM32, __hw_clock_source_irq, 3);
+/* Handle ITIM32 overflow if interrupt is disable */
+void __hw_clock_handle_overflow(uint32_t clksrc_high)
+{
+ timestamp_t new;
+
+ /*
+ * Restore ITIM32 preload counter value to maximum and execute
+ * process_timers() later in ISR by trigger software interrupt in
+ * force_time().
+ */
+ new.le.hi = ++clksrc_high;
+ new.le.lo = 0;
+ force_time(new);
+
+ /* Clear timeout status */
+ SET_BIT(NPCX_ITCTS(ITIM32), NPCX_ITCTS_TO_STS);
+}
+
static void update_prescaler(void)
{
/*
diff --git a/chip/npcx/hwtimer_chip.h b/chip/npcx/hwtimer_chip.h
index 08cf8e278f..6e8c7752b2 100644
--- a/chip/npcx/hwtimer_chip.h
+++ b/chip/npcx/hwtimer_chip.h
@@ -32,4 +32,7 @@ uint16_t __hw_clock_event_count(void);
/* Returns time delay because of deep idle */
uint32_t __hw_clock_get_sleep_time(uint16_t pre_evt_cnt);
+/* Handle ITIM32 overflow if interrupt is disable */
+void __hw_clock_handle_overflow(uint32_t clksrc_high);
+
#endif /* __CROS_EC_HWTIMER_CHIP_H */
diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c
index b649d70ebb..394e72a067 100644
--- a/chip/npcx/lpc.c
+++ b/chip/npcx/lpc.c
@@ -13,6 +13,7 @@
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
+#include "hwtimer_chip.h"
#include "keyboard_protocol.h"
#include "lpc.h"
#include "lpc_chip.h"
@@ -335,14 +336,17 @@ void lpc_keyboard_put_char(uint8_t chr, int send_irq)
*/
static void lpc_sib_wait_host_read_done(void)
{
- timestamp_t deadline;
+ timestamp_t deadline, start;
- deadline.val = get_time().val + LPC_HOST_TRANSACTION_TIMEOUT_US;
+ start = get_time();
+ deadline.val = start.val + LPC_HOST_TRANSACTION_TIMEOUT_US;
while (IS_BIT_SET(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD)) {
if (timestamp_expired(deadline, NULL)) {
ccprintf("Unexpected time of host read transaction\n");
break;
- }
+ } /* Overflow occurred? */
+ else if (IS_BIT_SET(NPCX_ITCTS(ITIM32), NPCX_ITCTS_TO_STS))
+ __hw_clock_handle_overflow(start.le.hi);
}
}
@@ -351,14 +355,17 @@ static void lpc_sib_wait_host_read_done(void)
*/
static void lpc_sib_wait_host_write_done(void)
{
- timestamp_t deadline;
+ timestamp_t deadline, start;
- deadline.val = get_time().val + LPC_HOST_TRANSACTION_TIMEOUT_US;
+ start = get_time();
+ deadline.val = start.val + LPC_HOST_TRANSACTION_TIMEOUT_US;
while (IS_BIT_SET(NPCX_SIBCTRL, NPCX_SIBCTRL_CSWR)) {
if (timestamp_expired(deadline, NULL)) {
ccprintf("Unexpected time of host write transaction\n");
break;
- }
+ } /* Overflow occurred? */
+ else if (IS_BIT_SET(NPCX_ITCTS(ITIM32), NPCX_ITCTS_TO_STS))
+ __hw_clock_handle_overflow(start.le.hi);
}
}