ec.c 26.1 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2
 *  ec.c - ACPI Embedded Controller Driver (v2.1)
L
Linus Torvalds 已提交
3
 *
4
 *  Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy@suse.de>
5
 *  Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com>
L
Linus Torvalds 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

29
/* Uncomment next line to get verbose printout */
30 31
/* #define DEBUG */

L
Linus Torvalds 已提交
32 33 34 35 36 37 38
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
D
Dmitry Torokhov 已提交
39
#include <linux/interrupt.h>
40
#include <linux/list.h>
41
#include <linux/spinlock.h>
L
Linus Torvalds 已提交
42 43 44 45 46 47 48 49
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/actypes.h>

#define ACPI_EC_CLASS			"embedded_controller"
#define ACPI_EC_DEVICE_NAME		"Embedded Controller"
#define ACPI_EC_FILE_INFO		"info"
50

51 52
#undef PREFIX
#define PREFIX				"ACPI: EC: "
53

54
/* EC status register */
L
Linus Torvalds 已提交
55 56
#define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */
#define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */
D
Dmitry Torokhov 已提交
57
#define ACPI_EC_FLAG_BURST	0x10	/* burst mode */
L
Linus Torvalds 已提交
58
#define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */
59

60
/* EC commands */
61
enum ec_command {
A
Alexey Starikovskiy 已提交
62 63 64 65 66
	ACPI_EC_COMMAND_READ = 0x80,
	ACPI_EC_COMMAND_WRITE = 0x81,
	ACPI_EC_BURST_ENABLE = 0x82,
	ACPI_EC_BURST_DISABLE = 0x83,
	ACPI_EC_COMMAND_QUERY = 0x84,
67
};
68

69
#define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */
70
#define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
71
#define ACPI_EC_UDELAY		100	/* Wait 100us before polling EC again */
72

73 74 75
#define ACPI_EC_STORM_THRESHOLD 20	/* number of false interrupts
					   per one transaction */

76 77
enum {
	EC_FLAGS_QUERY_PENDING,		/* Query is pending */
78 79
	EC_FLAGS_GPE_MODE,		/* Expect GPE to be sent
					 * for status change */
80
	EC_FLAGS_NO_GPE,		/* Don't use GPE mode */
81 82 83
	EC_FLAGS_GPE_STORM,		/* GPE storm detected */
	EC_FLAGS_HANDLERS_INSTALLED	/* Handlers for GPE and
					 * OpReg are installed */
L
Linus Torvalds 已提交
84
};
85 86

/* If we find an EC via the ECDT, we need to keep a ptr to its context */
87
/* External interfaces use first EC only, so remember */
88 89 90 91 92 93 94 95 96 97
typedef int (*acpi_ec_query_func) (void *data);

struct acpi_ec_query_handler {
	struct list_head node;
	acpi_ec_query_func func;
	acpi_handle handle;
	void *data;
	u8 query_bit;
};

98
struct transaction {
99 100 101
	const u8 *wdata;
	u8 *rdata;
	unsigned short irq_count;
102
	u8 command;
103 104 105 106
	u8 wlen;
	u8 rlen;
};

107
static struct acpi_ec {
108
	acpi_handle handle;
109
	unsigned long gpe;
110 111
	unsigned long command_addr;
	unsigned long data_addr;
112
	unsigned long global_lock;
113
	unsigned long flags;
114
	struct mutex lock;
115
	wait_queue_head_t wait;
116
	struct list_head list;
117 118
	struct transaction *curr;
	spinlock_t curr_lock;
119
} *boot_ec, *first_ec;
120

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
/* 
 * Some Asus system have exchanged ECDT data/command IO addresses.
 */
static int print_ecdt_error(const struct dmi_system_id *id)
{
	printk(KERN_NOTICE PREFIX "%s detected - "
		"ECDT has exchanged control/data I/O address\n",
		id->ident);
	return 0;
}

