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