diff options
-rw-r--r-- | chip/mec1322/port80.c | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/chip/mec1322/port80.c b/chip/mec1322/port80.c index 1ac75a9d9b..fa4fd36a4f 100644 --- a/chip/mec1322/port80.c +++ b/chip/mec1322/port80.c @@ -13,18 +13,38 @@ #include "registers.h" #include "task.h" -void port_80_interrupt(void) +/* Fire timer interrupt every 1000 usec to check for port80 data. */ +#define POLL_PERIOD_USEC 1000 +/* After 30 seconds of no port 80 data, disable the timer interrupt. */ +#define INTERRUPT_DISABLE_TIMEOUT_SEC 30 +#define INTERRUPT_DISABLE_IDLE_COUNT (INTERRUPT_DISABLE_TIMEOUT_SEC \ + * 1000000 \ + / POLL_PERIOD_USEC) + +/* Count the number of consecutive interrupts with no port 80 data. */ +static int idle_count; + +static void port_80_interrupt_enable(void) { - int data; - MEC1322_TMR16_STS(1) = 1; /* Ack the interrupt */ - if ((1 << 1) & MEC1322_INT_RESULT(23)) { - data = port_80_read(); + idle_count = 0; - if (data != PORT_80_IGNORE) - port_80_write(data); - } + /* Enable the interrupt. */ + task_enable_irq(MEC1322_IRQ_TIMER16_1); + /* Enable and start the timer. */ + MEC1322_TMR16_CTL(1) |= 1 | (1 << 5); } -DECLARE_IRQ(MEC1322_IRQ_TIMER16_1, port_80_interrupt, 2); +DECLARE_HOOK(HOOK_CHIPSET_RESUME, port_80_interrupt_enable, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_RESET, port_80_interrupt_enable, HOOK_PRIO_DEFAULT); + +static void port_80_interrupt_disable(void) +{ + /* Disable the timer block. */ + MEC1322_TMR16_CTL(1) &= ~1; + /* Disable the interrupt. */ + task_disable_irq(MEC1322_IRQ_TIMER16_1); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, port_80_interrupt_disable, + HOOK_PRIO_DEFAULT); /* * The port 80 interrupt will use TIMER16 instance 1 for a 1ms countdown @@ -46,8 +66,8 @@ static void port_80_interrupt_init(void) val &= ~(1 << 2); MEC1322_TMR16_CTL(1) = val; - /* Set the reload value to 1000us. (1ms). */ - MEC1322_TMR16_PRE(1) = 1000; + /* Set the reload value(us). */ + MEC1322_TMR16_PRE(1) = POLL_PERIOD_USEC; /* Clear the status if any. */ MEC1322_TMR16_STS(1) |= 1; @@ -59,28 +79,26 @@ static void port_80_interrupt_init(void) /* Enable the interrupt. */ MEC1322_TMR16_IEN(1) |= 1; MEC1322_INT_ENABLE(23) = (1 << 1); - task_enable_irq(MEC1322_IRQ_TIMER16_1); - /* Enable and start the timer. */ - MEC1322_TMR16_CTL(1) |= 1 | (1 << 5); + port_80_interrupt_enable(); } DECLARE_HOOK(HOOK_INIT, port_80_interrupt_init, HOOK_PRIO_DEFAULT); -static void port_80_interrupt_enable(void) +void port_80_interrupt(void) { - /* Enable the interrupt. */ - task_enable_irq(MEC1322_IRQ_TIMER16_1); - /* Enable the timer block. */ - MEC1322_TMR16_CTL(1) |= 1; -} -DECLARE_HOOK(HOOK_CHIPSET_RESUME, port_80_interrupt_enable, HOOK_PRIO_DEFAULT); + int data; -static void port_80_interrupt_disable(void) -{ - /* Disable the timer block. */ - MEC1322_TMR16_CTL(1) &= ~1; - /* Disable the interrupt. */ - task_disable_irq(MEC1322_IRQ_TIMER16_1); + MEC1322_TMR16_STS(1) = 1; /* Ack the interrupt */ + if ((1 << 1) & MEC1322_INT_RESULT(23)) { + data = port_80_read(); + + if (data != PORT_80_IGNORE) { + idle_count = 0; + port_80_write(data); + } + } + + if (++idle_count >= INTERRUPT_DISABLE_IDLE_COUNT) + port_80_interrupt_disable(); } -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, port_80_interrupt_disable, - HOOK_PRIO_DEFAULT); +DECLARE_IRQ(MEC1322_IRQ_TIMER16_1, port_80_interrupt, 2); |