diff options
author | Denis M. Sadykov <denis.m.sadykov@intel.com> | 2006-09-26 11:50:33 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-10-14 00:49:55 -0400 |
commit | 3576cf619b73d850f5b21375609645f221e6270f (patch) | |
tree | 0e4fedeea6c261b781c7ac1acb9d0467230fa4c2 /drivers/acpi/ec.c | |
parent | 703959d47e887a29dc58123c05aa0ffcbbfa131d (diff) |
ACPI: EC: Unify poll and interrupt mode transaction functions
Signed-off-by: Alexey Y. Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 110 |
1 files changed, 29 insertions, 81 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index c816b4eab50d..9c7fce6a42e8 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -112,12 +112,6 @@ static struct acpi_ec *ec_ecdt; | |||
112 | static struct acpi_device *first_ec; | 112 | static struct acpi_device *first_ec; |
113 | static int acpi_ec_mode = EC_INTR; | 113 | static int acpi_ec_mode = EC_INTR; |
114 | 114 | ||
115 | static int acpi_ec_poll_transaction(struct acpi_ec *ec, u8 command, | ||
116 | const u8 *wdata, unsigned wdata_len, | ||
117 | u8 *rdata, unsigned rdata_len); | ||
118 | static int acpi_ec_intr_transaction(struct acpi_ec *ec, u8 command, | ||
119 | const u8 *wdata, unsigned wdata_len, | ||
120 | u8 *rdata, unsigned rdata_len); | ||
121 | static void acpi_ec_gpe_poll_query(void *ec_cxt); | 115 | static void acpi_ec_gpe_poll_query(void *ec_cxt); |
122 | static void acpi_ec_gpe_intr_query(void *ec_cxt); | 116 | static void acpi_ec_gpe_intr_query(void *ec_cxt); |
123 | static u32 acpi_ec_gpe_poll_handler(void *data); | 117 | static u32 acpi_ec_gpe_poll_handler(void *data); |
@@ -257,32 +251,9 @@ int acpi_ec_leave_burst_mode(struct acpi_ec *ec) | |||
257 | } | 251 | } |
258 | #endif /* ACPI_FUTURE_USAGE */ | 252 | #endif /* ACPI_FUTURE_USAGE */ |
259 | 253 | ||
260 | static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | ||
261 | const u8 *wdata, unsigned wdata_len, | ||
262 | u8 *rdata, unsigned rdata_len) | ||
263 | { | ||
264 | if (acpi_ec_mode == EC_POLL) | ||
265 | return acpi_ec_poll_transaction(ec, command, wdata, wdata_len, rdata, rdata_len); | ||
266 | else | ||
267 | return acpi_ec_intr_transaction(ec, command, wdata, wdata_len, rdata, rdata_len); | ||
268 | } | ||
269 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u32 * data) | ||
270 | { | ||
271 | int result; | ||
272 | u8 d; | ||
273 | result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ, &address, 1, &d, 1); | ||
274 | *data = d; | ||
275 | return result; | ||
276 | } | ||
277 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | ||
278 | { | ||
279 | u8 wdata[2] = { address, data }; | ||
280 | return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, wdata, 2, NULL, 0); | ||
281 | } | ||
282 | |||
283 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | 254 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, |
284 | const u8 *wdata, unsigned wdata_len, | 255 | const u8 *wdata, unsigned wdata_len, |
285 | u8 *rdata, unsigned rdata_len) | 256 | u8 *rdata, unsigned rdata_len) |
286 | { | 257 | { |
287 | int result; | 258 | int result; |
288 | 259 | ||
@@ -292,9 +263,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | |||
292 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 263 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
293 | if (result) | 264 | if (result) |
294 | return result; | 265 | return result; |
295 | |||
296 | acpi_ec_write_data(ec, *(wdata++)); | 266 | acpi_ec_write_data(ec, *(wdata++)); |
297 | } | 267 | } |
298 | 268 | ||
299 | if (command == ACPI_EC_COMMAND_WRITE) { | 269 | if (command == ACPI_EC_COMMAND_WRITE) { |
300 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 270 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
@@ -316,46 +286,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | |||
316 | return 0; | 286 | return 0; |
317 | } | 287 | } |
318 | 288 | ||
319 | static int acpi_ec_poll_transaction(struct acpi_ec *ec, u8 command, | 289 | static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, |
320 | const u8 *wdata, unsigned wdata_len, | 290 | const u8 *wdata, unsigned wdata_len, |
321 | u8 *rdata, unsigned rdata_len) | 291 | u8 *rdata, unsigned rdata_len) |
322 | { | ||
323 | acpi_status status = AE_OK; | ||
324 | int result; | ||
325 | u32 glk = 0; | ||
326 | |||
327 | if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) | ||
328 | return -EINVAL; | ||
329 | |||
330 | if (rdata) | ||
331 | memset(rdata, 0, rdata_len); | ||
332 | |||
333 | if (ec->global_lock) { | ||
334 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
335 | if (ACPI_FAILURE(status)) | ||
336 | return -ENODEV; | ||
337 | } | ||
338 | |||
339 | if (down_interruptible(&ec->sem)) { | ||
340 | result = -ERESTARTSYS; | ||
341 | goto end_nosem; | ||
342 | } | ||
343 | |||
344 | result = acpi_ec_transaction_unlocked(ec, command, | ||
345 | wdata, wdata_len, | ||
346 | rdata, rdata_len); | ||
347 | up(&ec->sem); | ||
348 | |||
349 | end_nosem: | ||
350 | if (ec->global_lock) | ||
351 | acpi_release_global_lock(glk); | ||
352 | |||
353 | return result; | ||
354 | } | ||
355 | |||
356 | static int acpi_ec_intr_transaction(struct acpi_ec *ec, u8 command, | ||
357 | const u8 *wdata, unsigned wdata_len, | ||
358 | u8 *rdata, unsigned rdata_len) | ||
359 | { | 292 | { |
360 | int status; | 293 | int status; |
361 | u32 glk; | 294 | u32 glk; |
@@ -371,13 +304,11 @@ static int acpi_ec_intr_transaction(struct acpi_ec *ec, u8 command, | |||
371 | if (ACPI_FAILURE(status)) | 304 | if (ACPI_FAILURE(status)) |
372 | return -ENODEV; | 305 | return -ENODEV; |
373 | } | 306 | } |
374 | |||
375 | WARN_ON(in_interrupt()); | ||
376 | down(&ec->sem); | 307 | down(&ec->sem); |
377 | 308 | ||
378 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); | 309 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
379 | if (status) { | 310 | if (status) { |
380 | ACPI_EXCEPTION((AE_INFO, status, "read EC, IB not empty")); | 311 | printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); |
381 | goto end; | 312 | goto end; |
382 | } | 313 | } |
383 | 314 | ||
@@ -394,6 +325,23 @@ end: | |||
394 | return status; | 325 | return status; |
395 | } | 326 | } |
396 | 327 | ||
328 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u32 * data) | ||
329 | { | ||
330 | int result; | ||
331 | u8 d; | ||
332 | |||
333 | result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ, | ||
334 | &address, 1, &d, 1); | ||
335 | *data = d; | ||
336 | return result; | ||
337 | } | ||
338 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | ||
339 | { | ||
340 | u8 wdata[2] = { address, data }; | ||
341 | return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, | ||
342 | wdata, 2, NULL, 0); | ||
343 | } | ||
344 | |||
397 | /* | 345 | /* |
398 | * Externally callable EC access functions. For now, assume 1 EC only | 346 | * Externally callable EC access functions. For now, assume 1 EC only |
399 | */ | 347 | */ |
@@ -447,13 +395,13 @@ extern int ec_transaction(u8 command, | |||
447 | 395 | ||
448 | ec = acpi_driver_data(first_ec); | 396 | ec = acpi_driver_data(first_ec); |
449 | 397 | ||
450 | return acpi_ec_transaction(ec, command, wdata, wdata_len, rdata, rdata_len); | 398 | return acpi_ec_transaction(ec, command, wdata, |
399 | wdata_len, rdata, rdata_len); | ||
451 | } | 400 | } |
452 | 401 | ||
453 | EXPORT_SYMBOL(ec_transaction); | 402 | static int acpi_ec_query(struct acpi_ec *ec, u32 * data) |
454 | 403 | { | |
455 | static int acpi_ec_query(struct acpi_ec *ec, u32 * data) { | 404 | int result; |
456 | int result; | ||
457 | u8 d; | 405 | u8 d; |
458 | 406 | ||
459 | if (!ec || !data) | 407 | if (!ec || !data) |