diff options
Diffstat (limited to 'drivers/acpi/ec.c')
| -rw-r--r-- | drivers/acpi/ec.c | 89 |
1 files changed, 37 insertions, 52 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5999abd9909d..e7ce6e449424 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -101,7 +101,6 @@ static struct acpi_ec { | |||
| 101 | struct mutex lock; | 101 | struct mutex lock; |
| 102 | atomic_t query_pending; | 102 | atomic_t query_pending; |
| 103 | atomic_t event_count; | 103 | atomic_t event_count; |
| 104 | atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ | ||
| 105 | wait_queue_head_t wait; | 104 | wait_queue_head_t wait; |
| 106 | } *ec_ecdt; | 105 | } *ec_ecdt; |
| 107 | 106 | ||
| @@ -173,56 +172,6 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, unsigned count) | |||
| 173 | return -ETIME; | 172 | return -ETIME; |
| 174 | } | 173 | } |
| 175 | 174 | ||
| 176 | #ifdef ACPI_FUTURE_USAGE | ||
| 177 | /* | ||
| 178 | * Note: samsung nv5000 doesn't work with ec burst mode. | ||
| 179 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 | ||
| 180 | */ | ||
| 181 | int acpi_ec_enter_burst_mode(struct acpi_ec *ec) | ||
| 182 | { | ||
| 183 | u8 tmp = 0; | ||
| 184 | u8 status = 0; | ||
| 185 | |||
| 186 | status = acpi_ec_read_status(ec); | ||
| 187 | if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { | ||
| 188 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | ||
| 189 | if (status) | ||
| 190 | goto end; | ||
| 191 | acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE); | ||
| 192 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); | ||
| 193 | tmp = acpi_ec_read_data(ec); | ||
| 194 | if (tmp != 0x90) { /* Burst ACK byte */ | ||
| 195 | return -EINVAL; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | atomic_set(&ec->leaving_burst, 0); | ||
| 200 | return 0; | ||
| 201 | end: | ||
| 202 | ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode")); | ||
| 203 | return -1; | ||
| 204 | } | ||
| 205 | |||
| 206 | int acpi_ec_leave_burst_mode(struct acpi_ec *ec) | ||
| 207 | { | ||
| 208 | u8 status = 0; | ||
| 209 | |||
| 210 | status = acpi_ec_read_status(ec); | ||
| 211 | if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) { | ||
| 212 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | ||
| 213 | if (status) | ||
| 214 | goto end; | ||
| 215 | acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE); | ||
| 216 | acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | ||
| 217 | } | ||
| 218 | atomic_set(&ec->leaving_burst, 1); | ||
| 219 | return 0; | ||
| 220 | end: | ||
| 221 | ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode")); | ||
| 222 | return -1; | ||
| 223 | } | ||
| 224 | #endif /* ACPI_FUTURE_USAGE */ | ||
| 225 | |||
| 226 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | 175 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, |
| 227 | const u8 * wdata, unsigned wdata_len, | 176 | const u8 * wdata, unsigned wdata_len, |
| 228 | u8 * rdata, unsigned rdata_len) | 177 | u8 * rdata, unsigned rdata_len) |
| @@ -312,6 +261,21 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | |||
| 312 | return status; | 261 | return status; |
| 313 | } | 262 | } |
| 314 | 263 | ||
| 264 | /* | ||
| 265 | * Note: samsung nv5000 doesn't work with ec burst mode. | ||
| 266 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 | ||
| 267 | */ | ||
| 268 | int acpi_ec_burst_enable(struct acpi_ec *ec) | ||
| 269 | { | ||
| 270 | u8 d; | ||
| 271 | return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1); | ||
| 272 | } | ||
| 273 | |||
| 274 | int acpi_ec_burst_disable(struct acpi_ec *ec) | ||
| 275 | { | ||
| 276 | return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0); | ||
| 277 | } | ||
| 278 | |||
| 315 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | 279 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
| 316 | { | 280 | { |
| 317 | int result; | 281 | int result; |
| @@ -333,6 +297,28 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | |||
| 333 | /* | 297 | /* |
| 334 | * Externally callable EC access functions. For now, assume 1 EC only | 298 | * Externally callable EC access functions. For now, assume 1 EC only |
| 335 | */ | 299 | */ |
| 300 | int ec_burst_enable(void) | ||
| 301 | { | ||
| 302 | struct acpi_ec *ec; | ||
| 303 | if (!first_ec) | ||
| 304 | return -ENODEV; | ||
| 305 | ec = acpi_driver_data(first_ec); | ||
| 306 | return acpi_ec_burst_enable(ec); | ||
| 307 | } | ||
| 308 | |||
| 309 | EXPORT_SYMBOL(ec_burst_enable); | ||
| 310 | |||
| 311 | int ec_burst_disable(void) | ||
| 312 | { | ||
| 313 | struct acpi_ec *ec; | ||
| 314 | if (!first_ec) | ||
| 315 | return -ENODEV; | ||
| 316 | ec = acpi_driver_data(first_ec); | ||
| 317 | return acpi_ec_burst_disable(ec); | ||
| 318 | } | ||
| 319 | |||
| 320 | EXPORT_SYMBOL(ec_burst_disable); | ||
| 321 | |||
| 336 | int ec_read(u8 addr, u8 * val) | 322 | int ec_read(u8 addr, u8 * val) |
| 337 | { | 323 | { |
| 338 | struct acpi_ec *ec; | 324 | struct acpi_ec *ec; |
| @@ -639,7 +625,6 @@ static int acpi_ec_add(struct acpi_device *device) | |||
| 639 | atomic_set(&ec->query_pending, 0); | 625 | atomic_set(&ec->query_pending, 0); |
| 640 | atomic_set(&ec->event_count, 1); | 626 | atomic_set(&ec->event_count, 1); |
| 641 | if (acpi_ec_mode == EC_INTR) { | 627 | if (acpi_ec_mode == EC_INTR) { |
| 642 | atomic_set(&ec->leaving_burst, 1); | ||
| 643 | init_waitqueue_head(&ec->wait); | 628 | init_waitqueue_head(&ec->wait); |
| 644 | } | 629 | } |
| 645 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 630 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
