aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/ec.c89
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 */
181int 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
206int 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
226static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, 175static 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 */
268int 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
274int 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
315static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) 279static 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 */
300int 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
309EXPORT_SYMBOL(ec_burst_enable);
310
311int 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
320EXPORT_SYMBOL(ec_burst_disable);
321
336int ec_read(u8 addr, u8 * val) 322int 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);