static struct dmi_system_id __cpuinitdata ec_dmi_table[] = {
	{
	print_ecdt_error, "Asus L4R", {
	DMI_MATCH(DMI_BIOS_VERSION, "1008.006"),
	DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),
	DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL},
	{
	print_ecdt_error, "Asus M6R", {
	DMI_MATCH(DMI_BIOS_VERSION, "0207"),
	DMI_MATCH(DMI_PRODUCT_NAME, "M6R"),
	DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL},
	{},
};

L
Linus Torvalds 已提交
146 147 148 149
/* --------------------------------------------------------------------------
                             Transaction Management
   -------------------------------------------------------------------------- */

150
static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
L
Linus Torvalds 已提交
151
{
152
	u8 x = inb(ec->command_addr);
153
	pr_debug(PREFIX "---> status = 0x%2.2x\n", x);
154
	return x;
D
Dmitry Torokhov 已提交
155 156
}

157
static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
158
{
159
	u8 x = inb(ec->data_addr);
160
	pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
161
	return x;
162 163
}

164
static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
L
Luming Yu 已提交
165
{
166
	pr_debug(PREFIX "<--- command = 0x%2.2x\n", command);
167
	outb(command, ec->command_addr);
L
Luming Yu 已提交
168 169
}

170
static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
L
Luming Yu 已提交
171
{
172
	pr_debug(PREFIX "<--- data = 0x%2.2x\n", data);
173
	outb(data, ec->data_addr);
174
}
L
Luming Yu 已提交
175

176
static int ec_transaction_done(struct acpi_ec *ec)
177
{
178 179
	unsigned long flags;
	int ret = 0;
180 181
	spin_lock_irqsave(&ec->curr_lock, flags);
	if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
182
		ret = 1;
183
	spin_unlock_irqrestore(&ec->curr_lock, flags);
184
	return ret;
L
Luming Yu 已提交
185
}
D
Dmitry Torokhov 已提交
186

187
static void gpe_transaction(struct acpi_ec *ec, u8 status)
188
{
189
	unsigned long flags;
190 191
	spin_lock_irqsave(&ec->curr_lock, flags);
	if (!ec->curr)
192
		goto unlock;
193
	if (ec->curr->wlen > 0) {
194
		if ((status & ACPI_EC_FLAG_IBF) == 0) {
195 196
			acpi_ec_write_data(ec, *(ec->curr->wdata++));
			--ec->curr->wlen;
197 198
		} else
			/* false interrupt, state didn't change */
199
			++ec->curr->irq_count;
200

201
	} else if (ec->curr->rlen > 0) {
202
		if ((status & ACPI_EC_FLAG_OBF) == 1) {
203 204
			*(ec->curr->rdata++) = acpi_ec_read_data(ec);
			--ec->curr->rlen;
205 206
		} else
			/* false interrupt, state didn't change */
207
			++ec->curr->irq_count;
208 209
	}
unlock:
210
	spin_unlock_irqrestore(&ec->curr_lock, flags);
A
Alexey Starikovskiy 已提交
211
}
212

213
static int acpi_ec_wait(struct acpi_ec *ec)
A
Alexey Starikovskiy 已提交
214
{
215 216 217 218 219 220 221
	if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
			       msecs_to_jiffies(ACPI_EC_DELAY)))
		return 0;
	/* missing GPEs, switch back to poll mode */
	if (printk_ratelimit())
		pr_info(PREFIX "missing confirmations, "
				"switch off interrupt mode.\n");
222
	set_bit(EC_FLAGS_NO_GPE, &ec->flags);
A
Alexey Starikovskiy 已提交
223
	clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
224
	return 1;
A
Alexey Starikovskiy 已提交
225 226
}

227 228 229
static void acpi_ec_gpe_query(void *ec_cxt);

static int ec_check_sci(struct acpi_ec *ec, u8 state)
230
{
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
	if (state & ACPI_EC_FLAG_SCI) {
		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
			return acpi_os_execute(OSL_EC_BURST_HANDLER,
				acpi_ec_gpe_query, ec);
	}
	return 0;
}

static int ec_poll(struct acpi_ec *ec)
{
	unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
	msleep(1);
	while (time_before(jiffies, delay)) {
		gpe_transaction(ec, acpi_ec_read_status(ec));
		msleep(1);
		if (ec_transaction_done(ec))
247
			return 0;
248
	}
249
	return -ETIME;
L
Linus Torvalds 已提交
250 251
}

252 253
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
					struct transaction *t,
254
					int force_poll)
L
Luming Yu 已提交
255
{
256 257
	unsigned long tmp;
	int ret = 0;
258
	pr_debug(PREFIX "transaction start\n");
259 260 261 262
	/* disable GPE during transaction if storm is detected */
	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
		clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
		acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
263
	}
264
	/* start transaction */
265
	spin_lock_irqsave(&ec->curr_lock, tmp);
266
	/* following two actions should be kept atomic */
267 268 269 270
	t->irq_count = 0;
	ec->curr = t;
	acpi_ec_write_cmd(ec, ec->curr->command);
	if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
271
		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
272
	spin_unlock_irqrestore(&ec->curr_lock, tmp);
273 274 275 276 277
	/* if we selected poll mode or failed in GPE-mode do a poll loop */
	if (force_poll ||
	    !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ||
	    acpi_ec_wait(ec))
		ret = ec_poll(ec);
278
	pr_debug(PREFIX "transaction end\n");
