diff options
| author | Alexey Starikovskiy <astarikovskiy@suse.de> | 2007-10-22 06:18:30 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2007-10-25 16:31:31 -0400 |
| commit | 080e412cc0bdb9ef8e7a983d5e008537e1c4d36c (patch) | |
| tree | e9b4511fc1b66450cdaf08bb3979b46ec4c5a701 /drivers/acpi | |
| parent | 23de5d9ef2a4bbc4f733f58311bcb7cf6239c813 (diff) | |
ACPI: EC: Replace atomic variables with bits
Number of flags is about to be increased, so it is better to
put them all into bits.
No functional changes.
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
| -rw-r--r-- | drivers/acpi/ec.c | 79 |
1 files changed, 38 insertions, 41 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 7b4178393e34..08fbe62a2db4 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -65,7 +65,7 @@ enum ec_command { | |||
| 65 | /* EC events */ | 65 | /* EC events */ |
| 66 | enum ec_event { | 66 | enum ec_event { |
| 67 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ | 67 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ |
| 68 | ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ | 68 | ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 71 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
| @@ -76,6 +76,11 @@ static enum ec_mode { | |||
| 76 | EC_POLL, /* Input buffer empty */ | 76 | EC_POLL, /* Input buffer empty */ |
| 77 | } acpi_ec_mode = EC_INTR; | 77 | } acpi_ec_mode = EC_INTR; |
| 78 | 78 | ||
| 79 | enum { | ||
| 80 | EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */ | ||
| 81 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | ||
| 82 | }; | ||
| 83 | |||
| 79 | static int acpi_ec_remove(struct acpi_device *device, int type); | 84 | static int acpi_ec_remove(struct acpi_device *device, int type); |
| 80 | static int acpi_ec_start(struct acpi_device *device); | 85 | static int acpi_ec_start(struct acpi_device *device); |
| 81 | static int acpi_ec_stop(struct acpi_device *device, int type); | 86 | static int acpi_ec_stop(struct acpi_device *device, int type); |
| @@ -116,9 +121,8 @@ static struct acpi_ec { | |||
| 116 | unsigned long command_addr; | 121 | unsigned long command_addr; |
| 117 | unsigned long data_addr; | 122 | unsigned long data_addr; |
| 118 | unsigned long global_lock; | 123 | unsigned long global_lock; |
| 124 | unsigned long flags; | ||
| 119 | struct mutex lock; | 125 | struct mutex lock; |
| 120 | atomic_t query_pending; | ||
| 121 | atomic_t event_count; | ||
| 122 | wait_queue_head_t wait; | 126 | wait_queue_head_t wait; |
| 123 | struct list_head list; | 127 | struct list_head list; |
| 124 | u8 handlers_installed; | 128 | u8 handlers_installed; |
| @@ -148,45 +152,42 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | |||
| 148 | outb(data, ec->data_addr); | 152 | outb(data, ec->data_addr); |
| 149 | } | 153 | } |
| 150 | 154 | ||
| 151 | static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event, | 155 | static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event) |
| 152 | unsigned old_count) | ||
| 153 | { | 156 | { |
| 154 | u8 status = acpi_ec_read_status(ec); | 157 | if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags)) |
| 155 | if (old_count == atomic_read(&ec->event_count)) | ||
| 156 | return 0; | 158 | return 0; |
| 157 | if (event == ACPI_EC_EVENT_OBF_1) { | 159 | if (event == ACPI_EC_EVENT_OBF_1) { |
| 158 | if (status & ACPI_EC_FLAG_OBF) | 160 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF) |
| 159 | return 1; | 161 | return 1; |
| 160 | } else if (event == ACPI_EC_EVENT_IBF_0) { | 162 | } else if (event == ACPI_EC_EVENT_IBF_0) { |
| 161 | if (!(status & ACPI_EC_FLAG_IBF)) | 163 | if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) |
| 162 | return 1; | 164 | return 1; |
| 163 | } | 165 | } |
| 164 | 166 | ||
| 165 | return 0; | 167 | return 0; |
| 166 | } | 168 | } |
| 167 | 169 | ||
| 168 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, | 170 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) |
| 169 | unsigned count, int force_poll) | ||
| 170 | { | 171 | { |
| 171 | if (unlikely(force_poll) || acpi_ec_mode == EC_POLL) { | 172 | if (unlikely(force_poll) || acpi_ec_mode == EC_POLL) { |
| 172 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 173 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
| 174 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | ||
| 173 | while (time_before(jiffies, delay)) { | 175 | while (time_before(jiffies, delay)) { |
| 174 | if (acpi_ec_check_status(ec, event, 0)) | 176 | if (acpi_ec_check_status(ec, event)) |
| 175 | return 0; | 177 | return 0; |
| 176 | } | 178 | } |
| 177 | } else { | 179 | } else { |
| 178 | if (wait_event_timeout(ec->wait, | 180 | if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event), |
| 179 | acpi_ec_check_status(ec, event, count), | 181 | msecs_to_jiffies(ACPI_EC_DELAY))) |
| 180 | msecs_to_jiffies(ACPI_EC_DELAY)) || | 182 | return 0; |
| 181 | acpi_ec_check_status(ec, event, 0)) { | 183 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
| 184 | if (acpi_ec_check_status(ec, event)) { | ||
| 182 | return 0; | 185 | return 0; |
| 183 | } else { | ||
| 184 | printk(KERN_ERR PREFIX "acpi_ec_wait timeout," | ||
| 185 | " status = %d, expect_event = %d\n", | ||
| 186 | acpi_ec_read_status(ec), event); | ||
| 187 | } | 186 | } |
| 188 | } | 187 | } |
| 189 | 188 | printk(KERN_ERR PREFIX "acpi_ec_wait timeout," | |
| 189 | " status = %d, expect_event = %d\n", | ||
| 190 | acpi_ec_read_status(ec), event); | ||
| 190 | return -ETIME; | 191 | return -ETIME; |
| 191 | } | 192 | } |
| 192 | 193 | ||
| @@ -196,39 +197,38 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | |||
| 196 | int force_poll) | 197 | int force_poll) |
| 197 | { | 198 | { |
| 198 | int result = 0; | 199 | int result = 0; |
| 199 | unsigned count = atomic_read(&ec->event_count); | 200 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
| 200 | acpi_ec_write_cmd(ec, command); | 201 | acpi_ec_write_cmd(ec, command); |
| 201 | 202 | ||
| 202 | for (; wdata_len > 0; --wdata_len) { | 203 | for (; wdata_len > 0; --wdata_len) { |
| 203 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count, force_poll); | 204 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
| 204 | if (result) { | 205 | if (result) { |
| 205 | printk(KERN_ERR PREFIX | 206 | printk(KERN_ERR PREFIX |
| 206 | "write_cmd timeout, command = %d\n", command); | 207 | "write_cmd timeout, command = %d\n", command); |
| 207 | goto end; | 208 | goto end; |
| 208 | } | 209 | } |
| 209 | count = atomic_read(&ec->event_count); | 210 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
| 210 | acpi_ec_write_data(ec, *(wdata++)); | 211 | acpi_ec_write_data(ec, *(wdata++)); |
| 211 | } | 212 | } |
| 212 | 213 | ||
| 213 | if (!rdata_len) { | 214 | if (!rdata_len) { |
| 214 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count, force_poll); | 215 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
| 215 | if (result) { | 216 | if (result) { |
| 216 | printk(KERN_ERR PREFIX | 217 | printk(KERN_ERR PREFIX |
| 217 | "finish-write timeout, command = %d\n", command); | 218 | "finish-write timeout, command = %d\n", command); |
| 218 | goto end; | 219 | goto end; |
| 219 | } | 220 | } |
| 220 | } else if (command == ACPI_EC_COMMAND_QUERY) { | 221 | } else if (command == ACPI_EC_COMMAND_QUERY) |
| 221 | atomic_set(&ec->query_pending, 0); | 222 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
| 222 | } | ||
| 223 | 223 | ||
| 224 | for (; rdata_len > 0; --rdata_len) { | 224 | for (; rdata_len > 0; --rdata_len) { |
| 225 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, count, force_poll); | 225 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll); |
| 226 | if (result) { | 226 | if (result) { |
| 227 | printk(KERN_ERR PREFIX "read timeout, command = %d\n", | 227 | printk(KERN_ERR PREFIX "read timeout, command = %d\n", |
| 228 | command); | 228 | command); |
| 229 | goto end; | 229 | goto end; |
| 230 | } | 230 | } |
| 231 | count = atomic_read(&ec->event_count); | 231 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
| 232 | *(rdata++) = acpi_ec_read_data(ec); | 232 | *(rdata++) = acpi_ec_read_data(ec); |
| 233 | } | 233 | } |
| 234 | end: | 234 | end: |
| @@ -261,7 +261,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | |||
| 261 | /* Make sure GPE is enabled before doing transaction */ | 261 | /* Make sure GPE is enabled before doing transaction */ |
| 262 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 262 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); |
| 263 | 263 | ||
| 264 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0); | 264 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0); |
| 265 | if (status) { | 265 | if (status) { |
| 266 | printk(KERN_ERR PREFIX | 266 | printk(KERN_ERR PREFIX |
| 267 | "input buffer is not empty, aborting transaction\n"); | 267 | "input buffer is not empty, aborting transaction\n"); |
| @@ -476,20 +476,18 @@ static void acpi_ec_gpe_query(void *ec_cxt) | |||
| 476 | static u32 acpi_ec_gpe_handler(void *data) | 476 | static u32 acpi_ec_gpe_handler(void *data) |
| 477 | { | 477 | { |
| 478 | acpi_status status = AE_OK; | 478 | acpi_status status = AE_OK; |
| 479 | u8 value; | ||
| 480 | struct acpi_ec *ec = data; | 479 | struct acpi_ec *ec = data; |
| 481 | 480 | ||
| 482 | atomic_inc(&ec->event_count); | 481 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
| 483 | 482 | ||
| 484 | if (acpi_ec_mode == EC_INTR) { | 483 | if (acpi_ec_mode == EC_INTR) { |
| 485 | wake_up(&ec->wait); | 484 | wake_up(&ec->wait); |
| 486 | } | 485 | } |
| 487 | 486 | ||
| 488 | value = acpi_ec_read_status(ec); | 487 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) { |
| 489 | if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { | 488 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) |
| 490 | atomic_set(&ec->query_pending, 1); | 489 | status = acpi_os_execute(OSL_EC_BURST_HANDLER, |
| 491 | status = | 490 | acpi_ec_gpe_query, ec); |
| 492 | acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); | ||
| 493 | } | 491 | } |
| 494 | 492 | ||
| 495 | return status == AE_OK ? | 493 | return status == AE_OK ? |
| @@ -642,8 +640,7 @@ static struct acpi_ec *make_acpi_ec(void) | |||
| 642 | if (!ec) | 640 | if (!ec) |
| 643 | return NULL; | 641 | return NULL; |
| 644 | 642 | ||
| 645 | atomic_set(&ec->query_pending, 1); | 643 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; |
| 646 | atomic_set(&ec->event_count, 1); | ||
| 647 | mutex_init(&ec->lock); | 644 | mutex_init(&ec->lock); |
| 648 | init_waitqueue_head(&ec->wait); | 645 | init_waitqueue_head(&ec->wait); |
| 649 | INIT_LIST_HEAD(&ec->list); | 646 | INIT_LIST_HEAD(&ec->list); |
| @@ -833,7 +830,7 @@ static int acpi_ec_start(struct acpi_device *device) | |||
| 833 | ret = ec_install_handlers(ec); | 830 | ret = ec_install_handlers(ec); |
| 834 | 831 | ||
| 835 | /* EC is fully operational, allow queries */ | 832 | /* EC is fully operational, allow queries */ |
| 836 | atomic_set(&ec->query_pending, 0); | 833 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
| 837 | return ret; | 834 | return ret; |
| 838 | } | 835 | } |
| 839 | 836 | ||
