diff options
Diffstat (limited to 'arch/x86/pci/amd_bus.c')
-rw-r--r-- | arch/x86/pci/amd_bus.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index dbf532369711..6a0fca78c362 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
3 | #include <linux/topology.h> | 3 | #include <linux/topology.h> |
4 | #include <linux/cpu.h> | ||
4 | #include "pci.h" | 5 | #include "pci.h" |
5 | 6 | ||
6 | #ifdef CONFIG_X86_64 | 7 | #ifdef CONFIG_X86_64 |
@@ -555,15 +556,17 @@ static int __init early_fill_mp_bus_info(void) | |||
555 | return 0; | 556 | return 0; |
556 | } | 557 | } |
557 | 558 | ||
558 | postcore_initcall(early_fill_mp_bus_info); | 559 | #else /* !CONFIG_X86_64 */ |
559 | 560 | ||
560 | #endif | 561 | static int __init early_fill_mp_bus_info(void) { return 0; } |
562 | |||
563 | #endif /* !CONFIG_X86_64 */ | ||
561 | 564 | ||
562 | /* common 32/64 bit code */ | 565 | /* common 32/64 bit code */ |
563 | 566 | ||
564 | #define ENABLE_CF8_EXT_CFG (1ULL << 46) | 567 | #define ENABLE_CF8_EXT_CFG (1ULL << 46) |
565 | 568 | ||
566 | static void enable_pci_io_ecs_per_cpu(void *unused) | 569 | static void enable_pci_io_ecs(void *unused) |
567 | { | 570 | { |
568 | u64 reg; | 571 | u64 reg; |
569 | rdmsrl(MSR_AMD64_NB_CFG, reg); | 572 | rdmsrl(MSR_AMD64_NB_CFG, reg); |
@@ -573,14 +576,51 @@ static void enable_pci_io_ecs_per_cpu(void *unused) | |||
573 | } | 576 | } |
574 | } | 577 | } |
575 | 578 | ||
576 | static int __init enable_pci_io_ecs(void) | 579 | static int __cpuinit amd_cpu_notify(struct notifier_block *self, |
580 | unsigned long action, void *hcpu) | ||
577 | { | 581 | { |
582 | int cpu = (long)hcpu; | ||
583 | switch(action) { | ||
584 | case CPU_ONLINE: | ||
585 | case CPU_ONLINE_FROZEN: | ||
586 | smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0); | ||
587 | break; | ||
588 | default: | ||
589 | break; | ||
590 | } | ||
591 | return NOTIFY_OK; | ||
592 | } | ||
593 | |||
594 | static struct notifier_block __cpuinitdata amd_cpu_notifier = { | ||
595 | .notifier_call = amd_cpu_notify, | ||
596 | }; | ||
597 | |||
598 | static int __init pci_io_ecs_init(void) | ||
599 | { | ||
600 | int cpu; | ||
601 | |||
578 | /* assume all cpus from fam10h have IO ECS */ | 602 | /* assume all cpus from fam10h have IO ECS */ |
579 | if (boot_cpu_data.x86 < 0x10) | 603 | if (boot_cpu_data.x86 < 0x10) |
580 | return 0; | 604 | return 0; |
581 | on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1); | 605 | |
606 | register_cpu_notifier(&amd_cpu_notifier); | ||
607 | for_each_online_cpu(cpu) | ||
608 | amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE, | ||
609 | (void *)(long)cpu); | ||
582 | pci_probe |= PCI_HAS_IO_ECS; | 610 | pci_probe |= PCI_HAS_IO_ECS; |
611 | |||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | static int __init amd_postcore_init(void) | ||
616 | { | ||
617 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) | ||
618 | return 0; | ||
619 | |||
620 | early_fill_mp_bus_info(); | ||
621 | pci_io_ecs_init(); | ||
622 | |||
583 | return 0; | 623 | return 0; |
584 | } | 624 | } |
585 | 625 | ||
586 | postcore_initcall(enable_pci_io_ecs); | 626 | postcore_initcall(amd_postcore_init); |