279 280 281
	spin_lock_irqsave(&ec->curr_lock, tmp);
	ec->curr = NULL;
	spin_unlock_irqrestore(&ec->curr_lock, tmp);
282 283 284 285 286 287
	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
		/* check if we received SCI during transaction */
		ec_check_sci(ec, acpi_ec_read_status(ec));
		/* it is safe to enable GPE outside of transaction */
		acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
	} else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
288
		   t->irq_count > ACPI_EC_STORM_THRESHOLD) {
289 290 291 292 293 294 295 296 297 298
		pr_debug(PREFIX "GPE storm detected\n");
		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
	}
	return ret;
}

static int ec_check_ibf0(struct acpi_ec *ec)
{
	u8 status = acpi_ec_read_status(ec);
	return (status & ACPI_EC_FLAG_IBF) == 0;
L
Luming Yu 已提交
299 300
}

301
static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
302
			       int force_poll)
L
Linus Torvalds 已提交
303
{
304
	int status;
L
Len Brown 已提交
305
	u32 glk;
306
	if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
307
		return -EINVAL;
308 309
	if (t->rdata)
		memset(t->rdata, 0, t->rlen);
310
	mutex_lock(&ec->lock);
311
	if (ec->global_lock) {
L
Linus Torvalds 已提交
312
		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
313
		if (ACPI_FAILURE(status)) {
314 315
			status = -ENODEV;
			goto unlock;
316
		}
L
Linus Torvalds 已提交
317
	}
318 319
	if (!wait_event_timeout(ec->wait, ec_check_ibf0(ec),
				msecs_to_jiffies(ACPI_EC_DELAY))) {
320 321
		pr_err(PREFIX "input buffer is not empty, "
				"aborting transaction\n");
322
		status = -ETIME;
D
Dmitry Torokhov 已提交
323
		goto end;
324
	}
325
	status = acpi_ec_transaction_unlocked(ec, t, force_poll);
326
end:
327
	if (ec->global_lock)
L
Linus Torvalds 已提交
328
		acpi_release_global_lock(glk);
329
unlock:
330
	mutex_unlock(&ec->lock);
331
	return status;
L
Linus Torvalds 已提交
332 333
}

334 335 336 337 338 339 340
/*
 * Note: samsung nv5000 doesn't work with ec burst mode.
 * http://bugzilla.kernel.org/show_bug.cgi?id=4980
 */
int acpi_ec_burst_enable(struct acpi_ec *ec)
{
	u8 d;
341 342 343 344 345
	struct transaction t = {.command = ACPI_EC_BURST_ENABLE,
				.wdata = NULL, .rdata = &d,
				.wlen = 0, .rlen = 1};

	return acpi_ec_transaction(ec, &t, 0);
346 347 348 349
}

int acpi_ec_burst_disable(struct acpi_ec *ec)
{
350 351 352 353
	struct transaction t = {.command = ACPI_EC_BURST_DISABLE,
				.wdata = NULL, .rdata = NULL,
				.wlen = 0, .rlen = 0};

354
	return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
355
				acpi_ec_transaction(ec, &t, 0) : 0;
356 357
}

A
Alexey Starikovskiy 已提交
358
static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
359 360 361
{
	int result;
	u8 d;
362 363 364
	struct transaction t = {.command = ACPI_EC_COMMAND_READ,
				.wdata = &address, .rdata = &d,
				.wlen = 1, .rlen = 1};
365

366
	result = acpi_ec_transaction(ec, &t, 0);
367 368 369
	*data = d;
	return result;
}
370

371 372
static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
{
A
Alexey Starikovskiy 已提交
373
	u8 wdata[2] = { address, data };
374 375 376 377 378
	struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
				.wdata = wdata, .rdata = NULL,
				.wlen = 2, .rlen = 0};

	return acpi_ec_transaction(ec, &t, 0);
379 380
}

L
Linus Torvalds 已提交
381 382 383
/*
 * Externally callable EC access functions. For now, assume 1 EC only
 */
384 385 386 387
int ec_burst_enable(void)
{
	if (!first_ec)
		return -ENODEV;
388
	return acpi_ec_burst_enable(first_ec);
389 390 391 392 393 394 395 396
}

EXPORT_SYMBOL(ec_burst_enable);

int ec_burst_disable(void)
{
	if (!first_ec)
		return -ENODEV;
397
	return acpi_ec_burst_disable(first_ec);
398 399 400 401
}

EXPORT_SYMBOL(ec_burst_disable);

