--- arch/ia64/kernel/mca.c 23 Sep 2002 22:38:11 -0000 1.5 +++ arch/ia64/kernel/mca.c 12 Nov 2002 20:03:09 -0000 @@ -42,6 +42,9 @@ #include #include #include +#include +#include +#include #include #include @@ -105,6 +108,11 @@ static struct irqaction mca_cpe_irqactio name: "cpe_hndlr" }; +#define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */ +#define MIN_CPE_POLL_INTERVAL (2*60*HZ) /* 2 minutes */ + +static struct timer_list cpe_poll_timer; + /* * ia64_mca_log_sal_error_record * @@ -510,8 +518,7 @@ ia64_mca_init(void) setup_irq(irq, &mca_cpe_irqaction); } ia64_mca_register_cpev(cpev); - } else - printk("ia64_mca_init: Failed to get routed CPEI vector from ACPI.\n"); + } } /* Initialize the areas set aside by the OS to buffer the @@ -803,6 +810,62 @@ static ia64_state_log_t ia64_state_log[I #define IA64_LOG_CURR_BUFFER(it) (void *)((ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)])) /* + * ia64_mca_cpe_poll + * + * Poll for Corrected Platform Errors (CPEs), dynamically adjust + * polling interval based on occurance of an event. + * + * Inputs : dummy(unused) + * Outputs : None + * + */ +static void +ia64_mca_cpe_poll (unsigned long dummy) +{ + int start_index; + static int poll_time = MAX_CPE_POLL_INTERVAL; + + start_index = IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE); + + /* Call the interrupt handler */ + ia64_mca_cpe_int_handler(0, NULL, NULL); + + /* + * If a log was recorded, increase our polling frequency, + * otherwise, backoff. + */ + if (start_index != IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE)) { + poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time/2); + } else { + poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2); + } + mod_timer(&cpe_poll_timer, jiffies + poll_time); +} + +/* + * ia64_mca_late_init + * + * Opportunity to setup things that require initialization later + * than ia64_mca_init. Setup a timer to poll for CPEs if the + * platform doesn't support an interrupt driven mechanism. + * + * Inputs : None + * Outputs : Status + */ +static int __init +ia64_mca_late_init(void) +{ + if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0) { + init_timer(&cpe_poll_timer); + cpe_poll_timer.function = ia64_mca_cpe_poll; + ia64_mca_cpe_poll(0); + } + return 0; +} + +module_init(ia64_mca_late_init); + +/* * C portion of the OS INIT handler * * Called from ia64_monarch_init_handler @@ -962,7 +1025,6 @@ ia64_log_get(int sal_info_type, prfunc_t return total_len; } else { IA64_LOG_UNLOCK(sal_info_type); - prfunc("ia64_log_get: No SAL error record available for type %d\n", sal_info_type); return 0; } }