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/acpi_io.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 int wait;
63};
64
65#ifdef CONFIG_ACPI_CUSTOM_DSDT
66#include CONFIG_ACPI_CUSTOM_DSDT_FILE
67#endif
68
69#ifdef ENABLE_DEBUGGER
70#include <linux/kdb.h>
71
72
73int acpi_in_debugger;
74EXPORT_SYMBOL(acpi_in_debugger);
75
76extern char line_buf[80];
77#endif
78
79static unsigned int acpi_irq_irq;
80static acpi_osd_handler acpi_irq_handler;
81static void *acpi_irq_context;
82static struct workqueue_struct *kacpid_wq;
83static struct workqueue_struct *kacpi_notify_wq;
84static struct workqueue_struct *kacpi_hotplug_wq;
85
86struct acpi_res_list {
87 resource_size_t start;
88 resource_size_t end;
89 acpi_adr_space_type resource_type;
90 char name[5];
91
92 struct list_head resource_list;
93 int count;
94};
95
96static LIST_HEAD(resource_list_head);
97static DEFINE_SPINLOCK(acpi_res_lock);
98
99
100
101
102
103struct acpi_ioremap {
104 struct list_head list;
105 void __iomem *virt;
106 acpi_physical_address phys;
107 acpi_size size;
108 struct kref ref;
109};
110
111static LIST_HEAD(acpi_ioremaps);
112static DEFINE_SPINLOCK(acpi_ioremap_lock);
113
114static void __init acpi_osi_setup_late(void);
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
141
142
143
144
145
146
147
148
149static struct osi_linux {
150 unsigned int enable:1;
151 unsigned int dmi:1;
152 unsigned int cmdline:1;
153} osi_linux = {0, 0, 0};
154
155static u32 acpi_osi_handler(acpi_string interface, u32 supported)
156{
157 if (!strcmp("Linux", interface)) {
158
159 printk(KERN_NOTICE FW_BUG PREFIX
160 "BIOS _OSI(Linux) query %s%s\n",
161 osi_linux.enable ? "honored" : "ignored",
162 osi_linux.cmdline ? " via cmdline" :
163 osi_linux.dmi ? " via DMI" : "");
164 }
165
166 return supported;
167}
168
169static void __init acpi_request_region (struct acpi_generic_address *addr,
170 unsigned int length, char *desc)
171{
172 if (!addr->address || !length)
173 return;
174
175
176 if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
177 request_region(addr->address, length, desc);
178 else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
179 request_mem_region(addr->address, length, desc);
180}
181
182static int __init acpi_reserve_resources(void)
183{
184 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
185 "ACPI PM1a_EVT_BLK");
186
187 acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
188 "ACPI PM1b_EVT_BLK");
189
190 acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
191 "ACPI PM1a_CNT_BLK");
192
193 acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
194 "ACPI PM1b_CNT_BLK");
195
196 if (acpi_gbl_FADT.pm_timer_length == 4)
197 acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
198
199 acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
200 "ACPI PM2_CNT_BLK");
201
202
203
204 if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
205 acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
206 acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
207
208 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
209 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
210 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
211
212 return 0;
213}
214device_initcall(acpi_reserve_resources);
215
216void acpi_os_printf(const char *fmt, ...)
217{
218 va_list args;
219 va_start(args, fmt);
220 acpi_os_vprintf(fmt, args);
221 va_end(args);
222}
223
224void acpi_os_vprintf(const char *fmt, va_list args)
225{
226 static char buffer[512];
227
228 vsprintf(buffer, fmt, args);
229
230#ifdef ENABLE_DEBUGGER
231 if (acpi_in_debugger) {
232 kdb_printf("%s", buffer);
233 } else {
234 printk(KERN_CONT "%s", buffer);
235 }
236#else
237 printk(KERN_CONT "%s", buffer);
238#endif
239}
240
241acpi_physical_address __init acpi_os_get_root_pointer(void)
242{
243 if (efi_enabled) {
244 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
245 return efi.acpi20;
246 else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
247 return efi.acpi;
248 else {
249 printk(KERN_ERR PREFIX
250 "System description tables not found\n");
251 return 0;
252 }
253 } else {
254 acpi_physical_address pa = 0;
255
256 acpi_find_root_pointer(&pa);
257 return pa;
258 }
259}
260
261
262static struct acpi_ioremap *
263acpi_map_lookup(acpi_physical_address phys, acpi_size size)
264{
265 struct acpi_ioremap *map;
266
267 list_for_each_entry_rcu(map, &acpi_ioremaps, list)
268 if (map->phys <= phys &&
269 phys + size <= map->phys + map->size)
270 return map;
271
272 return NULL;
273}
274
275
276static void __iomem *
277acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
278{
279 struct acpi_ioremap *map;
280
281 map = acpi_map_lookup(phys, size);
282 if (map)
283 return map->virt + (phys - map->phys);
284
285 return NULL;
286}
287
288
289static struct acpi_ioremap *
290acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
291{
292 struct acpi_ioremap *map;
293
294 list_for_each_entry_rcu(map, &acpi_ioremaps, list)
295 if (map->virt <= virt &&
296 virt + size <= map->virt + map->size)
297 return map;
298
299 return NULL;
300}
301
302void __iomem *__init_refok
303acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
304{
305 struct acpi_ioremap *map, *tmp_map;
306 unsigned long flags;
307 void __iomem *virt;
308 acpi_physical_address pg_off;
309 acpi_size pg_sz;
310
311 if (phys > ULONG_MAX) {
312 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
313 return NULL;
314 }
315
316 if (!acpi_gbl_permanent_mmap)
317 return __acpi_map_table((unsigned long)phys, size);
318
319 map = kzalloc(sizeof(*map), GFP_KERNEL);
320 if (!map)
321 return NULL;
322
323 pg_off = round_down(phys, PAGE_SIZE);
324 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
325 virt = acpi_os_ioremap(pg_off, pg_sz);
326 if (!virt) {
327 kfree(map);
328 return NULL;
329 }
330
331 INIT_LIST_HEAD(&map->list);
332 map->virt = virt;
333 map->phys = pg_off;
334 map->size = pg_sz;
335 kref_init(&map->ref);
336
337 spin_lock_irqsave(&acpi_ioremap_lock, flags);
338
339 tmp_map = acpi_map_lookup(phys, size);
340 if (tmp_map) {
341 kref_get(&tmp_map->ref);
342 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
343 iounmap(map->virt);
344 kfree(map);
345 return tmp_map->virt + (phys - tmp_map->phys);
346 }
347 list_add_tail_rcu(&map->list, &acpi_ioremaps);
348 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
349
350 return map->virt + (phys - map->phys);
351}
352EXPORT_SYMBOL_GPL(acpi_os_map_memory);
353
354static void acpi_kref_del_iomap(struct kref *ref)
355{
356 struct acpi_ioremap *map;
357
358 map = container_of(ref, struct acpi_ioremap, ref);
359 list_del_rcu(&map->list);
360}
361
362void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
363{
364 struct acpi_ioremap *map;
365 unsigned long flags;
366 int del;
367
368 if (!acpi_gbl_permanent_mmap) {
369 __acpi_unmap_table(virt, size);
370 return;
371 }
372
373 spin_lock_irqsave(&acpi_ioremap_lock, flags);
374 map = acpi_map_lookup_virt(virt, size);
375 if (!map) {
376 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
377 printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt);
378 dump_stack();
379 return;
380 }
381
382 del = kref_put(&map->ref, acpi_kref_del_iomap);
383 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
384
385 if (!del)
386 return;
387
388 synchronize_rcu();
389 iounmap(map->virt);
390 kfree(map);
391}
392EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
393
394void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
395{
396 if (!acpi_gbl_permanent_mmap)
397 __acpi_unmap_table(virt, size);
398}
399
400int acpi_os_map_generic_address(struct acpi_generic_address *addr)
401{
402 void __iomem *virt;
403
404 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
405 return 0;
406
407 if (!addr->address || !addr->bit_width)
408 return -EINVAL;
409
410 virt = acpi_os_map_memory(addr->address, addr->bit_width / 8);
411 if (!virt)
412 return -EIO;
413
414 return 0;
415}
416EXPORT_SYMBOL_GPL(acpi_os_map_generic_address);
417
418void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
419{
420 void __iomem *virt;
421 unsigned long flags;
422 acpi_size size = addr->bit_width / 8;
423
424 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
425 return;
426
427 if (!addr->address || !addr->bit_width)
428 return;
429
430 spin_lock_irqsave(&acpi_ioremap_lock, flags);
431 virt = acpi_map_vaddr_lookup(addr->address, size);
432 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
433
434 acpi_os_unmap_memory(virt, size);
435}
436EXPORT_SYMBOL_GPL(acpi_os_unmap_generic_address);
437
438#ifdef ACPI_FUTURE_USAGE
439acpi_status
440acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
441{
442 if (!phys || !virt)
443 return AE_BAD_PARAMETER;
444
445 *phys = virt_to_phys(virt);
446
447 return AE_OK;
448}
449#endif
450
451#define ACPI_MAX_OVERRIDE_LEN 100
452
453static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
454
455acpi_status
456acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
457 acpi_string * new_val)
458{
459 if (!init_val || !new_val)
460 return AE_BAD_PARAMETER;
461
462 *new_val = NULL;
463 if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
464 printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
465 acpi_os_name);
466 *new_val = acpi_os_name;
467 }
468
469 return AE_OK;
470}
471
472acpi_status
473acpi_os_table_override(struct acpi_table_header * existing_table,
474 struct acpi_table_header ** new_table)
475{
476 if (!existing_table || !new_table)
477 return AE_BAD_PARAMETER;
478
479 *new_table = NULL;
480
481#ifdef CONFIG_ACPI_CUSTOM_DSDT
482 if (strncmp(existing_table->signature, "DSDT", 4) == 0)
483 *new_table = (struct acpi_table_header *)AmlCode;
484#endif
485 if (*new_table != NULL) {
486 printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
487 "this is unsafe: tainting kernel\n",
488 existing_table->signature,
489 existing_table->oem_table_id);
490 add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
491 }
492 return AE_OK;
493}
494
495static irqreturn_t acpi_irq(int irq, void *dev_id)
496{
497 u32 handled;
498
499 handled = (*acpi_irq_handler) (acpi_irq_context);
500
501 if (handled) {
502 acpi_irq_handled++;
503 return IRQ_HANDLED;
504 } else {
505 acpi_irq_not_handled++;
506 return IRQ_NONE;
507 }
508}
509
510acpi_status
511acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
512 void *context)
513{
514 unsigned int irq;
515
516 acpi_irq_stats_init();
517
518
519
520
521
522
523 gsi = acpi_gbl_FADT.sci_interrupt;
524 if (acpi_gsi_to_irq(gsi, &irq) < 0) {
525 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
526 gsi);
527 return AE_OK;
528 }
529
530 acpi_irq_handler = handler;
531 acpi_irq_context = context;
532 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
533 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
534 return AE_NOT_ACQUIRED;
535 }
536 acpi_irq_irq = irq;
537
538 return AE_OK;
539}
540
541acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
542{
543 if (irq) {
544 free_irq(irq, acpi_irq);
545 acpi_irq_handler = NULL;
546 acpi_irq_irq = 0;
547 }
548
549 return AE_OK;
550}
551
552
553
554
555
556void acpi_os_sleep(u64 ms)
557{
558 schedule_timeout_interruptible(msecs_to_jiffies(ms));
559}
560
561void acpi_os_stall(u32 us)
562{
563 while (us) {
564 u32 delay = 1000;
565
566 if (delay > us)
567 delay = us;
568 udelay(delay);
569 touch_nmi_watchdog();
570 us -= delay;
571 }
572}
573
574
575
576
577
578
579u64 acpi_os_get_timer(void)
580{
581 static u64 t;
582
583#ifdef CONFIG_HPET
584
585#endif
586
587#ifdef CONFIG_X86_PM_TIMER
588
589#endif
590 if (!t)
591 printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");
592
593 return ++t;
594}
595
596acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
597{
598 u32 dummy;
599
600 if (!value)
601 value = &dummy;
602
603 *value = 0;
604 if (width <= 8) {
605 *(u8 *) value = inb(port);
606 } else if (width <= 16) {
607 *(u16 *) value = inw(port);
608 } else if (width <= 32) {
609 *(u32 *) value = inl(port);
610 } else {
611 BUG();
612 }
613
614 return AE_OK;
615}
616
617EXPORT_SYMBOL(acpi_os_read_port);
618
619acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
620{
621 if (width <= 8) {
622 outb(value, port);
623 } else if (width <= 16) {
624 outw(value, port);
625 } else if (width <= 32) {
626 outl(value, port);
627 } else {
628 BUG();
629 }
630
631 return AE_OK;
632}
633
634EXPORT_SYMBOL(acpi_os_write_port);
635
636acpi_status
637acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
638{
639 void __iomem *virt_addr;
640 unsigned int size = width / 8;
641 bool unmap = false;
642 u32 dummy;
643
644 rcu_read_lock();
645 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
646 if (!virt_addr) {
647 rcu_read_unlock();
648 virt_addr = acpi_os_ioremap(phys_addr, size);
649 if (!virt_addr)
650 return AE_BAD_ADDRESS;
651 unmap = true;
652 }
653
654 if (!value)
655 value = &dummy;
656
657 switch (width) {
658 case 8:
659 *(u8 *) value = readb(virt_addr);
660 break;
661 case 16:
662 *(u16 *) value = readw(virt_addr);
663 break;
664 case 32:
665 *(u32 *) value = readl(virt_addr);
666 break;
667 default:
668 BUG();
669 }
670
671 if (unmap)
672 iounmap(virt_addr);
673 else
674 rcu_read_unlock();
675
676 return AE_OK;
677}
678
679acpi_status
680acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
681{
682 void __iomem *virt_addr;
683 unsigned int size = width / 8;
684 bool unmap = false;
685
686 rcu_read_lock();
687 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
688 if (!virt_addr) {
689 rcu_read_unlock();
690 virt_addr = acpi_os_ioremap(phys_addr, size);
691 if (!virt_addr)
692 return AE_BAD_ADDRESS;
693 unmap = true;
694 }
695
696 switch (width) {
697 case 8:
698 writeb(value, virt_addr);
699 break;
700 case 16:
701 writew(value, virt_addr);
702 break;
703 case 32:
704 writel(value, virt_addr);
705 break;
706 default:
707 BUG();
708 }
709
710 if (unmap)
711 iounmap(virt_addr);
712 else
713 rcu_read_unlock();
714
715 return AE_OK;
716}
717
718acpi_status
719acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
720 u64 *value, u32 width)
721{
722 int result, size;
723 u32 value32;
724
725 if (!value)
726 return AE_BAD_PARAMETER;
727
728 switch (width) {
729 case 8:
730 size = 1;
731 break;
732 case 16:
733 size = 2;
734 break;
735 case 32:
736 size = 4;
737 break;
738 default:
739 return AE_ERROR;
740 }
741
742 result = raw_pci_read(pci_id->segment, pci_id->bus,
743 PCI_DEVFN(pci_id->device, pci_id->function),
744 reg, size, &value32);
745 *value = value32;
746
747 return (result ? AE_ERROR : AE_OK);
748}
749
750acpi_status
751acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
752 u64 value, u32 width)
753{
754 int result, size;
755
756 switch (width) {
757 case 8:
758 size = 1;
759 break;
760 case 16:
761 size = 2;
762 break;
763 case 32:
764 size = 4;
765 break;
766 default:
767 return AE_ERROR;
768 }
769
770 result = raw_pci_write(pci_id->segment, pci_id->bus,
771 PCI_DEVFN(pci_id->device, pci_id->function),
772 reg, size, value);
773
774 return (result ? AE_ERROR : AE_OK);
775}
776
777static void acpi_os_execute_deferred(struct work_struct *work)
778{
779 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
780
781 if (dpc->wait)
782 acpi_os_wait_events_complete(NULL);
783
784 dpc->function(dpc->context);
785 kfree(dpc);
786}
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803static acpi_status __acpi_os_execute(acpi_execute_type type,
804 acpi_osd_exec_callback function, void *context, int hp)
805{
806 acpi_status status = AE_OK;
807 struct acpi_os_dpc *dpc;
808 struct workqueue_struct *queue;
809 int ret;
810 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
811 "Scheduling function [%p(%p)] for deferred execution.\n",
812 function, context));
813
814
815
816
817
818
819
820
821
822
823 dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
824 if (!dpc)
825 return AE_NO_MEMORY;
826
827 dpc->function = function;
828 dpc->context = context;
829
830
831
832
833
834
835
836 queue = hp ? kacpi_hotplug_wq :
837 (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
838 dpc->wait = hp ? 1 : 0;
839
840 if (queue == kacpi_hotplug_wq)
841 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
842 else if (queue == kacpi_notify_wq)
843 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
844 else
845 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
846
847
848
849
850
851
852
853
854 ret = queue_work_on(0, queue, &dpc->work);
855
856 if (!ret) {
857 printk(KERN_ERR PREFIX
858 "Call to queue_work() failed.\n");
859 status = AE_ERROR;
860 kfree(dpc);
861 }
862 return status;
863}
864
865acpi_status acpi_os_execute(acpi_execute_type type,
866 acpi_osd_exec_callback function, void *context)
867{
868 return __acpi_os_execute(type, function, context, 0);
869}
870EXPORT_SYMBOL(acpi_os_execute);
871
872acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
873 void *context)
874{
875 return __acpi_os_execute(0, function, context, 1);
876}
877
878void acpi_os_wait_events_complete(void *context)
879{
880 flush_workqueue(kacpid_wq);
881 flush_workqueue(kacpi_notify_wq);
882}
883
884EXPORT_SYMBOL(acpi_os_wait_events_complete);
885
886
887
888
889void acpi_os_delete_lock(acpi_spinlock handle)
890{
891 return;
892}
893
894acpi_status
895acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
896{
897 struct semaphore *sem = NULL;
898
899 sem = acpi_os_allocate(sizeof(struct semaphore));
900 if (!sem)
901 return AE_NO_MEMORY;
902 memset(sem, 0, sizeof(struct semaphore));
903
904 sema_init(sem, initial_units);
905
906 *handle = (acpi_handle *) sem;
907
908 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n",
909 *handle, initial_units));
910
911 return AE_OK;
912}
913
914
915
916
917
918
919
920
921acpi_status acpi_os_delete_semaphore(acpi_handle handle)
922{
923 struct semaphore *sem = (struct semaphore *)handle;
924
925 if (!sem)
926 return AE_BAD_PARAMETER;
927
928 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
929
930 BUG_ON(!list_empty(&sem->wait_list));
931 kfree(sem);
932 sem = NULL;
933
934 return AE_OK;
935}
936
937
938
939
940acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
941{
942 acpi_status status = AE_OK;
943 struct semaphore *sem = (struct semaphore *)handle;
944 long jiffies;
945 int ret = 0;
946
947 if (!sem || (units < 1))
948 return AE_BAD_PARAMETER;
949
950 if (units > 1)
951 return AE_SUPPORT;
952
953 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
954 handle, units, timeout));
955
956 if (timeout == ACPI_WAIT_FOREVER)
957 jiffies = MAX_SCHEDULE_TIMEOUT;
958 else
959 jiffies = msecs_to_jiffies(timeout);
960
961 ret = down_timeout(sem, jiffies);
962 if (ret)
963 status = AE_TIME;
964
965 if (ACPI_FAILURE(status)) {
966 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
967 "Failed to acquire semaphore[%p|%d|%d], %s",
968 handle, units, timeout,
969 acpi_format_exception(status)));
970 } else {
971 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
972 "Acquired semaphore[%p|%d|%d]", handle,
973 units, timeout));
974 }
975
976 return status;
977}
978
979
980
981
982acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
983{
984 struct semaphore *sem = (struct semaphore *)handle;
985
986 if (!sem || (units < 1))
987 return AE_BAD_PARAMETER;
988
989 if (units > 1)
990 return AE_SUPPORT;
991
992 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
993 units));
994
995 up(sem);
996
997 return AE_OK;
998}
999
1000#ifdef ACPI_FUTURE_USAGE
1001u32 acpi_os_get_line(char *buffer)
1002{
1003
1004#ifdef ENABLE_DEBUGGER
1005 if (acpi_in_debugger) {
1006 u32 chars;
1007
1008 kdb_read(buffer, sizeof(line_buf));
1009
1010
1011 chars = strlen(buffer) - 1;
1012 buffer[chars] = '\0';
1013 }
1014#endif
1015
1016 return 0;
1017}
1018#endif
1019
1020acpi_status acpi_os_signal(u32 function, void *info)
1021{
1022 switch (function) {
1023 case ACPI_SIGNAL_FATAL:
1024 printk(KERN_ERR PREFIX "Fatal opcode executed\n");
1025 break;
1026 case ACPI_SIGNAL_BREAKPOINT:
1027
1028
1029
1030
1031
1032
1033
1034
1035 break;
1036 default:
1037 break;
1038 }
1039
1040 return AE_OK;
1041}
1042
1043static int __init acpi_os_name_setup(char *str)
1044{
1045 char *p = acpi_os_name;
1046 int count = ACPI_MAX_OVERRIDE_LEN - 1;
1047
1048 if (!str || !*str)
1049 return 0;
1050
1051 for (; count-- && str && *str; str++) {
1052 if (isalnum(*str) || *str == ' ' || *str == ':')
1053 *p++ = *str;
1054 else if (*str == '\'' || *str == '"')
1055 continue;
1056 else
1057 break;
1058 }
1059 *p = 0;
1060
1061 return 1;
1062
1063}
1064
1065__setup("acpi_os_name=", acpi_os_name_setup);
1066
1067#define OSI_STRING_LENGTH_MAX 64
1068#define OSI_STRING_ENTRIES_MAX 16
1069
1070struct osi_setup_entry {
1071 char string[OSI_STRING_LENGTH_MAX];
1072 bool enable;
1073};
1074
1075static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
1076
1077void __init acpi_osi_setup(char *str)
1078{
1079 struct osi_setup_entry *osi;
1080 bool enable = true;
1081 int i;
1082
1083 if (!acpi_gbl_create_osi_method)
1084 return;
1085
1086 if (str == NULL || *str == '\0') {
1087 printk(KERN_INFO PREFIX "_OSI method disabled\n");
1088 acpi_gbl_create_osi_method = FALSE;
1089 return;
1090 }
1091
1092 if (*str == '!') {
1093 str++;
1094 enable = false;
1095 }
1096
1097 for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
1098 osi = &osi_setup_entries[i];
1099 if (!strcmp(osi->string, str)) {
1100 osi->enable = enable;
1101 break;
1102 } else if (osi->string[0] == '\0') {
1103 osi->enable = enable;
1104 strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
1105 break;
1106 }
1107 }
1108}
1109
1110static void __init set_osi_linux(unsigned int enable)
1111{
1112 if (osi_linux.enable != enable)
1113 osi_linux.enable = enable;
1114
1115 if (osi_linux.enable)
1116 acpi_osi_setup("Linux");
1117 else
1118 acpi_osi_setup("!Linux");
1119
1120 return;
1121}
1122
1123static void __init acpi_cmdline_osi_linux(unsigned int enable)
1124{
1125 osi_linux.cmdline = 1;
1126 osi_linux.dmi = 0;
1127 set_osi_linux(enable);
1128
1129 return;
1130}
1131
1132void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
1133{
1134 printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
1135
1136 if (enable == -1)
1137 return;
1138
1139 osi_linux.dmi = 1;
1140 set_osi_linux(enable);
1141
1142 return;
1143}
1144
1145
1146
1147
1148
1149
1150
1151
1152static void __init acpi_osi_setup_late(void)
1153{
1154 struct osi_setup_entry *osi;
1155 char *str;
1156 int i;
1157 acpi_status status;
1158
1159 for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
1160 osi = &osi_setup_entries[i];
1161 str = osi->string;
1162
1163 if (*str == '\0')
1164 break;
1165 if (osi->enable) {
1166 status = acpi_install_interface(str);
1167
1168 if (ACPI_SUCCESS(status))
1169 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
1170 } else {
1171 status = acpi_remove_interface(str);
1172
1173 if (ACPI_SUCCESS(status))
1174 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
1175 }
1176 }
1177}
1178
1179static int __init osi_setup(char *str)
1180{
1181 if (str && !strcmp("Linux", str))
1182 acpi_cmdline_osi_linux(1);
1183 else if (str && !strcmp("!Linux", str))
1184 acpi_cmdline_osi_linux(0);
1185 else
1186 acpi_osi_setup(str);
1187
1188 return 1;
1189}
1190
1191__setup("acpi_osi=", osi_setup);
1192
1193
1194static int __init acpi_serialize_setup(char *str)
1195{
1196 printk(KERN_INFO PREFIX "serialize enabled\n");
1197
1198 acpi_gbl_all_methods_serialized = TRUE;
1199
1200 return 1;
1201}
1202
1203__setup("acpi_serialize", acpi_serialize_setup);
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221#define ENFORCE_RESOURCES_STRICT 2
1222#define ENFORCE_RESOURCES_LAX 1
1223#define ENFORCE_RESOURCES_NO 0
1224
1225static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1226
1227static int __init acpi_enforce_resources_setup(char *str)
1228{
1229 if (str == NULL || *str == '\0')
1230 return 0;
1231
1232 if (!strcmp("strict", str))
1233 acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1234 else if (!strcmp("lax", str))
1235 acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
1236 else if (!strcmp("no", str))
1237 acpi_enforce_resources = ENFORCE_RESOURCES_NO;
1238
1239 return 1;
1240}
1241
1242__setup("acpi_enforce_resources=", acpi_enforce_resources_setup);
1243
1244
1245
1246int acpi_check_resource_conflict(const struct resource *res)
1247{
1248 struct acpi_res_list *res_list_elem;
1249 int ioport = 0, clash = 0;
1250
1251 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1252 return 0;
1253 if (!(res->flags & IORESOURCE_IO) && !(res->flags & IORESOURCE_MEM))
1254 return 0;
1255
1256 ioport = res->flags & IORESOURCE_IO;
1257
1258 spin_lock(&acpi_res_lock);
1259 list_for_each_entry(res_list_elem, &resource_list_head,
1260 resource_list) {
1261 if (ioport && (res_list_elem->resource_type
1262 != ACPI_ADR_SPACE_SYSTEM_IO))
1263 continue;
1264 if (!ioport && (res_list_elem->resource_type
1265 != ACPI_ADR_SPACE_SYSTEM_MEMORY))
1266 continue;
1267
1268 if (res->end < res_list_elem->start
1269 || res_list_elem->end < res->start)
1270 continue;
1271 clash = 1;
1272 break;
1273 }
1274 spin_unlock(&acpi_res_lock);
1275
1276 if (clash) {
1277 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1278 printk(KERN_WARNING "ACPI: resource %s %pR"
1279 " conflicts with ACPI region %s "
1280 "[%s 0x%zx-0x%zx]\n",
1281 res->name, res, res_list_elem->name,
1282 (res_list_elem->resource_type ==
1283 ACPI_ADR_SPACE_SYSTEM_IO) ? "io" : "mem",
1284 (size_t) res_list_elem->start,
1285 (size_t) res_list_elem->end);
1286 if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
1287 printk(KERN_NOTICE "ACPI: This conflict may"
1288 " cause random problems and system"
1289 " instability\n");
1290 printk(KERN_INFO "ACPI: If an ACPI driver is available"
1291 " for this device, you should use it instead of"
1292 " the native driver\n");
1293 }
1294 if (acpi_enforce_resources == ENFORCE_RESOURCES_STRICT)
1295 return -EBUSY;
1296 }
1297 return 0;
1298}
1299EXPORT_SYMBOL(acpi_check_resource_conflict);
1300
1301int acpi_check_region(resource_size_t start, resource_size_t n,
1302 const char *name)
1303{
1304 struct resource res = {
1305 .start = start,
1306 .end = start + n - 1,
1307 .name = name,
1308 .flags = IORESOURCE_IO,
1309 };
1310
1311 return acpi_check_resource_conflict(&res);
1312}
1313EXPORT_SYMBOL(acpi_check_region);
1314
1315
1316
1317
1318int acpi_resources_are_enforced(void)
1319{
1320 return acpi_enforce_resources == ENFORCE_RESOURCES_STRICT;
1321}
1322EXPORT_SYMBOL(acpi_resources_are_enforced);
1323
1324
1325
1326
1327
1328
1329
1330acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
1331{
1332 acpi_cpu_flags flags;
1333 spin_lock_irqsave(lockp, flags);
1334 return flags;
1335}
1336
1337
1338
1339
1340
1341void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
1342{
1343 spin_unlock_irqrestore(lockp, flags);
1344}
1345
1346#ifndef ACPI_USE_LOCAL_CACHE
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363acpi_status
1364acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1365{
1366 *cache = kmem_cache_create(name, size, 0, 0, NULL);
1367 if (*cache == NULL)
1368 return AE_ERROR;
1369 else
1370 return AE_OK;
1371}
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
1386{
1387 kmem_cache_shrink(cache);
1388 return (AE_OK);
1389}
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
1405{
1406 kmem_cache_destroy(cache);
1407 return (AE_OK);
1408}
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1425{
1426 kmem_cache_free(cache, object);
1427 return (AE_OK);
1428}
1429
1430static inline int acpi_res_list_add(struct acpi_res_list *res)
1431{
1432 struct acpi_res_list *res_list_elem;
1433
1434 list_for_each_entry(res_list_elem, &resource_list_head,
1435 resource_list) {
1436
1437 if (res->resource_type == res_list_elem->resource_type &&
1438 res->start == res_list_elem->start &&
1439 res->end == res_list_elem->end) {
1440
1441
1442
1443
1444
1445
1446 res_list_elem->count++;
1447 return 0;
1448 }
1449 }
1450
1451 res->count = 1;
1452 list_add(&res->resource_list, &resource_list_head);
1453 return 1;
1454}
1455
1456static inline void acpi_res_list_del(struct acpi_res_list *res)
1457{
1458 struct acpi_res_list *res_list_elem;
1459
1460 list_for_each_entry(res_list_elem, &resource_list_head,
1461 resource_list) {
1462
1463 if (res->resource_type == res_list_elem->resource_type &&
1464 res->start == res_list_elem->start &&
1465 res->end == res_list_elem->end) {
1466
1467
1468
1469
1470
1471
1472 if (--res_list_elem->count == 0) {
1473 list_del(&res_list_elem->resource_list);
1474 kfree(res_list_elem);
1475 }
1476 return;
1477 }
1478 }
1479}
1480
1481acpi_status
1482acpi_os_invalidate_address(
1483 u8 space_id,
1484 acpi_physical_address address,
1485 acpi_size length)
1486{
1487 struct acpi_res_list res;
1488
1489 switch (space_id) {
1490 case ACPI_ADR_SPACE_SYSTEM_IO:
1491 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1492
1493
1494 res.start = address;
1495 res.end = address + length - 1;
1496 res.resource_type = space_id;
1497 spin_lock(&acpi_res_lock);
1498 acpi_res_list_del(&res);
1499 spin_unlock(&acpi_res_lock);
1500 break;
1501 case ACPI_ADR_SPACE_PCI_CONFIG:
1502 case ACPI_ADR_SPACE_EC:
1503 case ACPI_ADR_SPACE_SMBUS:
1504 case ACPI_ADR_SPACE_CMOS:
1505 case ACPI_ADR_SPACE_PCI_BAR_TARGET:
1506 case ACPI_ADR_SPACE_DATA_TABLE:
1507 case ACPI_ADR_SPACE_FIXED_HARDWARE:
1508 break;
1509 }
1510 return AE_OK;
1511}
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529acpi_status
1530acpi_os_validate_address (
1531 u8 space_id,
1532 acpi_physical_address address,
1533 acpi_size length,
1534 char *name)
1535{
1536 struct acpi_res_list *res;
1537 int added;
1538 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1539 return AE_OK;
1540
1541 switch (space_id) {
1542 case ACPI_ADR_SPACE_SYSTEM_IO:
1543 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1544
1545
1546 res = kzalloc(sizeof(struct acpi_res_list), GFP_KERNEL);
1547 if (!res)
1548 return AE_OK;
1549
1550 strlcpy(res->name, name, 5);
1551 res->start = address;
1552 res->end = address + length - 1;
1553 res->resource_type = space_id;
1554 spin_lock(&acpi_res_lock);
1555 added = acpi_res_list_add(res);
1556 spin_unlock(&acpi_res_lock);
1557 pr_debug("%s %s resource: start: 0x%llx, end: 0x%llx, "
1558 "name: %s\n", added ? "Added" : "Already exist",
1559 (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
1560 ? "SystemIO" : "System Memory",
1561 (unsigned long long)res->start,
1562 (unsigned long long)res->end,
1563 res->name);
1564 if (!added)
1565 kfree(res);
1566 break;
1567 case ACPI_ADR_SPACE_PCI_CONFIG:
1568 case ACPI_ADR_SPACE_EC:
1569 case ACPI_ADR_SPACE_SMBUS:
1570 case ACPI_ADR_SPACE_CMOS:
1571 case ACPI_ADR_SPACE_PCI_BAR_TARGET:
1572 case ACPI_ADR_SPACE_DATA_TABLE:
1573 case ACPI_ADR_SPACE_FIXED_HARDWARE:
1574 break;
1575 }
1576 return AE_OK;
1577}
1578#endif
1579
1580acpi_status __init acpi_os_initialize(void)
1581{
1582 acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
1583 acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
1584 acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
1585 acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
1586
1587 return AE_OK;
1588}
1589
1590acpi_status __init acpi_os_initialize1(void)
1591{
1592 kacpid_wq = create_workqueue("kacpid");
1593 kacpi_notify_wq = create_workqueue("kacpi_notify");
1594 kacpi_hotplug_wq = create_workqueue("kacpi_hotplug");
1595 BUG_ON(!kacpid_wq);
1596 BUG_ON(!kacpi_notify_wq);
1597 BUG_ON(!kacpi_hotplug_wq);
1598 acpi_install_interface_handler(acpi_osi_handler);
1599 acpi_osi_setup_late();
1600 return AE_OK;
1601}
1602
1603acpi_status acpi_os_terminate(void)
1604{
1605 if (acpi_irq_handler) {
1606 acpi_os_remove_interrupt_handler(acpi_irq_irq,
1607 acpi_irq_handler);
1608 }
1609
1610 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block);
1611 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
1612 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
1613 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
1614
1615 destroy_workqueue(kacpid_wq);
1616 destroy_workqueue(kacpi_notify_wq);
1617 destroy_workqueue(kacpi_hotplug_wq);
1618
1619 return AE_OK;
1620}
1621