A
Alexey Starikovskiy 已提交
402
int ec_read(u8 addr, u8 * val)
L
Linus Torvalds 已提交
403 404
{
	int err;
405
	u8 temp_data;
L
Linus Torvalds 已提交
406 407 408 409

	if (!first_ec)
		return -ENODEV;

410
	err = acpi_ec_read(first_ec, addr, &temp_data);
L
Linus Torvalds 已提交
411 412 413 414

	if (!err) {
		*val = temp_data;
		return 0;
L
Len Brown 已提交
415
	} else
L
Linus Torvalds 已提交
416 417
		return err;
}
L
Len Brown 已提交
418

L
Linus Torvalds 已提交
419 420
EXPORT_SYMBOL(ec_read);

L
Len Brown 已提交
421
int ec_write(u8 addr, u8 val)
L
Linus Torvalds 已提交
422 423 424 425 426 427
{
	int err;

	if (!first_ec)
		return -ENODEV;

428
	err = acpi_ec_write(first_ec, addr, val);
L
Linus Torvalds 已提交
429 430 431

	return err;
}
L
Len Brown 已提交
432

L
Linus Torvalds 已提交
433 434
EXPORT_SYMBOL(ec_write);

435
int ec_transaction(u8 command,
436
		   const u8 * wdata, unsigned wdata_len,
437 438
		   u8 * rdata, unsigned rdata_len,
		   int force_poll)
L
Luming Yu 已提交
439
{
440 441 442
	struct transaction t = {.command = command,
				.wdata = wdata, .rdata = rdata,
				.wlen = wdata_len, .rlen = rdata_len};
443 444
	if (!first_ec)
		return -ENODEV;
L
Luming Yu 已提交
445

446
	return acpi_ec_transaction(first_ec, &t, force_poll);
L
Luming Yu 已提交
447
}
L
Linus Torvalds 已提交
448

449 450
EXPORT_SYMBOL(ec_transaction);

A
Alexey Starikovskiy 已提交
451
static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
452 453
{
	int result;
A
Alexey Starikovskiy 已提交
454
	u8 d;
455 456 457
	struct transaction t = {.command = ACPI_EC_COMMAND_QUERY,
				.wdata = NULL, .rdata = &d,
				.wlen = 0, .rlen = 1};
A
Alexey Starikovskiy 已提交
458 459
	if (!ec || !data)
		return -EINVAL;
L
Linus Torvalds 已提交
460

A
Alexey Starikovskiy 已提交
461 462 463 464 465
	/*
	 * Query the EC to find out which _Qxx method we need to evaluate.
	 * Note that successful completion of the query causes the ACPI_EC_SCI
	 * bit to be cleared (and thus clearing the interrupt source).
	 */
466

467
	result = acpi_ec_transaction(ec, &t, 0);
A
Alexey Starikovskiy 已提交
468 469
	if (result)
		return result;
L
Linus Torvalds 已提交
470

A
Alexey Starikovskiy 已提交
471 472
	if (!d)
		return -ENODATA;
L
Linus Torvalds 已提交
473

A
Alexey Starikovskiy 已提交
474 475
	*data = d;
	return 0;
L
Linus Torvalds 已提交
476 477 478 479 480
}

/* --------------------------------------------------------------------------
                                Event Management
   -------------------------------------------------------------------------- */
481 482 483 484 485 486 487 488 489 490 491 492 493 494
int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
			      acpi_handle handle, acpi_ec_query_func func,
			      void *data)
{
	struct acpi_ec_query_handler *handler =
	    kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL);
	if (!handler)
		return -ENOMEM;

	handler->query_bit = query_bit;
	handler->handle = handle;
	handler->func = func;
	handler->data = data;
	mutex_lock(&ec->lock);
495
	list_add(&handler->node, &ec->list);
496 497 498 499 500 501 502 503
	mutex_unlock(&ec->lock);
	return 0;
}

EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);

void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
{
A
Adrian Bunk 已提交
504
	struct acpi_ec_query_handler *handler, *tmp;
505
	mutex_lock(&ec->lock);
A
Adrian Bunk 已提交
506
	list_for_each_entry_safe(handler, tmp, &ec->list, node) {
507 508 509 510 511 512 513 514 515
		if (query_bit == handler->query_bit) {
			list_del(&handler->node);
			kfree(handler);
		}
	}
	mutex_unlock(&ec->lock);
}

EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
L
Linus Torvalds 已提交
516

