1 /*
2  *  acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 36 $)
3  *
4  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6  *
7  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or (at
12  *  your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful, but
15  *  WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License along
20  *  with this program; if not, write to the Free Software Foundation, Inc.,
21  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22  *
23  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24  */
25 
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/types.h>
30 #include <linux/delay.h>
31 #include <linux/compatmac.h>
32 #include <linux/proc_fs.h>
33 #include <asm/io.h>
34 #include <acpi/acpi_bus.h>
35 #include <acpi/acpi_drivers.h>
36 #include <acpi/actypes.h>
37 
38 #define _COMPONENT		ACPI_EC_COMPONENT
39 ACPI_MODULE_NAME		("acpi_ec")
40 
41 #define PREFIX			"ACPI: "
42 
43 
44 #define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */
45 #define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */
46 #define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */
47 
48 #define ACPI_EC_EVENT_OBF	0x01	/* Output buffer full */
49 #define ACPI_EC_EVENT_IBE	0x02	/* Input buffer empty */
50 
51 #define ACPI_EC_UDELAY		100	/* Poll @ 100us increments */
52 #define ACPI_EC_UDELAY_COUNT	1000	/* Wait 10ms max. during EC ops */
53 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
54 
55 #define ACPI_EC_COMMAND_READ	0x80
56 #define ACPI_EC_COMMAND_WRITE	0x81
57 #define ACPI_EC_COMMAND_QUERY	0x84
58 
59 static int acpi_ec_add (struct acpi_device *device);
60 static int acpi_ec_remove (struct acpi_device *device, int type);
61 static int acpi_ec_start (struct acpi_device *device);
62 static int acpi_ec_stop (struct acpi_device *device, int type);
63 
64 static struct acpi_driver acpi_ec_driver = {
65 	.name =		ACPI_EC_DRIVER_NAME,
66 	.class =	ACPI_EC_CLASS,
67 	.ids =		ACPI_EC_HID,
68 	.ops =		{
69 				.add =		acpi_ec_add,
70 				.remove =	acpi_ec_remove,
71 				.start =	acpi_ec_start,
72 				.stop =		acpi_ec_stop,
73 			},
74 };
75 
76 struct acpi_ec {
77 	acpi_handle			handle;
78 	unsigned long			uid;
79 	unsigned long			gpe_bit;
80 	struct acpi_generic_address	status_addr;
81 	struct acpi_generic_address	command_addr;
82 	struct acpi_generic_address	data_addr;
83 	unsigned long			global_lock;
84 	spinlock_t			lock;
85 };
86 
87 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
88 static struct acpi_ec	*ec_ecdt;
89 
90 /* External interfaces use first EC only, so remember */
91 static struct acpi_device *first_ec;
92 
93 /* --------------------------------------------------------------------------
94                              Transaction Management
95    -------------------------------------------------------------------------- */
96 
97 static int
acpi_ec_wait(struct acpi_ec * ec,u8 event)98 acpi_ec_wait (
99 	struct acpi_ec		*ec,
100 	u8			event)
101 {
102 	u32			acpi_ec_status = 0;
103 	u32			i = ACPI_EC_UDELAY_COUNT;
104 
105 	if (!ec)
106 		return -EINVAL;
107 
108 	/* Poll the EC status register waiting for the event to occur. */
109 	switch (event) {
110 	case ACPI_EC_EVENT_OBF:
111 		do {
112 			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
113 			if (acpi_ec_status & ACPI_EC_FLAG_OBF)
114 				return 0;
115 			udelay(ACPI_EC_UDELAY);
116 		} while (--i>0);
117 		break;
118 	case ACPI_EC_EVENT_IBE:
119 		do {
120 			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
121 			if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
122 				return 0;
123 			udelay(ACPI_EC_UDELAY);
124 		} while (--i>0);
125 		break;
126 	default:
127 		return -EINVAL;
128 	}
129 
130 	return -ETIME;
131 }
132 
133 
134 static int
acpi_ec_read(struct acpi_ec * ec,u8 address,u32 * data)135 acpi_ec_read (
136 	struct acpi_ec		*ec,
137 	u8			address,
138 	u32			*data)
139 {
140 	acpi_status		status = AE_OK;
141 	int			result = 0;
142 	unsigned long		flags = 0;
143 	u32			glk = 0;
144 
145 	ACPI_FUNCTION_TRACE("acpi_ec_read");
146 
147 	if (!ec || !data)
148 		return_VALUE(-EINVAL);
149 
150 	*data = 0;
151 
152 	if (ec->global_lock) {
153 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
154 		if (ACPI_FAILURE(status))
155 			return_VALUE(-ENODEV);
156 	}
157 
158 	spin_lock_irqsave(&ec->lock, flags);
159 
160 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
161 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
162 	if (result)
163 		goto end;
164 
165 	acpi_hw_low_level_write(8, address, &ec->data_addr);
166 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
167 	if (result)
168 		goto end;
169 
170 
171 	acpi_hw_low_level_read(8, data, &ec->data_addr);
172 
173 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
174 		*data, address));
175 
176 end:
177 	spin_unlock_irqrestore(&ec->lock, flags);
178 
179 	if (ec->global_lock)
180 		acpi_release_global_lock(glk);
181 
182 	return_VALUE(result);
183 }
184 
185 
186 static int
acpi_ec_write(struct acpi_ec * ec,u8 address,u8 data)187 acpi_ec_write (
188 	struct acpi_ec		*ec,
189 	u8			address,
190 	u8			data)
191 {
192 	int			result = 0;
193 	acpi_status		status = AE_OK;
194 	unsigned long		flags = 0;
195 	u32			glk = 0;
196 
197 	ACPI_FUNCTION_TRACE("acpi_ec_write");
198 
199 	if (!ec)
200 		return_VALUE(-EINVAL);
201 
202 	if (ec->global_lock) {
203 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
204 		if (ACPI_FAILURE(status))
205 			return_VALUE(-ENODEV);
206 	}
207 
208 	spin_lock_irqsave(&ec->lock, flags);
209 
210 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
211 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
212 	if (result)
213 		goto end;
214 
215 	acpi_hw_low_level_write(8, address, &ec->data_addr);
216 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
217 	if (result)
218 		goto end;
219 
220 	acpi_hw_low_level_write(8, data, &ec->data_addr);
221 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
222 	if (result)
223 		goto end;
224 
225 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
226 		data, address));
227 
228 end:
229 	spin_unlock_irqrestore(&ec->lock, flags);
230 
231 	if (ec->global_lock)
232 		acpi_release_global_lock(glk);
233 
234 	return_VALUE(result);
235 }
236 
237 /*
238  * Externally callable EC access functions. For now, assume 1 EC only
239  */
240 int
ec_read(u8 addr,u8 * val)241 ec_read(u8 addr, u8 *val)
242 {
243 	struct acpi_ec *ec;
244 	int err;
245 	u32 temp_data;
246 
247 	if (!first_ec)
248 		return -ENODEV;
249 
250 	ec = acpi_driver_data(first_ec);
251 
252 	err = acpi_ec_read(ec, addr, &temp_data);
253 
254 	if (!err) {
255 		*val = temp_data;
256 		return 0;
257 	}
258 	else
259 		return err;
260 }
261 
262 int
ec_write(u8 addr,u8 val)263 ec_write(u8 addr, u8 val)
264 {
265 	struct acpi_ec *ec;
266 	int err;
267 
268 	if (!first_ec)
269 		return -ENODEV;
270 
271 	ec = acpi_driver_data(first_ec);
272 
273 	err = acpi_ec_write(ec, addr, val);
274 
275 	return err;
276 }
277 
278 
279 static int
acpi_ec_query(struct acpi_ec * ec,u32 * data)280 acpi_ec_query (
281 	struct acpi_ec		*ec,
282 	u32			*data)
283 {
284 	int			result = 0;
285 	acpi_status		status = AE_OK;
286 	unsigned long		flags = 0;
287 	u32			glk = 0;
288 
289 	ACPI_FUNCTION_TRACE("acpi_ec_query");
290 
291 	if (!ec || !data)
292 		return_VALUE(-EINVAL);
293 
294 	*data = 0;
295 
296 	if (ec->global_lock) {
297 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
298 		if (ACPI_FAILURE(status))
299 			return_VALUE(-ENODEV);
300 	}
301 
302 	/*
303 	 * Query the EC to find out which _Qxx method we need to evaluate.
304 	 * Note that successful completion of the query causes the ACPI_EC_SCI
305 	 * bit to be cleared (and thus clearing the interrupt source).
306 	 */
307 	spin_lock_irqsave(&ec->lock, flags);
308 
309 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
310 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
311 	if (result)
312 		goto end;
313 
314 	acpi_hw_low_level_read(8, data, &ec->data_addr);
315 	if (!*data)
316 		result = -ENODATA;
317 
318 end:
319 	spin_unlock_irqrestore(&ec->lock, flags);
320 
321 	if (ec->global_lock)
322 		acpi_release_global_lock(glk);
323 
324 	return_VALUE(result);
325 }
326 
327 
328 /* --------------------------------------------------------------------------
329                                 Event Management
330    -------------------------------------------------------------------------- */
331 
332 struct acpi_ec_query_data {
333 	acpi_handle		handle;
334 	u8			data;
335 };
336 
337 static void
acpi_ec_gpe_query(void * ec_cxt)338 acpi_ec_gpe_query (
339 	void			*ec_cxt)
340 {
341 	struct acpi_ec		*ec = (struct acpi_ec *) ec_cxt;
342 	u32			value = 0;
343 	unsigned long		flags = 0;
344 	static char		object_name[5] = {'_','Q','0','0','\0'};
345 	const char		hex[] = {'0','1','2','3','4','5','6','7',
346 				         '8','9','A','B','C','D','E','F'};
347 
348 	ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
349 
350 	if (!ec_cxt)
351 		goto end;
352 
353 	spin_lock_irqsave(&ec->lock, flags);
354 	acpi_hw_low_level_read(8, &value, &ec->command_addr);
355 	spin_unlock_irqrestore(&ec->lock, flags);
356 
357 	/* TBD: Implement asynch events!
358 	 * NOTE: All we care about are EC-SCI's.  Other EC events are
359 	 * handled via polling (yuck!).  This is because some systems
360 	 * treat EC-SCIs as level (versus EDGE!) triggered, preventing
361 	 *  a purely interrupt-driven approach (grumble, grumble).
362 	 */
363 	if (!(value & ACPI_EC_FLAG_SCI))
364 		goto end;
365 
366 	if (acpi_ec_query(ec, &value))
367 		goto end;
368 
369 	object_name[2] = hex[((value >> 4) & 0x0F)];
370 	object_name[3] = hex[(value & 0x0F)];
371 
372 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
373 
374 	acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
375 
376 end:
377 	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
378 }
379 
380 static void
acpi_ec_gpe_handler(void * data)381 acpi_ec_gpe_handler (
382 	void			*data)
383 {
384 	acpi_status		status = AE_OK;
385 	struct acpi_ec		*ec = (struct acpi_ec *) data;
386 
387 	if (!ec)
388 		return;
389 
390 	acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
391 
392 	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
393 		acpi_ec_gpe_query, ec);
394 }
395 
396 /* --------------------------------------------------------------------------
397                              Address Space Management
398    -------------------------------------------------------------------------- */
399 
400 static acpi_status
acpi_ec_space_setup(acpi_handle region_handle,u32 function,void * handler_context,void ** return_context)401 acpi_ec_space_setup (
402 	acpi_handle		region_handle,
403 	u32			function,
404 	void			*handler_context,
405 	void			**return_context)
406 {
407 	/*
408 	 * The EC object is in the handler context and is needed
409 	 * when calling the acpi_ec_space_handler.
410 	 */
411 	if(function == ACPI_REGION_DEACTIVATE)
412 		*return_context = NULL;
413 	else
414 		*return_context = handler_context;
415 
416 	return AE_OK;
417 }
418 
419 
420 static acpi_status
acpi_ec_space_handler(u32 function,acpi_physical_address address,u32 bit_width,acpi_integer * value,void * handler_context,void * region_context)421 acpi_ec_space_handler (
422 	u32			function,
423 	acpi_physical_address	address,
424 	u32			bit_width,
425 	acpi_integer		*value,
426 	void			*handler_context,
427 	void			*region_context)
428 {
429 	int			result = 0;
430 	struct acpi_ec		*ec = NULL;
431 	u32			temp = 0;
432 
433 	ACPI_FUNCTION_TRACE("acpi_ec_space_handler");
434 
435 	if ((address > 0xFF) || (bit_width != 8) || !value || !handler_context)
436 		return_VALUE(AE_BAD_PARAMETER);
437 
438 	ec = (struct acpi_ec *) handler_context;
439 
440 	switch (function) {
441 	case ACPI_READ:
442 		result = acpi_ec_read(ec, (u8) address, &temp);
443 		*value = (acpi_integer) temp;
444 		break;
445 	case ACPI_WRITE:
446 		result = acpi_ec_write(ec, (u8) address, (u8) *value);
447 		break;
448 	default:
449 		result = -EINVAL;
450 		break;
451 	}
452 
453 	switch (result) {
454 	case -EINVAL:
455 		return_VALUE(AE_BAD_PARAMETER);
456 		break;
457 	case -ENODEV:
458 		return_VALUE(AE_NOT_FOUND);
459 		break;
460 	case -ETIME:
461 		return_VALUE(AE_TIME);
462 		break;
463 	default:
464 		return_VALUE(AE_OK);
465 	}
466 
467 }
468 
469 
470 /* --------------------------------------------------------------------------
471                               FS Interface (/proc)
472    -------------------------------------------------------------------------- */
473 
474 struct proc_dir_entry		*acpi_ec_dir;
475 
476 
477 static int
acpi_ec_read_info(char * page,char ** start,off_t off,int count,int * eof,void * data)478 acpi_ec_read_info (
479 	char			*page,
480 	char			**start,
481 	off_t			off,
482 	int 			count,
483 	int 			*eof,
484 	void			*data)
485 {
486 	struct acpi_ec		*ec = (struct acpi_ec *) data;
487 	char			*p = page;
488 	int			len = 0;
489 
490 	ACPI_FUNCTION_TRACE("acpi_ec_read_info");
491 
492 	if (!ec || (off != 0))
493 		goto end;
494 
495 	p += sprintf(p, "gpe bit:                 0x%02x\n",
496 		(u32) ec->gpe_bit);
497 	p += sprintf(p, "ports:                   0x%02x, 0x%02x\n",
498 		(u32) ec->status_addr.address, (u32) ec->data_addr.address);
499 	p += sprintf(p, "use global lock:         %s\n",
500 		ec->global_lock?"yes":"no");
501 
502 end:
503 	len = (p - page);
504 	if (len <= off+count) *eof = 1;
505 	*start = page + off;
506 	len -= off;
507 	if (len>count) len = count;
508 	if (len<0) len = 0;
509 
510 	return_VALUE(len);
511 }
512 
513 
514 static int
acpi_ec_add_fs(struct acpi_device * device)515 acpi_ec_add_fs (
516 	struct acpi_device	*device)
517 {
518 	struct proc_dir_entry	*entry = NULL;
519 
520 	ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
521 
522 	if (!acpi_device_dir(device)) {
523 		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
524 			acpi_ec_dir);
525 		if (!acpi_device_dir(device))
526 			return_VALUE(-ENODEV);
527 	}
528 
529 	entry = create_proc_read_entry(ACPI_EC_FILE_INFO, S_IRUGO,
530 		acpi_device_dir(device), acpi_ec_read_info,
531 		acpi_driver_data(device));
532 	if (!entry)
533 		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
534 			"Unable to create '%s' fs entry\n",
535 			ACPI_EC_FILE_INFO));
536 
537 	return_VALUE(0);
538 }
539 
540 
541 static int
acpi_ec_remove_fs(struct acpi_device * device)542 acpi_ec_remove_fs (
543 	struct acpi_device	*device)
544 {
545 	ACPI_FUNCTION_TRACE("acpi_ec_remove_fs");
546 
547 	if (acpi_device_dir(device)) {
548 		remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
549 		remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
550 		acpi_device_dir(device) = NULL;
551 	}
552 
553 	return_VALUE(0);
554 }
555 
556 
557 /* --------------------------------------------------------------------------
558                                Driver Interface
559    -------------------------------------------------------------------------- */
560 
561 static int
acpi_ec_add(struct acpi_device * device)562 acpi_ec_add (
563 	struct acpi_device	*device)
564 {
565 	int			result = 0;
566 	acpi_status		status = AE_OK;
567 	struct acpi_ec		*ec = NULL;
568 	unsigned long		uid;
569 
570 	ACPI_FUNCTION_TRACE("acpi_ec_add");
571 
572 	if (!device)
573 		return_VALUE(-EINVAL);
574 
575 	ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
576 	if (!ec)
577 		return_VALUE(-ENOMEM);
578 	memset(ec, 0, sizeof(struct acpi_ec));
579 
580 	ec->handle = device->handle;
581 	ec->uid = -1;
582 	ec->lock = SPIN_LOCK_UNLOCKED;
583 	sprintf(acpi_device_name(device), "%s", ACPI_EC_DEVICE_NAME);
584 	sprintf(acpi_device_class(device), "%s", ACPI_EC_CLASS);
585 	acpi_driver_data(device) = ec;
586 
587 	/* Use the global lock for all EC transactions? */
588 	acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
589 
590 	/* If our UID matches the UID for the ECDT-enumerated EC,
591 	   we now have the *real* EC info, so kill the makeshift one.*/
592 	acpi_evaluate_integer(ec->handle, "_UID", NULL, &uid);
593 	if (ec_ecdt && ec_ecdt->uid == uid) {
594 		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
595 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
596 
597 		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
598 
599 		kfree(ec_ecdt);
600 	}
601 
602 	/* Get GPE bit assignment (EC events). */
603 	/* TODO: Add support for _GPE returning a package */
604 	status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit);
605 	if (ACPI_FAILURE(status)) {
606 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
607 			"Error obtaining GPE bit assignment\n"));
608 		result = -ENODEV;
609 		goto end;
610 	}
611 
612 	result = acpi_ec_add_fs(device);
613 	if (result)
614 		goto end;
615 
616 	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
617 		acpi_device_name(device), acpi_device_bid(device),
618 		(u32) ec->gpe_bit);
619 
620 	if (!first_ec)
621 		first_ec = device;
622 
623 end:
624 	if (result)
625 		kfree(ec);
626 
627 	return_VALUE(result);
628 }
629 
630 
631 static int
acpi_ec_remove(struct acpi_device * device,int type)632 acpi_ec_remove (
633 	struct acpi_device	*device,
634 	int			type)
635 {
636 	struct acpi_ec		*ec = NULL;
637 
638 	ACPI_FUNCTION_TRACE("acpi_ec_remove");
639 
640 	if (!device)
641 		return_VALUE(-EINVAL);
642 
643 	ec = acpi_driver_data(device);
644 
645 	acpi_ec_remove_fs(device);
646 
647 	kfree(ec);
648 
649 	return_VALUE(0);
650 }
651 
652 
653 static acpi_status
acpi_ec_io_ports(struct acpi_resource * resource,void * context)654 acpi_ec_io_ports (
655 	struct acpi_resource	*resource,
656 	void			*context)
657 {
658 	struct acpi_ec		*ec = (struct acpi_ec *) context;
659 	struct acpi_generic_address *addr;
660 
661 	if (resource->id != ACPI_RSTYPE_IO) {
662 		return AE_OK;
663 	}
664 
665 	/*
666 	 * The first address region returned is the data port, and
667 	 * the second address region returned is the status/command
668 	 * port.
669 	 */
670 	if (ec->data_addr.register_bit_width == 0) {
671 		addr = &ec->data_addr;
672 	} else if (ec->command_addr.register_bit_width == 0) {
673 		addr = &ec->command_addr;
674 	} else {
675 		return AE_CTRL_TERMINATE;
676 	}
677 
678 	addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
679 	addr->register_bit_width = 8;
680 	addr->register_bit_offset = 0;
681 	addr->address = resource->data.io.min_base_address;
682 
683 	return AE_OK;
684 }
685 
686 
687 static int
acpi_ec_start(struct acpi_device * device)688 acpi_ec_start (
689 	struct acpi_device	*device)
690 {
691 	acpi_status		status = AE_OK;
692 	struct acpi_ec		*ec = NULL;
693 
694 	ACPI_FUNCTION_TRACE("acpi_ec_start");
695 
696 	if (!device)
697 		return_VALUE(-EINVAL);
698 
699 	ec = acpi_driver_data(device);
700 
701 	if (!ec)
702 		return_VALUE(-EINVAL);
703 
704 	/*
705 	 * Get I/O port addresses. Convert to GAS format.
706 	 */
707 	status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
708 		acpi_ec_io_ports, ec);
709 	if (ACPI_FAILURE(status) || ec->command_addr.register_bit_width == 0) {
710 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
711 		return_VALUE(-ENODEV);
712 	}
713 
714 	ec->status_addr = ec->command_addr;
715 
716 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
717 		(u32) ec->gpe_bit, (u32) ec->command_addr.address,
718 		(u32) ec->data_addr.address));
719 
720 	/*
721 	 * Install GPE handler
722 	 */
723 	status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
724 		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
725 	if (ACPI_FAILURE(status)) {
726 		return_VALUE(-ENODEV);
727 	}
728 
729 	status = acpi_install_address_space_handler (ec->handle,
730 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
731 			&acpi_ec_space_setup, ec);
732 	if (ACPI_FAILURE(status)) {
733 		acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
734 		return_VALUE(-ENODEV);
735 	}
736 
737 	return_VALUE(AE_OK);
738 }
739 
740 
741 static int
acpi_ec_stop(struct acpi_device * device,int type)742 acpi_ec_stop (
743 	struct acpi_device	*device,
744 	int			type)
745 {
746 	acpi_status		status = AE_OK;
747 	struct acpi_ec		*ec = NULL;
748 
749 	ACPI_FUNCTION_TRACE("acpi_ec_stop");
750 
751 	if (!device)
752 		return_VALUE(-EINVAL);
753 
754 	ec = acpi_driver_data(device);
755 
756 	status = acpi_remove_address_space_handler(ec->handle,
757 		ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
758 	if (ACPI_FAILURE(status))
759 		return_VALUE(-ENODEV);
760 
761 	status = acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
762 	if (ACPI_FAILURE(status))
763 		return_VALUE(-ENODEV);
764 
765 	return_VALUE(0);
766 }
767 
768 
769 int __init
acpi_ec_ecdt_probe(void)770 acpi_ec_ecdt_probe (void)
771 {
772 	acpi_status		status;
773 	struct acpi_table_ecdt 	*ecdt_ptr;
774 
775 	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
776 		(struct acpi_table_header **) &ecdt_ptr);
777 	if (ACPI_FAILURE(status))
778 		return 0;
779 
780 	printk(KERN_INFO PREFIX "Found ECDT\n");
781 
782 	 /*
783 	 * Generate a temporary ec context to use until the namespace is scanned
784 	 */
785 	ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
786 	if (!ec_ecdt)
787 		return -ENOMEM;
788 	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
789 
790 	ec_ecdt->command_addr = ecdt_ptr->ec_control;
791 	ec_ecdt->status_addr = ecdt_ptr->ec_control;
792 	ec_ecdt->data_addr = ecdt_ptr->ec_data;
793 	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
794 	ec_ecdt->lock = SPIN_LOCK_UNLOCKED;
795 	/* use the GL just to be safe */
796 	ec_ecdt->global_lock = TRUE;
797 	ec_ecdt->uid = ecdt_ptr->uid;
798 
799 	status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
800 	if (ACPI_FAILURE(status)) {
801 		goto error;
802 	}
803 
804 	/*
805 	 * Install GPE handler
806 	 */
807 	status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
808 		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
809 		ec_ecdt);
810 	if (ACPI_FAILURE(status)) {
811 		goto error;
812 	}
813 
814 	status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
815 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
816 			&acpi_ec_space_setup, ec_ecdt);
817 	if (ACPI_FAILURE(status)) {
818 		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
819 			&acpi_ec_gpe_handler);
820 		goto error;
821 	}
822 
823 	return 0;
824 
825 error:
826 	printk(KERN_ERR PREFIX "Could not use ECDT\n");
827 	kfree(ec_ecdt);
828 	ec_ecdt = NULL;
829 
830 	return -ENODEV;
831 }
832 
833 
834 int __init
acpi_ec_init(void)835 acpi_ec_init (void)
836 {
837 	int			result = 0;
838 
839 	ACPI_FUNCTION_TRACE("acpi_ec_init");
840 
841 	acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
842 	if (!acpi_ec_dir)
843 		return_VALUE(-ENODEV);
844 
845 	result = acpi_bus_register_driver(&acpi_ec_driver);
846 	if (result < 0) {
847 		remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
848 		return_VALUE(-ENODEV);
849 	}
850 
851 	return_VALUE(0);
852 }
853 
854 /* EC can't be unloaded atm, so don't compile these */
855 #if 0
856 void __exit
857 acpi_ec_exit (void)
858 {
859 	ACPI_FUNCTION_TRACE("acpi_ec_exit");
860 
861 	acpi_bus_unregister_driver(&acpi_ec_driver);
862 
863 	remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
864 
865 	return_VOID;
866 }
867 #endif /* 0 */
868 
869