aboutsummaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2012-09-28 15:22:00 +0800
committerBen Hutchings <ben@decadent.org.uk>2012-10-30 23:26:37 +0000
commit6e653c320e86a62e0079217f70fead75e9a56aec (patch)
treed291615b711aaf30335590a7edc8fe5005bf3d67 /drivers/acpi
parent9719a5f38c56b4005c5427e6730a6f808567d7f0 (diff)
ACPI: EC: Make the GPE storm threshold a module parameter
commit a520d52e99b14ba7db135e916348f12f2a6e09be upstream. The Linux EC driver includes a mechanism to detect GPE storms, and switch from interrupt-mode to polling mode. However, polling mode sometimes doesn't work, so the workaround is problematic. Also, different systems seem to need the threshold for detecting the GPE storm at different levels. ACPI_EC_STORM_THRESHOLD was initially 20 when it's created, and was changed to 8 in 2.6.28 commit 06cf7d3c7 "ACPI: EC: lower interrupt storm threshold" to fix kernel bug 11892 by forcing the laptop in that bug to work in polling mode. However in bug 45151, it works fine in interrupt mode if we lift the threshold back to 20. This patch makes the threshold a module parameter so that user has a flexible option to debug/workaround this issue. The default is unchanged. This is also a preparation patch to fix specific systems: https://bugzilla.kernel.org/show_bug.cgi?id=45151 Signed-off-by: Feng Tang <feng.tang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/ec.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index b19a18dd994..05b3331ff2c 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -71,9 +71,6 @@ enum ec_command {
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
#define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */
-#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
- per one transaction */
-
enum {
EC_FLAGS_QUERY_PENDING, /* Query is pending */
EC_FLAGS_GPE_STORM, /* GPE storm detected */
@@ -87,6 +84,15 @@ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
module_param(ec_delay, uint, 0644);
MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes");
+/*
+ * If the number of false interrupts per one transaction exceeds
+ * this threshold, will think there is a GPE storm happened and
+ * will disable the GPE for normal transaction.
+ */
+static unsigned int ec_storm_threshold __read_mostly = 8;
+module_param(ec_storm_threshold, uint, 0644);
+MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm");
+
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
/* External interfaces use first EC only, so remember */
typedef int (*acpi_ec_query_func) (void *data);
@@ -319,7 +325,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
msleep(1);
/* It is safe to enable the GPE outside of the transaction. */
acpi_enable_gpe(NULL, ec->gpe);
- } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+ } else if (t->irq_count > ec_storm_threshold) {
pr_info(PREFIX "GPE storm detected, "
"transactions will use polling mode\n");
set_bit(EC_FLAGS_GPE_STORM, &ec->flags);