L
Len Brown 已提交
517
static void acpi_ec_gpe_query(void *ec_cxt)
L
Luming Yu 已提交
518
{
519
	struct acpi_ec *ec = ec_cxt;
520
	u8 value = 0;
521
	struct acpi_ec_query_handler *handler, copy;
L
Luming Yu 已提交
522

523
	if (!ec || acpi_ec_query(ec, &value))
524
		return;
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
	mutex_lock(&ec->lock);
	list_for_each_entry(handler, &ec->list, node) {
		if (value == handler->query_bit) {
			/* have custom handler for this bit */
			memcpy(&copy, handler, sizeof(copy));
			mutex_unlock(&ec->lock);
			if (copy.func) {
				copy.func(copy.data);
			} else if (copy.handle) {
				acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
			}
			return;
		}
	}
	mutex_unlock(&ec->lock);
L
Luming Yu 已提交
540
}
L
Linus Torvalds 已提交
541

L
Len Brown 已提交
542
static u32 acpi_ec_gpe_handler(void *data)
L
Linus Torvalds 已提交
543
{
544
	struct acpi_ec *ec = data;
545
	u8 status;
546

547
	pr_debug(PREFIX "~~~> interrupt\n");
548 549 550 551
	status = acpi_ec_read_status(ec);

	gpe_transaction(ec, status);
	if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
552
		wake_up(&ec->wait);
D
Dmitry Torokhov 已提交
553

554 555 556
	ec_check_sci(ec, status);
	if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
	    !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
557
		/* this is non-query, must be confirmation */
558 559 560
		if (printk_ratelimit())
			pr_info(PREFIX "non-query interrupt received,"
				" switching to interrupt mode\n");
561
		set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
562
	}
563
	return ACPI_INTERRUPT_HANDLED;
A
Alexey Starikovskiy 已提交
564 565
}

L
Linus Torvalds 已提交
566 567 568 569 570
/* --------------------------------------------------------------------------
                             Address Space Management
   -------------------------------------------------------------------------- */

static acpi_status
571 572
acpi_ec_space_handler(u32 function, acpi_physical_address address,
		      u32 bits, acpi_integer *value,
L
Len Brown 已提交
573
		      void *handler_context, void *region_context)
L
Linus Torvalds 已提交
574
{
575
	struct acpi_ec *ec = handler_context;
576
	int result = 0, i;
577
	u8 temp = 0;
L
Linus Torvalds 已提交
578 579

	if ((address > 0xFF) || !value || !handler_context)
580
		return AE_BAD_PARAMETER;
L
Linus Torvalds 已提交
581

582
	if (function != ACPI_READ && function != ACPI_WRITE)
583
		return AE_BAD_PARAMETER;
L
Linus Torvalds 已提交
584

585 586
	if (bits != 8 && acpi_strict)
		return AE_BAD_PARAMETER;
L
Linus Torvalds 已提交
587

588 589
	acpi_ec_burst_enable(ec);

590 591 592 593 594 595 596 597 598 599
	if (function == ACPI_READ) {
		result = acpi_ec_read(ec, address, &temp);
		*value = temp;
	} else {
		temp = 0xff & (*value);
		result = acpi_ec_write(ec, address, temp);
	}

	for (i = 8; unlikely(bits - i > 0); i += 8) {
		++address;
600 601 602 603 604 605 606
		if (function == ACPI_READ) {
			result = acpi_ec_read(ec, address, &temp);
			(*value) |= ((acpi_integer)temp) << i;
		} else {
			temp = 0xff & ((*value) >> i);
			result = acpi_ec_write(ec, address, temp);
		}
L
Linus Torvalds 已提交
607 608
	}

609 610
	acpi_ec_burst_disable(ec);

L
Linus Torvalds 已提交
611 612
	switch (result) {
	case -EINVAL:
613
		return AE_BAD_PARAMETER;
L
Linus Torvalds 已提交
614 615
		break;
	case -ENODEV:
616
		return AE_NOT_FOUND;
L
Linus Torvalds 已提交
617 618
		break;
	case -ETIME:
619
		return AE_TIME;
L
Linus Torvalds 已提交
620 621
		break;
	default:
622
		return AE_OK;
L
Linus Torvalds 已提交
623 624 625 626 627 628 629
	}
}

/* --------------------------------------------------------------------------
                              FS Interface (/proc)
   -------------------------------------------------------------------------- */

L
Len Brown 已提交
630
static struct proc_dir_entry *acpi_ec_dir;
L
Linus Torvalds 已提交
631

L
Len Brown 已提交
632
static int acpi_ec_read_info(struct seq_file *seq, void *offset)
L
Linus Torvalds 已提交
633
{
634
	struct acpi_ec *ec = seq->private;
L
Linus Torvalds 已提交
635 636 637 638

	if (!ec)
		goto end;

639 640 641 642
	seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe);
	seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n",
		   (unsigned)ec->command_addr, (unsigned)ec->data_addr);
	seq_printf(seq, "use global lock:\t%s\n",
643
		   ec->global_lock ? "yes" : "no");
L
Len Brown 已提交
644
      end:
645
	return 0;
