1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/slab.h>
33#include <linux/mm.h>
34#include <linux/pci.h>
35#include <linux/interrupt.h>
36#include <linux/kmod.h>
37#include <linux/delay.h>
38#include <linux/dmi.h>
39#include <linux/workqueue.h>
40#include <linux/nmi.h>
41#include <linux/acpi.h>
42#include <linux/efi.h>
43#include <linux/ioport.h>
44#include <linux/list.h>
45#include <linux/jiffies.h>
46#include <linux/semaphore.h>
47
48#include <asm/io.h>
49#include <asm/uaccess.h>
50
51#include <acpi/acpi.h>
52#include <acpi/acpi_bus.h>
53#include <acpi/processor.h>
54
55#define _COMPONENT ACPI_OS_SERVICES
56ACPI_MODULE_NAME("osl");
57#define PREFIX "ACPI: "
58struct acpi_os_dpc {
59 acpi_osd_exec_callback function;
60 void *context;
61 struct work_struct work;
62};
63
64#ifdef CONFIG_ACPI_CUSTOM_DSDT
65#include CONFIG_ACPI_CUSTOM_DSDT_FILE
66#endif
67
68#ifdef ENABLE_DEBUGGER
69#include <linux/kdb.h>
70
71
72int acpi_in_debugger;
73EXPORT_SYMBOL(acpi_in_debugger);
74
75extern char line_buf[80];
76#endif
77
78static unsigned int acpi_irq_irq;
79static acpi_osd_handler acpi_irq_handler;
80static void *acpi_irq_context;
81static struct workqueue_struct *kacpid_wq;
82static struct workqueue_struct *kacpi_notify_wq;
83
84struct acpi_res_list {
85 resource_size_t start;
86 resource_size_t end;
87 acpi_adr_space_type resource_type;
88 char name[5];
89
90 struct list_head resource_list;
91};
92
93static LIST_HEAD(resource_list_head);
94static DEFINE_SPINLOCK(acpi_res_lock);
95
96#define OSI_STRING_LENGTH_MAX 64
97static char osi_additional_string[OSI_STRING_LENGTH_MAX];
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140#define OSI_LINUX_ENABLE 0
141
142static struct osi_linux {
143 unsigned int enable:1;
144 unsigned int dmi:1;
145 unsigned int cmdline:1;
146 unsigned int known:1;
147} osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0};
148
149static void __init acpi_request_region (struct acpi_generic_address *addr,
150 unsigned int length, char *desc)
151{
152 struct resource *res;
153
154 if (!addr->address || !length)
155 return;
156
157 if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
158 res = request_region(addr->address, length, desc);
159 else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
160 res = request_mem_region(addr->address, length, desc);
161}
162
163static int __init acpi_reserve_resources(void)
164{
165 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
166 "ACPI PM1a_EVT_BLK");
167
168 acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
169 "ACPI PM1b_EVT_BLK");
170
171 acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
172 "ACPI PM1a_CNT_BLK");
173
174 acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
175 "ACPI PM1b_CNT_BLK");
176
177 if (acpi_gbl_FADT.pm_timer_length == 4)
178 acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
179
180 acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
181 "ACPI PM2_CNT_BLK");
182
183
184
185 if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
186 acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
187 acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
188
189 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
190 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
191 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
192
193 return 0;
194}
195device_initcall(acpi_reserve_resources);
196
197acpi_status __init acpi_os_initialize(void)
198{
199 return AE_OK;
200}
201
202acpi_status acpi_os_initialize1(void)
203{
204 kacpid_wq = create_singlethread_workqueue("kacpid");
205 kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
206 BUG_ON(!kacpid_wq);
207 BUG_ON(!kacpi_notify_wq);
208 return AE_OK;
209}
210
211acpi_status acpi_os_terminate(void)
212{
213 if (acpi_irq_handler) {
214 acpi_os_remove_interrupt_handler(acpi_irq_irq,
215 acpi_irq_handler);
216 }
217
218 destroy_workqueue(kacpid_wq);
219 destroy_workqueue(kacpi_notify_wq);
220
221 return AE_OK;
222}
223
224void acpi_os_printf(const char *fmt, ...)
225{
226 va_list args;
227 va_start(args, fmt);
228 acpi_os_vprintf(fmt, args);
229 va_end(args);
230}
231
232void acpi_os_vprintf(const char *fmt, va_list args)
233{
234 static char buffer[512];
235
236 vsprintf(buffer, fmt, args);
237
238#ifdef ENABLE_DEBUGGER
239 if (acpi_in_debugger) {
240 kdb_printf("%s", buffer);
241 } else {
242 printk("%s", buffer);
243 }
244#else
245 printk("%s", buffer);
246#endif
247}
248
249acpi_physical_address __init acpi_os_get_root_pointer(void)
250{
251 if (efi_enabled) {
252 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
253 return efi.acpi20;
254 else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
255 return efi.acpi;
256 else {
257 printk(KERN_ERR PREFIX
258 "System description tables not found\n");
259 return 0;
260 }
261 } else {
262 acpi_physical_address pa = 0;
263
264 acpi_find_root_pointer(&pa);
265 return pa;
266 }
267}
268
269void __iomem *__init_refok
270acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
271{
272 if (phys > ULONG_MAX) {
273 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
274 return NULL;
275 }
276 if (acpi_gbl_permanent_mmap)
277
278
279
280 return ioremap((unsigned long)phys, size);
281 else
282 return __acpi_map_table((unsigned long)phys, size);
283}
284EXPORT_SYMBOL_GPL(acpi_os_map_memory);
285
286void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
287{
288 if (acpi_gbl_permanent_mmap) {
289 iounmap(virt);
290 }
291}
292EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
293
294#ifdef ACPI_FUTURE_USAGE
295acpi_status
296acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
297{
298 if (!phys || !virt)
299 return AE_BAD_PARAMETER;
300
301 *phys = virt_to_phys(virt);
302
303 return AE_OK;
304}
305#endif
306
307#define ACPI_MAX_OVERRIDE_LEN 100
308
309static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
310
311acpi_status
312acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
313 acpi_string * new_val)
314{
315 if (!init_val || !new_val)
316 return AE_BAD_PARAMETER;
317
318 *new_val = NULL;
319 if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
320 printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
321 acpi_os_name);
322 *new_val = acpi_os_name;
323 }
324
325 return AE_OK;
326}
327
328acpi_status
329acpi_os_table_override(struct acpi_table_header * existing_table,
330 struct acpi_table_header ** new_table)
331{
332 if (!existing_table || !new_table)
333 return AE_BAD_PARAMETER;
334
335 *new_table = NULL;
336
337#ifdef CONFIG_ACPI_CUSTOM_DSDT
338 if (strncmp(existing_table->signature, "DSDT", 4) == 0)
339 *new_table = (struct acpi_table_header *)AmlCode;
340#endif
341 if (*new_table != NULL) {
342 printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
343 "this is unsafe: tainting kernel\n",
344 existing_table->signature,
345 existing_table->oem_table_id);
346 add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
347 }
348 return AE_OK;
349}
350
351static irqreturn_t acpi_irq(int irq, void *dev_id)
352{
353 u32 handled;
354
355 handled = (*acpi_irq_handler) (acpi_irq_context);
356
357 if (handled) {
358 acpi_irq_handled++;
359 return IRQ_HANDLED;
360 } else
361 return IRQ_NONE;
362}
363
364acpi_status
365acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
366 void *context)
367{
368 unsigned int irq;
369
370 acpi_irq_stats_init();
371
372
373
374
375
376
377 gsi = acpi_gbl_FADT.sci_interrupt;
378 if (acpi_gsi_to_irq(gsi, &irq) < 0) {
379 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
380 gsi);
381 return AE_OK;
382 }
383
384 acpi_irq_handler = handler;
385 acpi_irq_context = context;
386 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
387 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
388 return AE_NOT_ACQUIRED;
389 }
390 acpi_irq_irq = irq;
391
392 return AE_OK;
393}
394
395acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
396{
397 if (irq) {
398 free_irq(irq, acpi_irq);
399 acpi_irq_handler = NULL;
400 acpi_irq_irq = 0;
401 }
402
403 return AE_OK;
404}
405
406
407
408
409
410void acpi_os_sleep(acpi_integer ms)
411{
412 schedule_timeout_interruptible(msecs_to_jiffies(ms));
413}
414
415void acpi_os_stall(u32 us)
416{
417 while (us) {
418 u32 delay = 1000;
419
420 if (delay > us)
421 delay = us;
422 udelay(delay);
423 touch_nmi_watchdog();
424 us -= delay;
425 }
426}
427
428
429
430
431
432
433u64 acpi_os_get_timer(void)
434{
435 static u64 t;
436
437#ifdef CONFIG_HPET
438
439#endif
440
441#ifdef CONFIG_X86_PM_TIMER
442
443#endif
444 if (!t)
445 printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");
446
447 return ++t;
448}
449
450acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
451{
452 u32 dummy;
453
454 if (!value)
455 value = &dummy;
456
457 *value = 0;
458 if (width <= 8) {
459 *(u8 *) value = inb(port);
460 } else if (width <= 16) {
461 *(u16 *) value = inw(port);
462 } else if (width <= 32) {
463 *(u32 *) value = inl(port);
464 } else {
465 BUG();
466 }
467
468 return AE_OK;
469}
470
471EXPORT_SYMBOL(acpi_os_read_port);
472
473acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
474{
475 if (width <= 8) {
476 outb(value, port);
477 } else if (width <= 16) {
478 outw(value, port);
479 } else if (width <= 32) {
480 outl(value, port);
481 } else {
482 BUG();
483 }
484
485 return AE_OK;
486}
487
488EXPORT_SYMBOL(acpi_os_write_port);
489
490acpi_status
491acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
492{
493 u32 dummy;
494 void __iomem *virt_addr;
495
496 virt_addr = ioremap(phys_addr, width);
497 if (!value)
498 value = &dummy;
499
500 switch (width) {
501 case 8:
502 *(u8 *) value = readb(virt_addr);
503 break;
504 case 16:
505 *(u16 *) value = readw(virt_addr);
506 break;
507 case 32:
508 *(u32 *) value = readl(virt_addr);
509 break;
510 default:
511 BUG();
512 }
513
514 iounmap(virt_addr);
515
516 return AE_OK;
517}
518
519acpi_status
520acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
521{
522 void __iomem *virt_addr;
523
524 virt_addr = ioremap(phys_addr, width);
525
526 switch (width) {
527 case 8:
528 writeb(value, virt_addr);
529 break;
530 case 16:
531 writew(value, virt_addr);
532 break;
533 case 32:
534 writel(value, virt_addr);
535 break;
536 default:
537 BUG();
538 }
539
540 iounmap(virt_addr);
541
542 return AE_OK;
543}
544
545acpi_status
546acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
547 u32 *value, u32 width)
548{
549 int result, size;
550
551 if (!value)
552 return AE_BAD_PARAMETER;
553
554 switch (width) {
555 case 8:
556 size = 1;
557 break;
558 case 16:
559 size = 2;
560 break;
561 case 32:
562 size = 4;
563 break;
564 default:
565 return AE_ERROR;
566 }
567
568 result = raw_pci_read(pci_id->segment, pci_id->bus,
569 PCI_DEVFN(pci_id->device, pci_id->function),
570 reg, size, value);
571
572 return (result ? AE_ERROR : AE_OK);
573}
574
575acpi_status
576acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
577 acpi_integer value, u32 width)
578{
579 int result, size;
580
581 switch (width) {
582 case 8:
583 size = 1;
584 break;
585 case 16:
586 size = 2;
587 break;
588 case 32:
589 size = 4;
590 break;
591 default:
592 return AE_ERROR;
593 }
594
595 result = raw_pci_write(pci_id->segment, pci_id->bus,
596 PCI_DEVFN(pci_id->device, pci_id->function),
597 reg, size, value);
598
599 return (result ? AE_ERROR : AE_OK);
600}
601
602
603static void acpi_os_derive_pci_id_2(acpi_handle rhandle,
604 acpi_handle chandle,
605 struct acpi_pci_id **id,
606 int *is_bridge, u8 * bus_number)
607{
608 acpi_handle handle;
609 struct acpi_pci_id *pci_id = *id;
610 acpi_status status;
611 unsigned long long temp;
612 acpi_object_type type;
613
614 acpi_get_parent(chandle, &handle);
615 if (handle != rhandle) {
616 acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge,
617 bus_number);
618
619 status = acpi_get_type(handle, &type);
620 if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
621 return;
622
623 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
624 &temp);
625 if (ACPI_SUCCESS(status)) {
626 u32 val;
627 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp));
628 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp));
629
630 if (*is_bridge)
631 pci_id->bus = *bus_number;
632
633
634 status =
635 acpi_os_read_pci_configuration(pci_id, 0x0e, &val,
636 8);
637 if (ACPI_SUCCESS(status)
638 && ((val & 0x7f) == 1 || (val & 0x7f) == 2)) {
639 status =
640 acpi_os_read_pci_configuration(pci_id, 0x18,
641 &val, 8);
642 if (!ACPI_SUCCESS(status)) {
643
644 return;
645 }
646 *is_bridge = 1;
647 pci_id->bus = val;
648 status =
649 acpi_os_read_pci_configuration(pci_id, 0x19,
650 &val, 8);
651 if (ACPI_SUCCESS(status)) {
652 *bus_number = val;
653 }
654 } else
655 *is_bridge = 0;
656 }
657 }
658}
659
660void acpi_os_derive_pci_id(acpi_handle rhandle,
661 acpi_handle chandle,
662 struct acpi_pci_id **id)
663{
664 int is_bridge = 1;
665 u8 bus_number = (*id)->bus;
666
667 acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
668}
669
670static void acpi_os_execute_deferred(struct work_struct *work)
671{
672 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
673 if (!dpc) {
674 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
675 return;
676 }
677
678 dpc->function(dpc->context);
679 kfree(dpc);
680
681 return;
682}
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699acpi_status acpi_os_execute(acpi_execute_type type,
700 acpi_osd_exec_callback function, void *context)
701{
702 acpi_status status = AE_OK;
703 struct acpi_os_dpc *dpc;
704 struct workqueue_struct *queue;
705 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
706 "Scheduling function [%p(%p)] for deferred execution.\n",
707 function, context));
708
709 if (!function)
710 return AE_BAD_PARAMETER;
711
712
713
714
715
716
717
718
719
720
721 dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
722 if (!dpc)
723 return_ACPI_STATUS(AE_NO_MEMORY);
724
725 dpc->function = function;
726 dpc->context = context;
727
728 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
729 queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq;
730 if (!queue_work(queue, &dpc->work)) {
731 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
732 "Call to queue_work() failed.\n"));
733 status = AE_ERROR;
734 kfree(dpc);
735 }
736 return_ACPI_STATUS(status);
737}
738
739EXPORT_SYMBOL(acpi_os_execute);
740
741void acpi_os_wait_events_complete(void *context)
742{
743 flush_workqueue(kacpid_wq);
744 flush_workqueue(kacpi_notify_wq);
745}
746
747EXPORT_SYMBOL(acpi_os_wait_events_complete);
748
749
750
751
752acpi_status acpi_os_create_lock(acpi_spinlock * handle)
753{
754 spin_lock_init(*handle);
755
756 return AE_OK;
757}
758
759
760
761
762void acpi_os_delete_lock(acpi_spinlock handle)
763{
764 return;
765}
766
767acpi_status
768acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
769{
770 struct semaphore *sem = NULL;
771
772 sem = acpi_os_allocate(sizeof(struct semaphore));
773 if (!sem)
774 return AE_NO_MEMORY;
775 memset(sem, 0, sizeof(struct semaphore));
776
777 sema_init(sem, initial_units);
778
779 *handle = (acpi_handle *) sem;
780
781 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n",
782 *handle, initial_units));
783
784 return AE_OK;
785}
786
787
788
789
790
791
792
793
794acpi_status acpi_os_delete_semaphore(acpi_handle handle)
795{
796 struct semaphore *sem = (struct semaphore *)handle;
797
798 if (!sem)
799 return AE_BAD_PARAMETER;
800
801 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
802
803 BUG_ON(!list_empty(&sem->wait_list));
804 kfree(sem);
805 sem = NULL;
806
807 return AE_OK;
808}
809
810
811
812
813acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
814{
815 acpi_status status = AE_OK;
816 struct semaphore *sem = (struct semaphore *)handle;
817 long jiffies;
818 int ret = 0;
819
820 if (!sem || (units < 1))
821 return AE_BAD_PARAMETER;
822
823 if (units > 1)
824 return AE_SUPPORT;
825
826 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
827 handle, units, timeout));
828
829 if (timeout == ACPI_WAIT_FOREVER)
830 jiffies = MAX_SCHEDULE_TIMEOUT;
831 else
832 jiffies = msecs_to_jiffies(timeout);
833
834 ret = down_timeout(sem, jiffies);
835 if (ret)
836 status = AE_TIME;
837
838 if (ACPI_FAILURE(status)) {
839 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
840 "Failed to acquire semaphore[%p|%d|%d], %s",
841 handle, units, timeout,
842 acpi_format_exception(status)));
843 } else {
844 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
845 "Acquired semaphore[%p|%d|%d]", handle,
846 units, timeout));
847 }
848
849 return status;
850}
851
852
853
854
855acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
856{
857 struct semaphore *sem = (struct semaphore *)handle;
858
859 if (!sem || (units < 1))
860 return AE_BAD_PARAMETER;
861
862 if (units > 1)
863 return AE_SUPPORT;
864
865 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
866 units));
867
868 up(sem);
869
870 return AE_OK;
871}
872
873#ifdef ACPI_FUTURE_USAGE
874u32 acpi_os_get_line(char *buffer)
875{
876
877#ifdef ENABLE_DEBUGGER
878 if (acpi_in_debugger) {
879 u32 chars;
880
881 kdb_read(buffer, sizeof(line_buf));
882
883
884 chars = strlen(buffer) - 1;
885 buffer[chars] = '\0';
886 }
887#endif
888
889 return 0;
890}
891#endif
892
893acpi_status acpi_os_signal(u32 function, void *info)
894{
895 switch (function) {
896 case ACPI_SIGNAL_FATAL:
897 printk(KERN_ERR PREFIX "Fatal opcode executed\n");
898 break;
899 case ACPI_SIGNAL_BREAKPOINT:
900
901
902
903
904
905
906
907
908 break;
909 default:
910 break;
911 }
912
913 return AE_OK;
914}
915
916static int __init acpi_os_name_setup(char *str)
917{
918 char *p = acpi_os_name;
919 int count = ACPI_MAX_OVERRIDE_LEN - 1;
920
921 if (!str || !*str)
922 return 0;
923
924 for (; count-- && str && *str; str++) {
925 if (isalnum(*str) || *str == ' ' || *str == ':')
926 *p++ = *str;
927 else if (*str == '\'' || *str == '"')
928 continue;
929 else
930 break;
931 }
932 *p = 0;
933
934 return 1;
935
936}
937
938__setup("acpi_os_name=", acpi_os_name_setup);
939
940static void __init set_osi_linux(unsigned int enable)
941{
942 if (osi_linux.enable != enable) {
943 osi_linux.enable = enable;
944 printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
945 enable ? "Add": "Delet");
946 }
947 return;
948}
949
950static void __init acpi_cmdline_osi_linux(unsigned int enable)
951{
952 osi_linux.cmdline = 1;
953 set_osi_linux(enable);
954
955 return;
956}
957
958void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
959{
960 osi_linux.dmi = 1;
961
962 printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
963
964 if (enable == -1)
965 return;
966
967 osi_linux.known = 1;
968
969 set_osi_linux(enable);
970
971 return;
972}
973
974
975
976
977
978
979
980
981int __init acpi_osi_setup(char *str)
982{
983 if (str == NULL || *str == '\0') {
984 printk(KERN_INFO PREFIX "_OSI method disabled\n");
985 acpi_gbl_create_osi_method = FALSE;
986 } else if (!strcmp("!Linux", str)) {
987 acpi_cmdline_osi_linux(0);
988 } else if (*str == '!') {
989 if (acpi_osi_invalidate(++str) == AE_OK)
990 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
991 } else if (!strcmp("Linux", str)) {
992 acpi_cmdline_osi_linux(1);
993 } else if (*osi_additional_string == '\0') {
994 strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
995 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
996 }
997
998 return 1;
999}
1000
1001__setup("acpi_osi=", acpi_osi_setup);
1002
1003
1004static int __init acpi_serialize_setup(char *str)
1005{
1006 printk(KERN_INFO PREFIX "serialize enabled\n");
1007
1008 acpi_gbl_all_methods_serialized = TRUE;
1009
1010 return 1;
1011}
1012
1013__setup("acpi_serialize", acpi_serialize_setup);
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024static int __init acpi_wake_gpes_always_on_setup(char *str)
1025{
1026 printk(KERN_INFO PREFIX "wake GPEs not disabled\n");
1027
1028 acpi_gbl_leave_wake_gpes_disabled = FALSE;
1029
1030 return 1;
1031}
1032
1033__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051#define ENFORCE_RESOURCES_STRICT 2
1052#define ENFORCE_RESOURCES_LAX 1
1053#define ENFORCE_RESOURCES_NO 0
1054
1055static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
1056
1057static int __init acpi_enforce_resources_setup(char *str)
1058{
1059 if (str == NULL || *str == '\0')
1060 return 0;
1061
1062 if (!strcmp("strict", str))
1063 acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1064 else if (!strcmp("lax", str))
1065 acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
1066 else if (!strcmp("no", str))
1067 acpi_enforce_resources = ENFORCE_RESOURCES_NO;
1068
1069 return 1;
1070}
1071
1072__setup("acpi_enforce_resources=", acpi_enforce_resources_setup);
1073
1074
1075
1076int acpi_check_resource_conflict(struct resource *res)
1077{
1078 struct acpi_res_list *res_list_elem;
1079 int ioport;
1080 int clash = 0;
1081
1082 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1083 return 0;
1084 if (!(res->flags & IORESOURCE_IO) && !(res->flags & IORESOURCE_MEM))
1085 return 0;
1086
1087 ioport = res->flags & IORESOURCE_IO;
1088
1089 spin_lock(&acpi_res_lock);
1090 list_for_each_entry(res_list_elem, &resource_list_head,
1091 resource_list) {
1092 if (ioport && (res_list_elem->resource_type
1093 != ACPI_ADR_SPACE_SYSTEM_IO))
1094 continue;
1095 if (!ioport && (res_list_elem->resource_type
1096 != ACPI_ADR_SPACE_SYSTEM_MEMORY))
1097 continue;
1098
1099 if (res->end < res_list_elem->start
1100 || res_list_elem->end < res->start)
1101 continue;
1102 clash = 1;
1103 break;
1104 }
1105 spin_unlock(&acpi_res_lock);
1106
1107 if (clash) {
1108 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1109 printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
1110 " conflicts with ACPI region %s"
1111 " [0x%llx-0x%llx]\n",
1112 acpi_enforce_resources == ENFORCE_RESOURCES_LAX
1113 ? KERN_WARNING : KERN_ERR,
1114 ioport ? "I/O" : "Memory", res->name,
1115 (long long) res->start, (long long) res->end,
1116 res_list_elem->name,
1117 (long long) res_list_elem->start,
1118 (long long) res_list_elem->end);
1119 printk(KERN_INFO "ACPI: Device needs an ACPI driver\n");
1120 }
1121 if (acpi_enforce_resources == ENFORCE_RESOURCES_STRICT)
1122 return -EBUSY;
1123 }
1124 return 0;
1125}
1126EXPORT_SYMBOL(acpi_check_resource_conflict);
1127
1128int acpi_check_region(resource_size_t start, resource_size_t n,
1129 const char *name)
1130{
1131 struct resource res = {
1132 .start = start,
1133 .end = start + n - 1,
1134 .name = name,
1135 .flags = IORESOURCE_IO,
1136 };
1137
1138 return acpi_check_resource_conflict(&res);
1139}
1140EXPORT_SYMBOL(acpi_check_region);
1141
1142int acpi_check_mem_region(resource_size_t start, resource_size_t n,
1143 const char *name)
1144{
1145 struct resource res = {
1146 .start = start,
1147 .end = start + n - 1,
1148 .name = name,
1149 .flags = IORESOURCE_MEM,
1150 };
1151
1152 return acpi_check_resource_conflict(&res);
1153
1154}
1155EXPORT_SYMBOL(acpi_check_mem_region);
1156
1157
1158
1159
1160
1161
1162
1163acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
1164{
1165 acpi_cpu_flags flags;
1166 spin_lock_irqsave(lockp, flags);
1167 return flags;
1168}
1169
1170
1171
1172
1173
1174void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
1175{
1176 spin_unlock_irqrestore(lockp, flags);
1177}
1178
1179#ifndef ACPI_USE_LOCAL_CACHE
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196acpi_status
1197acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1198{
1199 *cache = kmem_cache_create(name, size, 0, 0, NULL);
1200 if (*cache == NULL)
1201 return AE_ERROR;
1202 else
1203 return AE_OK;
1204}
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
1219{
1220 kmem_cache_shrink(cache);
1221 return (AE_OK);
1222}
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
1238{
1239 kmem_cache_destroy(cache);
1240 return (AE_OK);
1241}
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1258{
1259 kmem_cache_free(cache, object);
1260 return (AE_OK);
1261}
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276acpi_status
1277acpi_os_validate_interface (char *interface)
1278{
1279 if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
1280 return AE_OK;
1281 if (!strcmp("Linux", interface)) {
1282
1283 printk(KERN_NOTICE PREFIX
1284 "BIOS _OSI(Linux) query %s%s\n",
1285 osi_linux.enable ? "honored" : "ignored",
1286 osi_linux.cmdline ? " via cmdline" :
1287 osi_linux.dmi ? " via DMI" : "");
1288
1289 if (!osi_linux.known && !osi_linux.cmdline) {
1290 printk(KERN_NOTICE PREFIX
1291 "If \"acpi_osi=%sLinux\" works better, "
1292 "please notify linux-acpi@vger.kernel.org\n",
1293 osi_linux.enable ? "!" : "");
1294 }
1295
1296 if (osi_linux.enable)
1297 return AE_OK;
1298 }
1299 return AE_SUPPORT;
1300}
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318acpi_status
1319acpi_os_validate_address (
1320 u8 space_id,
1321 acpi_physical_address address,
1322 acpi_size length,
1323 char *name)
1324{
1325 struct acpi_res_list *res;
1326 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1327 return AE_OK;
1328
1329 switch (space_id) {
1330 case ACPI_ADR_SPACE_SYSTEM_IO:
1331 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1332
1333
1334 res = kzalloc(sizeof(struct acpi_res_list), GFP_KERNEL);
1335 if (!res)
1336 return AE_OK;
1337
1338 strlcpy(res->name, name, 5);
1339 res->start = address;
1340 res->end = address + length - 1;
1341 res->resource_type = space_id;
1342 spin_lock(&acpi_res_lock);
1343 list_add(&res->resource_list, &resource_list_head);
1344 spin_unlock(&acpi_res_lock);
1345 pr_debug("Added %s resource: start: 0x%llx, end: 0x%llx, "
1346 "name: %s\n", (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
1347 ? "SystemIO" : "System Memory",
1348 (unsigned long long)res->start,
1349 (unsigned long long)res->end,
1350 res->name);
1351 break;
1352 case ACPI_ADR_SPACE_PCI_CONFIG:
1353 case ACPI_ADR_SPACE_EC:
1354 case ACPI_ADR_SPACE_SMBUS:
1355 case ACPI_ADR_SPACE_CMOS:
1356 case ACPI_ADR_SPACE_PCI_BAR_TARGET:
1357 case ACPI_ADR_SPACE_DATA_TABLE:
1358 case ACPI_ADR_SPACE_FIXED_HARDWARE:
1359 break;
1360 }
1361 return AE_OK;
1362}
1363
1364#endif
1365