summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-02-11 15:56:26 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-02-25 11:22:17 -0800
commit6f3c58741d736f72b0a29ffcb9f9ecc168ff9634 (patch)
treea5faf92a72aa96b9a2b93a15db6d55d079a4e3f7
parent8e31328e024306bdc3b6c917d131d13f7375ba6e (diff)
downloadchrome-ec-6f3c58741d736f72b0a29ffcb9f9ecc168ff9634.tar.gz
mec1322: port80: Disable port80 interrupt and timer after timeout
port80 activity usually comes in bursts during AP boot and then goes quiet. For power savings, turn off the port80 interrupt and timer after no activity is seen for 30 seconds. BUG=chrome-os-partner:50175 TEST=Boot chell, verify port80 prints are seen. Verify timer + interrupts are disabled ~30 seconds later. Power down, power up, and verify port80 prints are seen once again. BRANCH=glados Change-Id: Iea091d73aa0c6e9cfb36240d68e31a20425cea45 Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/327256 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Icarus W Sparry <icarus.w.sparry@intel.com> Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r--chip/mec1322/port80.c76
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);