L
Linus Torvalds 已提交
646 647 648 649 650 651 652
}

static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
{
	return single_open(file, acpi_ec_read_info, PDE(inode)->data);
}

653
static struct file_operations acpi_ec_info_ops = {
L
Len Brown 已提交
654 655 656 657
	.open = acpi_ec_info_open_fs,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
L
Linus Torvalds 已提交
658 659 660
	.owner = THIS_MODULE,
};

L
Len Brown 已提交
661
static int acpi_ec_add_fs(struct acpi_device *device)
L
Linus Torvalds 已提交
662
{
L
Len Brown 已提交
663
	struct proc_dir_entry *entry = NULL;
L
Linus Torvalds 已提交
664 665 666

	if (!acpi_device_dir(device)) {
		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
L
Len Brown 已提交
667
						     acpi_ec_dir);
L
Linus Torvalds 已提交
668
		if (!acpi_device_dir(device))
669
			return -ENODEV;
L
Linus Torvalds 已提交
670 671
	}

672 673 674
	entry = proc_create_data(ACPI_EC_FILE_INFO, S_IRUGO,
				 acpi_device_dir(device),
				 &acpi_ec_info_ops, acpi_driver_data(device));
L
Linus Torvalds 已提交
675
	if (!entry)
676 677
		return -ENODEV;
	return 0;
L
Linus Torvalds 已提交
678 679
}

L
Len Brown 已提交
680
static int acpi_ec_remove_fs(struct acpi_device *device)
L
Linus Torvalds 已提交
681 682 683 684 685 686 687 688
{

	if (acpi_device_dir(device)) {
		remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
		remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
		acpi_device_dir(device) = NULL;
	}

689
	return 0;
L
Linus Torvalds 已提交
690 691 692 693 694
}

/* --------------------------------------------------------------------------
                               Driver Interface
   -------------------------------------------------------------------------- */
695 696 697 698 699 700 701 702
static acpi_status
ec_parse_io_ports(struct acpi_resource *resource, void *context);

static struct acpi_ec *make_acpi_ec(void)
{
	struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
	if (!ec)
		return NULL;
703
	ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
704 705
	mutex_init(&ec->lock);
	init_waitqueue_head(&ec->wait);
706
	INIT_LIST_HEAD(&ec->list);
707
	spin_lock_init(&ec->curr_lock);
708 709
	return ec;
}
710

711 712 713 714 715 716 717 718 719 720 721 722 723
static acpi_status
acpi_ec_register_query_methods(acpi_handle handle, u32 level,
			       void *context, void **return_value)
{
	struct acpi_namespace_node *node = handle;
	struct acpi_ec *ec = context;
	int value = 0;
	if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
		acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
	}
	return AE_OK;
}

724 725
static acpi_status
ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
726
{
727 728 729 730 731 732 733
	acpi_status status;

	struct acpi_ec *ec = context;
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
				     ec_parse_io_ports, ec);
	if (ACPI_FAILURE(status))
		return status;
734 735 736

	/* Get GPE bit assignment (EC events). */
	/* TODO: Add support for _GPE returning a package */
737 738 739
	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
	if (ACPI_FAILURE(status))
		return status;
740 741 742
	/* Use the global lock for all EC transactions? */
	acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
	ec->handle = handle;
743
	return AE_CTRL_TERMINATE;
744 745
}

746 747 748 749
static void ec_remove_handlers(struct acpi_ec *ec)
{
	if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
				ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
750
		pr_err(PREFIX "failed to remove space handler\n");
751 752
	if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
				&acpi_ec_gpe_handler)))
753
		pr_err(PREFIX "failed to remove gpe handler\n");
754
	clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
755 756
}

757
static int acpi_ec_add(struct acpi_device *device)
L
Linus Torvalds 已提交
758
{
759
	struct acpi_ec *ec = NULL;
L
Luming Yu 已提交
760 761

	if (!device)
762
		return -EINVAL;
763 764 765
	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_EC_CLASS);

766
	/* Check for boot EC */
767 768 769 770 771 772 773 774 775 776 777 778 779
	if (boot_ec &&
	    (boot_ec->handle == device->handle ||
	     boot_ec->handle == ACPI_ROOT_OBJECT)) {
		ec = boot_ec;
		boot_ec = NULL;
	} else {
		ec = make_acpi_ec();
		if (!ec)
			return -ENOMEM;
		if (ec_parse_device(device->handle, 0, ec, NULL) !=
		    AE_CTRL_TERMINATE) {
			kfree(ec);
			return -EINVAL;
780 781 782
		}
	}

783
	ec->handle = device->handle;
784 785 786 787 788

	/* Find and register all query methods */
	acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
			    acpi_ec_register_query_methods, ec, NULL);

