mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
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>
This commit is contained in:
committed by
chrome-bot
parent
8e31328e02
commit
6f3c58741d
@@ -13,18 +13,38 @@
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
|
||||
void port_80_interrupt(void)
|
||||
{
|
||||
int data;
|
||||
MEC1322_TMR16_STS(1) = 1; /* Ack the interrupt */
|
||||
if ((1 << 1) & MEC1322_INT_RESULT(23)) {
|
||||
data = port_80_read();
|
||||
/* 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)
|
||||
|
||||
if (data != PORT_80_IGNORE)
|
||||
port_80_write(data);
|
||||
}
|
||||
/* Count the number of consecutive interrupts with no port 80 data. */
|
||||
static int idle_count;
|
||||
|
||||
static void port_80_interrupt_enable(void)
|
||||
{
|
||||
idle_count = 0;
|
||||
|
||||
/* 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);
|
||||
|
||||
Reference in New Issue
Block a user