Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'acpi-ec'

* acpi-ec:
ACPI / EC: Free saved_ec on error exit path
ACPI / EC: Add detailed fields debugging support of EC_SC(R).
ACPI / EC: Update revision due to recent changes
ACPI / EC: Fix race condition in ec_transaction_completed()
ACPI / EC: Remove duplicated ec_wait_ibf0() waiter
ACPI / EC: Add asynchronous command byte write support
ACPI / EC: Avoid race condition related to advance_transaction()

+85 -79
+85 -79
drivers/acpi/ec.c
··· 1 1 /* 2 - * ec.c - ACPI Embedded Controller Driver (v2.1) 2 + * ec.c - ACPI Embedded Controller Driver (v2.2) 3 3 * 4 - * Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy@suse.de> 5 - * Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com> 6 - * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> 7 - * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 8 - * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 4 + * Copyright (C) 2001-2014 Intel Corporation 5 + * Author: 2014 Lv Zheng <lv.zheng@intel.com> 6 + * 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> 7 + * 2006 Denis Sadykov <denis.m.sadykov@intel.com> 8 + * 2004 Luming Yu <luming.yu@intel.com> 9 + * 2001, 2002 Andy Grover <andrew.grover@intel.com> 10 + * 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 11 + * Copyright (C) 2008 Alexey Starikovskiy <astarikovskiy@suse.de> 9 12 * 10 13 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 14 * ··· 55 52 /* EC status register */ 56 53 #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 57 54 #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 55 + #define ACPI_EC_FLAG_CMD 0x08 /* Input buffer contains a command */ 58 56 #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ 59 57 #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ 60 58 ··· 81 77 * OpReg are installed */ 82 78 EC_FLAGS_BLOCKED, /* Transactions are blocked */ 83 79 }; 80 + 81 + #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ 82 + #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ 84 83 85 84 /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ 86 85 static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; ··· 116 109 u8 ri; 117 110 u8 wlen; 118 111 u8 rlen; 119 - bool done; 112 + u8 flags; 120 113 }; 121 114 122 115 struct acpi_ec *boot_ec, *first_ec; ··· 134 127 static inline u8 acpi_ec_read_status(struct acpi_ec *ec) 135 128 { 136 129 u8 x = inb(ec->command_addr); 137 - pr_debug("---> status = 0x%2.2x\n", x); 130 + pr_debug("EC_SC(R) = 0x%2.2x " 131 + "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d\n", 132 + x, 133 + !!(x & ACPI_EC_FLAG_SCI), 134 + !!(x & ACPI_EC_FLAG_BURST), 135 + !!(x & ACPI_EC_FLAG_CMD), 136 + !!(x & ACPI_EC_FLAG_IBF), 137 + !!(x & ACPI_EC_FLAG_OBF)); 138 138 return x; 139 139 } 140 140 141 141 static inline u8 acpi_ec_read_data(struct acpi_ec *ec) 142 142 { 143 143 u8 x = inb(ec->data_addr); 144 - pr_debug("---> data = 0x%2.2x\n", x); 144 + pr_debug("EC_DATA(R) = 0x%2.2x\n", x); 145 145 return x; 146 146 } 147 147 148 148 static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) 149 149 { 150 - pr_debug("<--- command = 0x%2.2x\n", command); 150 + pr_debug("EC_SC(W) = 0x%2.2x\n", command); 151 151 outb(command, ec->command_addr); 152 152 } 153 153 154 154 static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) 155 155 { 156 - pr_debug("<--- data = 0x%2.2x\n", data); 156 + pr_debug("EC_DATA(W) = 0x%2.2x\n", data); 157 157 outb(data, ec->data_addr); 158 158 } 159 159 160 - static int ec_transaction_done(struct acpi_ec *ec) 160 + static int ec_transaction_completed(struct acpi_ec *ec) 161 161 { 162 162 unsigned long flags; 163 163 int ret = 0; 164 164 spin_lock_irqsave(&ec->lock, flags); 165 - if (!ec->curr || ec->curr->done) 165 + if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE)) 166 166 ret = 1; 167 167 spin_unlock_irqrestore(&ec->lock, flags); 168 168 return ret; 169 169 } 170 170 171 - static void start_transaction(struct acpi_ec *ec) 171 + static bool advance_transaction(struct acpi_ec *ec) 172 172 { 173 - ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; 174 - ec->curr->done = false; 175 - acpi_ec_write_cmd(ec, ec->curr->command); 176 - } 177 - 178 - static void advance_transaction(struct acpi_ec *ec, u8 status) 179 - { 180 - unsigned long flags; 181 173 struct transaction *t; 174 + u8 status; 175 + bool wakeup = false; 182 176 183 - spin_lock_irqsave(&ec->lock, flags); 177 + pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK"); 178 + status = acpi_ec_read_status(ec); 184 179 t = ec->curr; 185 180 if (!t) 186 - goto unlock; 187 - if (t->wlen > t->wi) { 188 - if ((status & ACPI_EC_FLAG_IBF) == 0) 189 - acpi_ec_write_data(ec, 190 - t->wdata[t->wi++]); 191 - else 192 - goto err; 193 - } else if (t->rlen > t->ri) { 194 - if ((status & ACPI_EC_FLAG_OBF) == 1) { 195 - t->rdata[t->ri++] = acpi_ec_read_data(ec); 196 - if (t->rlen == t->ri) 197 - t->done = true; 181 + goto err; 182 + if (t->flags & ACPI_EC_COMMAND_POLL) { 183 + if (t->wlen > t->wi) { 184 + if ((status & ACPI_EC_FLAG_IBF) == 0) 185 + acpi_ec_write_data(ec, t->wdata[t->wi++]); 186 + else 187 + goto err; 188 + } else if (t->rlen > t->ri) { 189 + if ((status & ACPI_EC_FLAG_OBF) == 1) { 190 + t->rdata[t->ri++] = acpi_ec_read_data(ec); 191 + if (t->rlen == t->ri) { 192 + t->flags |= ACPI_EC_COMMAND_COMPLETE; 193 + wakeup = true; 194 + } 195 + } else 196 + goto err; 197 + } else if (t->wlen == t->wi && 198 + (status & ACPI_EC_FLAG_IBF) == 0) { 199 + t->flags |= ACPI_EC_COMMAND_COMPLETE; 200 + wakeup = true; 201 + } 202 + return wakeup; 203 + } else { 204 + if ((status & ACPI_EC_FLAG_IBF) == 0) { 205 + acpi_ec_write_cmd(ec, t->command); 206 + t->flags |= ACPI_EC_COMMAND_POLL; 198 207 } else 199 208 goto err; 200 - } else if (t->wlen == t->wi && 201 - (status & ACPI_EC_FLAG_IBF) == 0) 202 - t->done = true; 203 - goto unlock; 209 + return wakeup; 210 + } 204 211 err: 205 212 /* 206 213 * If SCI bit is set, then don't think it's a false IRQ 207 214 * otherwise will take a not handled IRQ as a false one. 208 215 */ 209 - if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI)) 210 - ++t->irq_count; 216 + if (!(status & ACPI_EC_FLAG_SCI)) { 217 + if (in_interrupt() && t) 218 + ++t->irq_count; 219 + } 220 + return wakeup; 221 + } 211 222 212 - unlock: 213 - spin_unlock_irqrestore(&ec->lock, flags); 223 + static void start_transaction(struct acpi_ec *ec) 224 + { 225 + ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; 226 + ec->curr->flags = 0; 227 + (void)advance_transaction(ec); 214 228 } 215 229 216 230 static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); ··· 256 228 /* don't sleep with disabled interrupts */ 257 229 if (EC_FLAGS_MSI || irqs_disabled()) { 258 230 udelay(ACPI_EC_MSI_UDELAY); 259 - if (ec_transaction_done(ec)) 231 + if (ec_transaction_completed(ec)) 260 232 return 0; 261 233 } else { 262 234 if (wait_event_timeout(ec->wait, 263 - ec_transaction_done(ec), 235 + ec_transaction_completed(ec), 264 236 msecs_to_jiffies(1))) 265 237 return 0; 266 238 } 267 - advance_transaction(ec, acpi_ec_read_status(ec)); 239 + spin_lock_irqsave(&ec->lock, flags); 240 + (void)advance_transaction(ec); 241 + spin_unlock_irqrestore(&ec->lock, flags); 268 242 } while (time_before(jiffies, delay)); 269 243 pr_debug("controller reset, restart transaction\n"); 270 244 spin_lock_irqsave(&ec->lock, flags); ··· 298 268 return ret; 299 269 } 300 270 301 - static int ec_check_ibf0(struct acpi_ec *ec) 302 - { 303 - u8 status = acpi_ec_read_status(ec); 304 - return (status & ACPI_EC_FLAG_IBF) == 0; 305 - } 306 - 307 - static int ec_wait_ibf0(struct acpi_ec *ec) 308 - { 309 - unsigned long delay = jiffies + msecs_to_jiffies(ec_delay); 310 - /* interrupt wait manually if GPE mode is not active */ 311 - while (time_before(jiffies, delay)) 312 - if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), 313 - msecs_to_jiffies(1))) 314 - return 0; 315 - return -ETIME; 316 - } 317 - 318 271 static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) 319 272 { 320 273 int status; ··· 317 304 status = -ENODEV; 318 305 goto unlock; 319 306 } 320 - } 321 - if (ec_wait_ibf0(ec)) { 322 - pr_err("input buffer is not empty, " 323 - "aborting transaction\n"); 324 - status = -ETIME; 325 - goto end; 326 307 } 327 308 pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n", 328 309 t->command, t->wdata ? t->wdata[0] : 0); ··· 341 334 set_bit(EC_FLAGS_GPE_STORM, &ec->flags); 342 335 } 343 336 pr_debug("transaction end\n"); 344 - end: 345 337 if (ec->global_lock) 346 338 acpi_release_global_lock(glk); 347 339 unlock: ··· 640 634 static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, 641 635 u32 gpe_number, void *data) 642 636 { 637 + unsigned long flags; 643 638 struct acpi_ec *ec = data; 644 - u8 status = acpi_ec_read_status(ec); 645 639 646 - pr_debug("~~~> interrupt, status:0x%02x\n", status); 647 - 648 - advance_transaction(ec, status); 649 - if (ec_transaction_done(ec) && 650 - (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { 640 + spin_lock_irqsave(&ec->lock, flags); 641 + if (advance_transaction(ec)) 651 642 wake_up(&ec->wait); 652 - ec_check_sci(ec, acpi_ec_read_status(ec)); 653 - } 643 + spin_unlock_irqrestore(&ec->lock, flags); 644 + ec_check_sci(ec, acpi_ec_read_status(ec)); 654 645 return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; 655 646 } 656 647 ··· 1069 1066 /* fall through */ 1070 1067 } 1071 1068 1072 - if (EC_FLAGS_SKIP_DSDT_SCAN) 1069 + if (EC_FLAGS_SKIP_DSDT_SCAN) { 1070 + kfree(saved_ec); 1073 1071 return -ENODEV; 1072 + } 1074 1073 1075 1074 /* This workaround is needed only on some broken machines, 1076 1075 * which require early EC, but fail to provide ECDT */ ··· 1110 1105 } 1111 1106 error: 1112 1107 kfree(boot_ec); 1108 + kfree(saved_ec); 1113 1109 boot_ec = NULL; 1114 1110 return -ENODEV; 1115 1111 }