789 790
	if (!first_ec)
		first_ec = ec;
791 792
	acpi_driver_data(device) = ec;
	acpi_ec_add_fs(device);
793
	pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
794
			  ec->gpe, ec->command_addr, ec->data_addr);
795
	pr_info(PREFIX "driver started in %s mode\n",
796
		(test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll");
797
	return 0;
L
Linus Torvalds 已提交
798 799
}

L
Len Brown 已提交
800
static int acpi_ec_remove(struct acpi_device *device, int type)
L
Linus Torvalds 已提交
801
{
802
	struct acpi_ec *ec;
803
	struct acpi_ec_query_handler *handler, *tmp;
L
Linus Torvalds 已提交
804 805

	if (!device)
806
		return -EINVAL;
L
Linus Torvalds 已提交
807 808

	ec = acpi_driver_data(device);
809
	mutex_lock(&ec->lock);
810
	list_for_each_entry_safe(handler, tmp, &ec->list, node) {
811 812 813 814
		list_del(&handler->node);
		kfree(handler);
	}
	mutex_unlock(&ec->lock);
L
Linus Torvalds 已提交
815
	acpi_ec_remove_fs(device);
816
	acpi_driver_data(device) = NULL;
817
	if (ec == first_ec)
818
		first_ec = NULL;
819
	kfree(ec);
820
	return 0;
L
Linus Torvalds 已提交
821 822 823
}

static acpi_status
824
ec_parse_io_ports(struct acpi_resource *resource, void *context)
L
Linus Torvalds 已提交
825
{
826
	struct acpi_ec *ec = context;
L
Linus Torvalds 已提交
827

828
	if (resource->type != ACPI_RESOURCE_TYPE_IO)
L
Linus Torvalds 已提交
829 830 831 832 833 834 835
		return AE_OK;

	/*
	 * The first address region returned is the data port, and
	 * the second address region returned is the status/command
	 * port.
	 */
836
	if (ec->data_addr == 0)
837
		ec->data_addr = resource->data.io.minimum;
838
	else if (ec->command_addr == 0)
839
		ec->command_addr = resource->data.io.minimum;
840
	else
L
Linus Torvalds 已提交
841 842 843 844 845
		return AE_CTRL_TERMINATE;

	return AE_OK;
}

846 847
static int ec_install_handlers(struct acpi_ec *ec)
{
848
	acpi_status status;
849
	if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags))
850
		return 0;
851
	status = acpi_install_gpe_handler(NULL, ec->gpe,
852 853
				  ACPI_GPE_EDGE_TRIGGERED,
				  &acpi_ec_gpe_handler, ec);
854 855 856 857 858 859 860
	if (ACPI_FAILURE(status))
		return -ENODEV;
	acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
	status = acpi_install_address_space_handler(ec->handle,
						    ACPI_ADR_SPACE_EC,
						    &acpi_ec_space_handler,
861
						    NULL, ec);
862 863 864 865 866
	if (ACPI_FAILURE(status)) {
		acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
		return -ENODEV;
	}

867
	set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
868 869 870
	return 0;
}

L
Len Brown 已提交
871
static int acpi_ec_start(struct acpi_device *device)
L
Linus Torvalds 已提交
872
{
873
	struct acpi_ec *ec;
874
	int ret = 0;
L
Linus Torvalds 已提交
875 876

	if (!device)
877
		return -EINVAL;
L
Linus Torvalds 已提交
878 879 880 881

	ec = acpi_driver_data(device);

	if (!ec)
882
		return -EINVAL;
L
Linus Torvalds 已提交
883

884
	ret = ec_install_handlers(ec);
885 886

	/* EC is fully operational, allow queries */
887
	clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
888
	return ret;
L
Linus Torvalds 已提交
889 890
}

L
Len Brown 已提交
891
static int acpi_ec_stop(struct acpi_device *device, int type)
L
Linus Torvalds 已提交
892
{
893
	struct acpi_ec *ec;
L
Linus Torvalds 已提交
894
	if (!device)
895
		return -EINVAL;
L
Linus Torvalds 已提交
896
	ec = acpi_driver_data(device);
897 898
	if (!ec)
		return -EINVAL;
899
	ec_remove_handlers(ec);
900

901
	return 0;
L
Linus Torvalds 已提交
902 903
}

904 905
int __init acpi_boot_ec_enable(void)
{
906
	if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags))
907 908 909 910 911 912 913 914
		return 0;
	if (!ec_install_handlers(boot_ec)) {
		first_ec = boot_ec;
		return 0;
	}
	return -EFAULT;
}

