diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2012-02-27 15:04:11 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-03-08 19:39:51 -0500 |
commit | 3780444c4fcec28c96ab7002858bb051215a5fc1 (patch) | |
tree | cc0b5ce6a72793470d006e668d488ba8f52daa3a /arch/powerpc/platforms/pseries/eeh.c | |
parent | e575f8db1ed8e73515350a0d569a0eb8367ab6b4 (diff) |
powerpc/eeh: pseries platform config space access in EEH
With the original EEH implementation, the access to config space of
the corresponding PCI device is done by RTAS sensitive function. That
depends on pci_dn heavily. That would limit EEH extension to other
platforms like powernv because other platforms might have different
ways to access PCI config space.
The patch splits those functions used to access PCI config space
and implement them in platform related EEH component. It would be
helpful to support EEH on multiple platforms simutaneously in future.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries/eeh.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 1d08cd76e68d..8011088392d3 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -141,11 +141,11 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) | |||
141 | n += scnprintf(buf+n, len-n, "%s\n", dn->full_name); | 141 | n += scnprintf(buf+n, len-n, "%s\n", dn->full_name); |
142 | printk(KERN_WARNING "EEH: of node=%s\n", dn->full_name); | 142 | printk(KERN_WARNING "EEH: of node=%s\n", dn->full_name); |
143 | 143 | ||
144 | rtas_read_config(PCI_DN(dn), PCI_VENDOR_ID, 4, &cfg); | 144 | eeh_ops->read_config(dn, PCI_VENDOR_ID, 4, &cfg); |
145 | n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg); | 145 | n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg); |
146 | printk(KERN_WARNING "EEH: PCI device/vendor: %08x\n", cfg); | 146 | printk(KERN_WARNING "EEH: PCI device/vendor: %08x\n", cfg); |
147 | 147 | ||
148 | rtas_read_config(PCI_DN(dn), PCI_COMMAND, 4, &cfg); | 148 | eeh_ops->read_config(dn, PCI_COMMAND, 4, &cfg); |
149 | n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg); | 149 | n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg); |
150 | printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg); | 150 | printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg); |
151 | 151 | ||
@@ -156,11 +156,11 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) | |||
156 | 156 | ||
157 | /* Gather bridge-specific registers */ | 157 | /* Gather bridge-specific registers */ |
158 | if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) { | 158 | if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) { |
159 | rtas_read_config(PCI_DN(dn), PCI_SEC_STATUS, 2, &cfg); | 159 | eeh_ops->read_config(dn, PCI_SEC_STATUS, 2, &cfg); |
160 | n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg); | 160 | n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg); |
161 | printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg); | 161 | printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg); |
162 | 162 | ||
163 | rtas_read_config(PCI_DN(dn), PCI_BRIDGE_CONTROL, 2, &cfg); | 163 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &cfg); |
164 | n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg); | 164 | n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg); |
165 | printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg); | 165 | printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg); |
166 | } | 166 | } |
@@ -168,11 +168,11 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) | |||
168 | /* Dump out the PCI-X command and status regs */ | 168 | /* Dump out the PCI-X command and status regs */ |
169 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 169 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
170 | if (cap) { | 170 | if (cap) { |
171 | rtas_read_config(PCI_DN(dn), cap, 4, &cfg); | 171 | eeh_ops->read_config(dn, cap, 4, &cfg); |
172 | n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg); | 172 | n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg); |
173 | printk(KERN_WARNING "EEH: PCI-X cmd: %08x\n", cfg); | 173 | printk(KERN_WARNING "EEH: PCI-X cmd: %08x\n", cfg); |
174 | 174 | ||
175 | rtas_read_config(PCI_DN(dn), cap+4, 4, &cfg); | 175 | eeh_ops->read_config(dn, cap+4, 4, &cfg); |
176 | n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg); | 176 | n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg); |
177 | printk(KERN_WARNING "EEH: PCI-X status: %08x\n", cfg); | 177 | printk(KERN_WARNING "EEH: PCI-X status: %08x\n", cfg); |
178 | } | 178 | } |
@@ -185,7 +185,7 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) | |||
185 | "EEH: PCI-E capabilities and status follow:\n"); | 185 | "EEH: PCI-E capabilities and status follow:\n"); |
186 | 186 | ||
187 | for (i=0; i<=8; i++) { | 187 | for (i=0; i<=8; i++) { |
188 | rtas_read_config(PCI_DN(dn), cap+4*i, 4, &cfg); | 188 | eeh_ops->read_config(dn, cap+4*i, 4, &cfg); |
189 | n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); | 189 | n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); |
190 | printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg); | 190 | printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg); |
191 | } | 191 | } |
@@ -197,7 +197,7 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) | |||
197 | "EEH: PCI-E AER capability register set follows:\n"); | 197 | "EEH: PCI-E AER capability register set follows:\n"); |
198 | 198 | ||
199 | for (i=0; i<14; i++) { | 199 | for (i=0; i<14; i++) { |
200 | rtas_read_config(PCI_DN(dn), cap+4*i, 4, &cfg); | 200 | eeh_ops->read_config(dn, cap+4*i, 4, &cfg); |
201 | n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); | 201 | n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); |
202 | printk(KERN_WARNING "EEH: PCI-E AER %02x: %08x\n", i, cfg); | 202 | printk(KERN_WARNING "EEH: PCI-E AER %02x: %08x\n", i, cfg); |
203 | } | 203 | } |
@@ -746,28 +746,28 @@ static inline void eeh_restore_one_device_bars(struct eeh_dev *edev) | |||
746 | return; | 746 | return; |
747 | 747 | ||
748 | for (i=4; i<10; i++) { | 748 | for (i=4; i<10; i++) { |
749 | rtas_write_config(PCI_DN(dn), i*4, 4, edev->config_space[i]); | 749 | eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]); |
750 | } | 750 | } |
751 | 751 | ||
752 | /* 12 == Expansion ROM Address */ | 752 | /* 12 == Expansion ROM Address */ |
753 | rtas_write_config(PCI_DN(dn), 12*4, 4, edev->config_space[12]); | 753 | eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]); |
754 | 754 | ||
755 | #define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) | 755 | #define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) |
756 | #define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)]) | 756 | #define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)]) |
757 | 757 | ||
758 | rtas_write_config(PCI_DN(dn), PCI_CACHE_LINE_SIZE, 1, | 758 | eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1, |
759 | SAVED_BYTE(PCI_CACHE_LINE_SIZE)); | 759 | SAVED_BYTE(PCI_CACHE_LINE_SIZE)); |
760 | 760 | ||
761 | rtas_write_config(PCI_DN(dn), PCI_LATENCY_TIMER, 1, | 761 | eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1, |
762 | SAVED_BYTE(PCI_LATENCY_TIMER)); | 762 | SAVED_BYTE(PCI_LATENCY_TIMER)); |
763 | 763 | ||
764 | /* max latency, min grant, interrupt pin and line */ | 764 | /* max latency, min grant, interrupt pin and line */ |
765 | rtas_write_config(PCI_DN(dn), 15*4, 4, edev->config_space[15]); | 765 | eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]); |
766 | 766 | ||
767 | /* Restore PERR & SERR bits, some devices require it, | 767 | /* Restore PERR & SERR bits, some devices require it, |
768 | * don't touch the other command bits | 768 | * don't touch the other command bits |
769 | */ | 769 | */ |
770 | rtas_read_config(PCI_DN(dn), PCI_COMMAND, 4, &cmd); | 770 | eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd); |
771 | if (edev->config_space[1] & PCI_COMMAND_PARITY) | 771 | if (edev->config_space[1] & PCI_COMMAND_PARITY) |
772 | cmd |= PCI_COMMAND_PARITY; | 772 | cmd |= PCI_COMMAND_PARITY; |
773 | else | 773 | else |
@@ -776,7 +776,7 @@ static inline void eeh_restore_one_device_bars(struct eeh_dev *edev) | |||
776 | cmd |= PCI_COMMAND_SERR; | 776 | cmd |= PCI_COMMAND_SERR; |
777 | else | 777 | else |
778 | cmd &= ~PCI_COMMAND_SERR; | 778 | cmd &= ~PCI_COMMAND_SERR; |
779 | rtas_write_config(PCI_DN(dn), PCI_COMMAND, 4, cmd); | 779 | eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd); |
780 | } | 780 | } |
781 | 781 | ||
782 | /** | 782 | /** |
@@ -818,7 +818,7 @@ static void eeh_save_bars(struct eeh_dev *edev) | |||
818 | dn = eeh_dev_to_of_node(edev); | 818 | dn = eeh_dev_to_of_node(edev); |
819 | 819 | ||
820 | for (i = 0; i < 16; i++) | 820 | for (i = 0; i < 16; i++) |
821 | rtas_read_config(PCI_DN(dn), i * 4, 4, &edev->config_space[i]); | 821 | eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]); |
822 | } | 822 | } |
823 | 823 | ||
824 | /** | 824 | /** |