From 6eb8a6e9999618e6111db7549b46edddaa09313c Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Sat, 22 Dec 2012 00:46:57 +0800 Subject: [PATCH] tps65090: Throttle PMU interrupt instead of charger task This is a prepartory work for integrating USB port control into PMU task. Currently TPS65090 charger task is throttled to only waken by event once per 500 ms. This in a way makes it hard to integrate other functionality into this task. This CL moves the throttling mechanism to interrupt handler so as to provide better control of when to throttle the interrupt event. BUG=chrome-os-partner:14319 TEST=Build success and boot on spring. BRANCH=none Change-Id: I72e63180442b379a379e1a87c10ef62395434872 Signed-off-by: Vic Yang Reviewed-on: https://gerrit.chromium.org/gerrit/40189 Reviewed-by: Rong Chang --- common/pmu_tps65090.c | 2 +- common/pmu_tps65090_charger.c | 41 +++++++++++++++++++++++++---------- include/pmu_tpschrome.h | 3 +++ 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/common/pmu_tps65090.c b/common/pmu_tps65090.c index d825cd028c..e6e67a1ead 100644 --- a/common/pmu_tps65090.c +++ b/common/pmu_tps65090.c @@ -403,7 +403,7 @@ void pmu_irq_handler(enum gpio_signal signal) #ifdef CONFIG_AC_POWER_STATUS gpio_set_level(GPIO_AC_STATUS, board_get_ac()); #endif - task_wake(TASK_ID_PMU_TPS65090_CHARGER); + pmu_task_throttled_wake(); CPRINTF("Charger IRQ received.\n"); } diff --git a/common/pmu_tps65090_charger.c b/common/pmu_tps65090_charger.c index a0575820a0..4e474451fc 100644 --- a/common/pmu_tps65090_charger.c +++ b/common/pmu_tps65090_charger.c @@ -57,6 +57,10 @@ static const char * const state_list[] = { "discharging" }; +/* States for throttling PMU task */ +static timestamp_t last_waken; /* Initialized to 0 */ +static int has_pending_event; + static void enable_charging(int enable) { enable = enable ? 1 : 0; @@ -372,7 +376,6 @@ void pmu_charger_task(void) { int state = ST_IDLE; int next_state; - int event = 0; int wait_time = T1_USEC; unsigned int pre_charging_count = 0; @@ -386,6 +389,7 @@ void pmu_charger_task(void) disable_sleep(SLEEP_MASK_CHARGING); while (1) { + last_waken = get_time(); pmu_clear_irq(); /* @@ -466,24 +470,39 @@ void pmu_charger_task(void) } } - /* - * Throttle the charging loop. If previous loop awakened due to - * an event, sleep 500 ms instead of waiting for next event. - */ - if (event & TASK_EVENT_WAKE) { - msleep(500); - event = 0; - } else { - event = task_wait_event(wait_time); + if (!has_pending_event) { + task_wait_event(wait_time); disable_sleep(SLEEP_MASK_CHARGING); + } else { + has_pending_event = 0; } } } +void pmu_task_throttled_wake(void) +{ + timestamp_t now = get_time(); + if (now.val - last_waken.val >= HOOK_TICK_INTERVAL) { + has_pending_event = 0; + task_wake(TASK_ID_PMU_TPS65090_CHARGER); + } else { + has_pending_event = 1; + } +} + +static void wake_pmu_task_if_necessary(void) +{ + if (has_pending_event) { + has_pending_event = 0; + task_wake(TASK_ID_PMU_TPS65090_CHARGER); + } +} +DECLARE_HOOK(HOOK_TICK, wake_pmu_task_if_necessary, HOOK_PRIO_DEFAULT); + /* Wake charging task on chipset events */ static void pmu_chipset_events(void) { - task_wake(TASK_ID_PMU_TPS65090_CHARGER); + pmu_task_throttled_wake(); } DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pmu_chipset_events, HOOK_PRIO_DEFAULT); DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pmu_chipset_events, HOOK_PRIO_DEFAULT); diff --git a/include/pmu_tpschrome.h b/include/pmu_tpschrome.h index 757f833f17..4e42ec7e77 100644 --- a/include/pmu_tpschrome.h +++ b/include/pmu_tpschrome.h @@ -224,5 +224,8 @@ int board_get_ac(void); */ void board_hard_reset(void); +/* Wake TPS65090 charger task, but throttled to at most one call per tick. */ +void pmu_task_throttled_wake(void); + #endif /* __CROS_EC_TPSCHROME_H */