915 916 917 918 919
static const struct acpi_device_id ec_device_ids[] = {
	{"PNP0C09", 0},
	{"", 0},
};

920 921 922 923
int __init acpi_ec_ecdt_probe(void)
{
	int ret;
	acpi_status status;
L
Len Brown 已提交
924
	struct acpi_table_ecdt *ecdt_ptr;
L
Luming Yu 已提交
925

926 927
	boot_ec = make_acpi_ec();
	if (!boot_ec)
928 929 930 931
		return -ENOMEM;
	/*
	 * Generate a boot ec context
	 */
932 933
	status = acpi_get_table(ACPI_SIG_ECDT, 1,
				(struct acpi_table_header **)&ecdt_ptr);
934
	if (ACPI_SUCCESS(status)) {
935
		pr_info(PREFIX "EC description table is found, configuring boot EC\n");
936 937
		boot_ec->command_addr = ecdt_ptr->control.address;
		boot_ec->data_addr = ecdt_ptr->data.address;
938 939 940 941 942 943 944 945 946
		if (dmi_check_system(ec_dmi_table)) {
			/*
			 * If the board falls into ec_dmi_table, it means
			 * that ECDT table gives the incorrect command/status
			 * & data I/O address. Just fix it.
			 */
			boot_ec->data_addr = ecdt_ptr->control.address;
			boot_ec->command_addr = ecdt_ptr->data.address;
		}
947
		boot_ec->gpe = ecdt_ptr->gpe;
948
		boot_ec->handle = ACPI_ROOT_OBJECT;
949
		acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
950
	} else {
951 952 953
		/* This workaround is needed only on some broken machines,
		 * which require early EC, but fail to provide ECDT */
		acpi_handle x;
954 955 956
		printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
		status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
						boot_ec, NULL);
957 958
		/* Check that acpi_get_devices actually find something */
		if (ACPI_FAILURE(status) || !boot_ec->handle)
959
			goto error;
960 961
		/* We really need to limit this workaround, the only ASUS,
		 * which needs it, has fake EC._INI method, so use it as flag.
962
		 * Keep boot_ec struct as it will be needed soon.
963 964
		 */
		if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x)))
965
			return -ENODEV;
966
	}
L
Linus Torvalds 已提交
967

968
	ret = ec_install_handlers(boot_ec);
969 970
	if (!ret) {
		first_ec = boot_ec;
971
		return 0;
972
	}
973
      error:
974 975
	kfree(boot_ec);
	boot_ec = NULL;
L
Linus Torvalds 已提交
976 977 978
	return -ENODEV;
}

979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
{
	struct acpi_ec *ec = acpi_driver_data(device);
	/* Stop using GPE */
	set_bit(EC_FLAGS_NO_GPE, &ec->flags);
	clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
	acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
	return 0;
}

static int acpi_ec_resume(struct acpi_device *device)
{
	struct acpi_ec *ec = acpi_driver_data(device);
	/* Enable use of GPE back */
	clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
	return 0;
}

static struct acpi_driver acpi_ec_driver = {
	.name = "ec",
	.class = ACPI_EC_CLASS,
	.ids = ec_device_ids,
	.ops = {
		.add = acpi_ec_add,
		.remove = acpi_ec_remove,
		.start = acpi_ec_start,
		.stop = acpi_ec_stop,
		.suspend = acpi_ec_suspend,
		.resume = acpi_ec_resume,
		},
};

L
Len Brown 已提交
1012
static int __init acpi_ec_init(void)
L
Linus Torvalds 已提交
1013
{
L
Len Brown 已提交
1014
	int result = 0;
L
Linus Torvalds 已提交
1015 1016

	if (acpi_disabled)
1017
		return 0;
L
Linus Torvalds 已提交
1018 1019 1020

	acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
	if (!acpi_ec_dir)
1021
		return -ENODEV;
L
Linus Torvalds 已提交
1022 1023 1024 1025 1026

	/* Now register the driver for the EC */
	result = acpi_bus_register_driver(&acpi_ec_driver);
	if (result < 0) {
		remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
1027
		return -ENODEV;
L
Linus Torvalds 已提交
1028 1029
	}

1030
	return result;
L
Linus Torvalds 已提交
1031 1032 1033 1034 1035 1036
}

subsys_initcall(acpi_ec_init);

/* EC driver currently not unloadable */
#if 0
L
Len Brown 已提交
1037
static void __exit acpi_ec_exit(void)
L
Linus Torvalds 已提交
1038 1039 1040 1041 1042 1043
{

	acpi_bus_unregister_driver(&acpi_ec_driver);

	remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);

1044
	return;
L
Linus Torvalds 已提交
1045
}
1046
#endif	/* 0 */