aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index f31291ba94d0..b19a18dd994f 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -69,7 +69,6 @@ enum ec_command {
69 69
70#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ 70#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
71#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ 71#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
72#define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */
73#define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ 72#define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */
74 73
75#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts 74#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
@@ -83,6 +82,11 @@ enum {
83 EC_FLAGS_BLOCKED, /* Transactions are blocked */ 82 EC_FLAGS_BLOCKED, /* Transactions are blocked */
84}; 83};
85 84
85/* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */
86static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
87module_param(ec_delay, uint, 0644);
88MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes");
89
86/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 90/* If we find an EC via the ECDT, we need to keep a ptr to its context */
87/* External interfaces use first EC only, so remember */ 91/* External interfaces use first EC only, so remember */
88typedef int (*acpi_ec_query_func) (void *data); 92typedef int (*acpi_ec_query_func) (void *data);
@@ -210,7 +214,7 @@ static int ec_poll(struct acpi_ec *ec)
210 int repeat = 2; /* number of command restarts */ 214 int repeat = 2; /* number of command restarts */
211 while (repeat--) { 215 while (repeat--) {
212 unsigned long delay = jiffies + 216 unsigned long delay = jiffies +
213 msecs_to_jiffies(ACPI_EC_DELAY); 217 msecs_to_jiffies(ec_delay);
214 do { 218 do {
215 /* don't sleep with disabled interrupts */ 219 /* don't sleep with disabled interrupts */
216 if (EC_FLAGS_MSI || irqs_disabled()) { 220 if (EC_FLAGS_MSI || irqs_disabled()) {
@@ -265,7 +269,7 @@ static int ec_check_ibf0(struct acpi_ec *ec)
265 269
266static int ec_wait_ibf0(struct acpi_ec *ec) 270static int ec_wait_ibf0(struct acpi_ec *ec)
267{ 271{
268 unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); 272 unsigned long delay = jiffies + msecs_to_jiffies(ec_delay);
269 /* interrupt wait manually if GPE mode is not active */ 273 /* interrupt wait manually if GPE mode is not active */
270 while (time_before(jiffies, delay)) 274 while (time_before(jiffies, delay))
271 if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), 275 if (wait_event_timeout(ec->wait, ec_check_ibf0(ec),
@@ -428,8 +432,7 @@ EXPORT_SYMBOL(ec_write);
428 432
429int ec_transaction(u8 command, 433int ec_transaction(u8 command,
430 const u8 * wdata, unsigned wdata_len, 434 const u8 * wdata, unsigned wdata_len,
431 u8 * rdata, unsigned rdata_len, 435 u8 * rdata, unsigned rdata_len)
432 int force_poll)
433{ 436{
434 struct transaction t = {.command = command, 437 struct transaction t = {.command = command,
435 .wdata = wdata, .rdata = rdata, 438 .wdata = wdata, .rdata = rdata,
@@ -587,8 +590,6 @@ static void acpi_ec_gpe_query(void *ec_cxt)
587 mutex_unlock(&ec->lock); 590 mutex_unlock(&ec->lock);
588} 591}
589 592
590static void acpi_ec_gpe_query(void *ec_cxt);
591
592static int ec_check_sci(struct acpi_ec *ec, u8 state) 593static int ec_check_sci(struct acpi_ec *ec, u8 state)
593{ 594{
594 if (state & ACPI_EC_FLAG_SCI) { 595 if (state & ACPI_EC_FLAG_SCI) {
@@ -601,7 +602,8 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
601 return 0; 602 return 0;
602} 603}
603 604
604static u32 acpi_ec_gpe_handler(void *data) 605static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
606 u32 gpe_number, void *data)
605{ 607{
606 struct acpi_ec *ec = data; 608 struct acpi_ec *ec = data;
607 609
@@ -613,7 +615,7 @@ static u32 acpi_ec_gpe_handler(void *data)
613 wake_up(&ec->wait); 615 wake_up(&ec->wait);
614 ec_check_sci(ec, acpi_ec_read_status(ec)); 616 ec_check_sci(ec, acpi_ec_read_status(ec));
615 } 617 }
616 return ACPI_INTERRUPT_HANDLED; 618 return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
617} 619}
618 620
619/* -------------------------------------------------------------------------- 621/* --------------------------------------------------------------------------
@@ -802,8 +804,6 @@ static int acpi_ec_add(struct acpi_device *device)
802 return -EINVAL; 804 return -EINVAL;
803 } 805 }
804 806
805 ec->handle = device->handle;
806
807 /* Find and register all query methods */ 807 /* Find and register all query methods */
808 acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, 808 acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
809 acpi_ec_register_query_methods, NULL, ec, NULL); 809 acpi_ec_register_query_methods, NULL, ec, NULL);
@@ -929,8 +929,22 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
929 ec_flag_msi, "MSI hardware", { 929 ec_flag_msi, "MSI hardware", {
930 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, 930 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
931 { 931 {
932 ec_flag_msi, "MSI hardware", {
933 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
934 {
935 ec_flag_msi, "Quanta hardware", {
936 DMI_MATCH(DMI_SYS_VENDOR, "Quanta"),
937 DMI_MATCH(DMI_PRODUCT_NAME, "TW8/SW8/DW8"),}, NULL},
938 {
939 ec_flag_msi, "Quanta hardware", {
940 DMI_MATCH(DMI_SYS_VENDOR, "Quanta"),
941 DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL},
942 {
932 ec_validate_ecdt, "ASUS hardware", { 943 ec_validate_ecdt, "ASUS hardware", {
933 DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, 944 DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
945 {
946 ec_validate_ecdt, "ASUS hardware", {
947 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL},
934 {}, 948 {},
935}; 949};
936 950