diff options
author | Linas Vepstas <linas@linas.org> | 2005-11-03 19:55:19 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-09 23:30:39 -0500 |
commit | 7684b40cb53ba00cc51271f1c42897b776c48fbc (patch) | |
tree | 19155abfd3b76d13b55dfb6fdf1a46e4a8c0a048 /arch | |
parent | d177c207ba16b1db31283e2d1fee7ad4a863584b (diff) |
[PATCH] powerpc: Save device BARs much earlier in the boot sequence
241-eeh-save-bars-earlier.patch
Save the PCI device bars *before* any PCI probing is done.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
(cherry picked from 76c902b919098860f3d4e125f847abcc4cb1782a commit)
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/rtas_pci.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 16 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh_cache.c | 3 |
3 files changed, 9 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 45b8109951fe..5579f6559912 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -72,7 +72,7 @@ static int of_device_available(struct device_node * dn) | |||
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
74 | 74 | ||
75 | static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) | 75 | int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) |
76 | { | 76 | { |
77 | int returnval = -1; | 77 | int returnval = -1; |
78 | unsigned long buid, addr; | 78 | unsigned long buid, addr; |
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 02bc1f9d20b9..9e597cb7e659 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -106,6 +106,8 @@ static DEFINE_PER_CPU(unsigned long, false_positives); | |||
106 | static DEFINE_PER_CPU(unsigned long, ignored_failures); | 106 | static DEFINE_PER_CPU(unsigned long, ignored_failures); |
107 | static DEFINE_PER_CPU(unsigned long, slot_resets); | 107 | static DEFINE_PER_CPU(unsigned long, slot_resets); |
108 | 108 | ||
109 | #define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE) | ||
110 | |||
109 | /* --------------------------------------------------------------- */ | 111 | /* --------------------------------------------------------------- */ |
110 | /* Below lies the EEH event infrastructure */ | 112 | /* Below lies the EEH event infrastructure */ |
111 | 113 | ||
@@ -620,7 +622,7 @@ void eeh_restore_bars(struct pci_dn *pdn) | |||
620 | if (!pdn) | 622 | if (!pdn) |
621 | return; | 623 | return; |
622 | 624 | ||
623 | if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && (!pdn->eeh_is_bridge)) | 625 | if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code)) |
624 | __restore_bars (pdn); | 626 | __restore_bars (pdn); |
625 | 627 | ||
626 | dn = pdn->node->child; | 628 | dn = pdn->node->child; |
@@ -638,18 +640,15 @@ void eeh_restore_bars(struct pci_dn *pdn) | |||
638 | * PCI devices are added individuallly; but, for the restore, | 640 | * PCI devices are added individuallly; but, for the restore, |
639 | * an entire slot is reset at a time. | 641 | * an entire slot is reset at a time. |
640 | */ | 642 | */ |
641 | void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn) | 643 | static void eeh_save_bars(struct pci_dn *pdn) |
642 | { | 644 | { |
643 | int i; | 645 | int i; |
644 | 646 | ||
645 | if (!pdev || !pdn ) | 647 | if (!pdn ) |
646 | return; | 648 | return; |
647 | 649 | ||
648 | for (i = 0; i < 16; i++) | 650 | for (i = 0; i < 16; i++) |
649 | pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]); | 651 | rtas_read_config(pdn, i * 4, 4, &pdn->config_space[i]); |
650 | |||
651 | if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | ||
652 | pdn->eeh_is_bridge = 1; | ||
653 | } | 652 | } |
654 | 653 | ||
655 | void | 654 | void |
@@ -699,6 +698,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
699 | int enable; | 698 | int enable; |
700 | struct pci_dn *pdn = PCI_DN(dn); | 699 | struct pci_dn *pdn = PCI_DN(dn); |
701 | 700 | ||
701 | pdn->class_code = *class_code; | ||
702 | pdn->eeh_mode = 0; | 702 | pdn->eeh_mode = 0; |
703 | pdn->eeh_check_count = 0; | 703 | pdn->eeh_check_count = 0; |
704 | pdn->eeh_freeze_count = 0; | 704 | pdn->eeh_freeze_count = 0; |
@@ -781,6 +781,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
781 | dn->full_name); | 781 | dn->full_name); |
782 | } | 782 | } |
783 | 783 | ||
784 | eeh_save_bars(pdn); | ||
784 | return NULL; | 785 | return NULL; |
785 | } | 786 | } |
786 | 787 | ||
@@ -915,7 +916,6 @@ void eeh_add_device_late(struct pci_dev *dev) | |||
915 | pdn->pcidev = dev; | 916 | pdn->pcidev = dev; |
916 | 917 | ||
917 | pci_addr_cache_insert_device (dev); | 918 | pci_addr_cache_insert_device (dev); |
918 | eeh_save_bars(dev, pdn); | ||
919 | } | 919 | } |
920 | EXPORT_SYMBOL_GPL(eeh_add_device_late); | 920 | EXPORT_SYMBOL_GPL(eeh_add_device_late); |
921 | 921 | ||
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index ff6c938f424b..71b2187581a3 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c | |||
@@ -304,10 +304,7 @@ void __init pci_addr_cache_build(void) | |||
304 | 304 | ||
305 | pci_addr_cache_insert_device(dev); | 305 | pci_addr_cache_insert_device(dev); |
306 | 306 | ||
307 | /* Save the BAR's; firmware doesn't restore these after EEH reset */ | ||
308 | dn = pci_device_to_OF_node(dev); | 307 | dn = pci_device_to_OF_node(dev); |
309 | eeh_save_bars(dev, PCI_DN(dn)); | ||
310 | |||
311 | pci_dev_get (dev); /* matching put is in eeh_remove_device() */ | 308 | pci_dev_get (dev); /* matching put is in eeh_remove_device() */ |
312 | PCI_DN(dn)->pcidev = dev; | 309 | PCI_DN(dn)->pcidev = dev; |
313 | } | 310 | } |