diff options
Diffstat (limited to 'arch/x86_64/kernel/setup.c')
-rw-r--r-- | arch/x86_64/kernel/setup.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 759070c82751..f0870bef24d1 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -571,17 +571,28 @@ static inline void copy_edd(void) | |||
571 | #endif | 571 | #endif |
572 | 572 | ||
573 | #define EBDA_ADDR_POINTER 0x40E | 573 | #define EBDA_ADDR_POINTER 0x40E |
574 | static void __init reserve_ebda_region(void) | 574 | |
575 | unsigned __initdata ebda_addr; | ||
576 | unsigned __initdata ebda_size; | ||
577 | |||
578 | static void discover_ebda(void) | ||
575 | { | 579 | { |
576 | unsigned int addr; | 580 | /* |
577 | /** | ||
578 | * there is a real-mode segmented pointer pointing to the | 581 | * there is a real-mode segmented pointer pointing to the |
579 | * 4K EBDA area at 0x40E | 582 | * 4K EBDA area at 0x40E |
580 | */ | 583 | */ |
581 | addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER); | 584 | ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER; |
582 | addr <<= 4; | 585 | ebda_addr <<= 4; |
583 | if (addr) | 586 | |
584 | reserve_bootmem_generic(addr, PAGE_SIZE); | 587 | ebda_size = *(unsigned short *)(unsigned long)ebda_addr; |
588 | |||
589 | /* Round EBDA up to pages */ | ||
590 | if (ebda_size == 0) | ||
591 | ebda_size = 1; | ||
592 | ebda_size <<= 10; | ||
593 | ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE); | ||
594 | if (ebda_size > 64*1024) | ||
595 | ebda_size = 64*1024; | ||
585 | } | 596 | } |
586 | 597 | ||
587 | void __init setup_arch(char **cmdline_p) | 598 | void __init setup_arch(char **cmdline_p) |
@@ -627,6 +638,8 @@ void __init setup_arch(char **cmdline_p) | |||
627 | 638 | ||
628 | check_efer(); | 639 | check_efer(); |
629 | 640 | ||
641 | discover_ebda(); | ||
642 | |||
630 | init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); | 643 | init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); |
631 | 644 | ||
632 | dmi_scan_machine(); | 645 | dmi_scan_machine(); |
@@ -669,7 +682,8 @@ void __init setup_arch(char **cmdline_p) | |||
669 | reserve_bootmem_generic(0, PAGE_SIZE); | 682 | reserve_bootmem_generic(0, PAGE_SIZE); |
670 | 683 | ||
671 | /* reserve ebda region */ | 684 | /* reserve ebda region */ |
672 | reserve_ebda_region(); | 685 | if (ebda_addr) |
686 | reserve_bootmem_generic(ebda_addr, ebda_size); | ||
673 | 687 | ||
674 | #ifdef CONFIG_SMP | 688 | #ifdef CONFIG_SMP |
675 | /* | 689 | /* |
@@ -1426,3 +1440,22 @@ struct seq_operations cpuinfo_op = { | |||
1426 | .show = show_cpuinfo, | 1440 | .show = show_cpuinfo, |
1427 | }; | 1441 | }; |
1428 | 1442 | ||
1443 | #ifdef CONFIG_INPUT_PCSPKR | ||
1444 | #include <linux/platform_device.h> | ||
1445 | static __init int add_pcspkr(void) | ||
1446 | { | ||
1447 | struct platform_device *pd; | ||
1448 | int ret; | ||
1449 | |||
1450 | pd = platform_device_alloc("pcspkr", -1); | ||
1451 | if (!pd) | ||
1452 | return -ENOMEM; | ||
1453 | |||
1454 | ret = platform_device_add(pd); | ||
1455 | if (ret) | ||
1456 | platform_device_put(pd); | ||
1457 | |||
1458 | return ret; | ||
1459 | } | ||
1460 | device_initcall(add_pcspkr); | ||
1461 | #endif | ||