aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
authorLinas Vepstas <linas@austin.ibm.com>2007-05-23 13:16:46 -0400
committerPaul Mackerras <paulus@samba.org>2007-06-14 08:29:55 -0400
commite1d04c9769398ae7df8c7ca2681b25f540b719d5 (patch)
tree78ae5fd5814571870e6aeb75c875ffdb84e62748 /arch/powerpc/platforms/pseries
parentc2e221e8b93ea54da85d9b5413a2eff9f4a653f7 (diff)
[POWERPC] Add EEH sysfs blinkenlights
Add sysfs blinkenlights for EEH statistics. Shuffle the eeh_add_device_tree() call so that it appears in the correct sequence. Signed-off-by: Linas Vepstas <linas@austin.ibm.com> ---- arch/powerpc/platforms/pseries/Makefile | 2 arch/powerpc/platforms/pseries/eeh.c | 4 + arch/powerpc/platforms/pseries/eeh_cache.c | 2 arch/powerpc/platforms/pseries/eeh_sysfs.c | 84 +++++++++++++++++++++++++++++ arch/powerpc/platforms/pseries/pci_dlpar.c | 7 +- include/asm-powerpc/ppc-pci.h | 3 + 6 files changed, 98 insertions(+), 4 deletions(-) Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/Makefile2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c4
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c2
-rw-r--r--arch/powerpc/platforms/pseries/eeh_sysfs.c84
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c7
5 files changed, 95 insertions, 4 deletions
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index ae1fc92dc1c9..992ba6753cf2 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -8,7 +8,7 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \
8obj-$(CONFIG_SMP) += smp.o 8obj-$(CONFIG_SMP) += smp.o
9obj-$(CONFIG_XICS) += xics.o 9obj-$(CONFIG_XICS) += xics.o
10obj-$(CONFIG_SCANLOG) += scanlog.o 10obj-$(CONFIG_SCANLOG) += scanlog.o
11obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o 11obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o
12obj-$(CONFIG_KEXEC) += kexec.o 12obj-$(CONFIG_KEXEC) += kexec.o
13obj-$(CONFIG_PCI) += pci.o pci_dlpar.o 13obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
14obj-$(CONFIG_PCI_MSI) += msi.o 14obj-$(CONFIG_PCI_MSI) += msi.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 5f3e6d8659fe..d284a58c5b5f 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1139,7 +1139,8 @@ static void eeh_add_device_late(struct pci_dev *dev)
1139 pdn = PCI_DN(dn); 1139 pdn = PCI_DN(dn);
1140 pdn->pcidev = dev; 1140 pdn->pcidev = dev;
1141 1141
1142 pci_addr_cache_insert_device (dev); 1142 pci_addr_cache_insert_device(dev);
1143 eeh_sysfs_add_device(dev);
1143} 1144}
1144 1145
1145void eeh_add_device_tree_late(struct pci_bus *bus) 1146void eeh_add_device_tree_late(struct pci_bus *bus)
@@ -1178,6 +1179,7 @@ static void eeh_remove_device(struct pci_dev *dev)
1178 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); 1179 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
1179#endif 1180#endif
1180 pci_addr_cache_remove_device(dev); 1181 pci_addr_cache_remove_device(dev);
1182 eeh_sysfs_remove_device(dev);
1181 1183
1182 dn = pci_device_to_OF_node(dev); 1184 dn = pci_device_to_OF_node(dev);
1183 if (PCI_DN(dn)->pcidev) { 1185 if (PCI_DN(dn)->pcidev) {
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index f2bae04424f8..60abea2d257c 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -295,6 +295,8 @@ void __init pci_addr_cache_build(void)
295 continue; 295 continue;
296 pci_dev_get (dev); /* matching put is in eeh_remove_device() */ 296 pci_dev_get (dev); /* matching put is in eeh_remove_device() */
297 PCI_DN(dn)->pcidev = dev; 297 PCI_DN(dn)->pcidev = dev;
298
299 eeh_sysfs_add_device(dev);
298 } 300 }
299 301
300#ifdef DEBUG 302#ifdef DEBUG
diff --git a/arch/powerpc/platforms/pseries/eeh_sysfs.c b/arch/powerpc/platforms/pseries/eeh_sysfs.c
new file mode 100644
index 000000000000..0543cafec56b
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/eeh_sysfs.c
@@ -0,0 +1,84 @@
1/*
2 * Sysfs entries for PCI Error Recovery for PAPR-compliant platform.
3 * Copyright IBM Corporation 2007
4 * Copyright Linas Vepstas <linas@austin.ibm.com> 2007
5 *
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
24 */
25#include <linux/pci.h>
26#include <asm/ppc-pci.h>
27#include <asm/pci-bridge.h>
28#include <linux/kobject.h>
29
30/**
31 * EEH_SHOW_ATTR -- create sysfs entry for eeh statistic
32 * @_name: name of file in sysfs directory
33 * @_memb: name of member in struct pci_dn to access
34 * @_format: printf format for display
35 *
36 * All of the attributes look very similar, so just
37 * auto-gen a cut-n-paste routine to display them.
38 */
39#define EEH_SHOW_ATTR(_name,_memb,_format) \
40static ssize_t eeh_show_##_name(struct device *dev, \
41 struct device_attribute *attr, char *buf) \
42{ \
43 struct pci_dev *pdev = to_pci_dev(dev); \
44 struct device_node *dn = pci_device_to_OF_node(pdev); \
45 struct pci_dn *pdn; \
46 \
47 if (!dn || PCI_DN(dn) == NULL) \
48 return 0; \
49 \
50 pdn = PCI_DN(dn); \
51 return sprintf(buf, _format "\n", pdn->_memb); \
52} \
53static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL);
54
55
56EEH_SHOW_ATTR(eeh_mode, eeh_mode, "0x%x");
57EEH_SHOW_ATTR(eeh_config_addr, eeh_config_addr, "0x%x");
58EEH_SHOW_ATTR(eeh_pe_config_addr, eeh_pe_config_addr, "0x%x");
59EEH_SHOW_ATTR(eeh_check_count, eeh_check_count, "%d");
60EEH_SHOW_ATTR(eeh_freeze_count, eeh_freeze_count, "%d");
61
62void eeh_sysfs_add_device(struct pci_dev *pdev)
63{
64 int rc=0;
65
66 rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode);
67 rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr);
68 rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
69 rc += device_create_file(&pdev->dev, &dev_attr_eeh_check_count);
70 rc += device_create_file(&pdev->dev, &dev_attr_eeh_freeze_count);
71
72 if (rc)
73 printk(KERN_WARNING "EEH: Unable to create sysfs entries\n");
74}
75
76void eeh_sysfs_remove_device(struct pci_dev *pdev)
77{
78 device_remove_file(&pdev->dev, &dev_attr_eeh_mode);
79 device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr);
80 device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
81 device_remove_file(&pdev->dev, &dev_attr_eeh_check_count);
82 device_remove_file(&pdev->dev, &dev_attr_eeh_freeze_count);
83}
84
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index ffaf6c5c517b..0b113ab90ba9 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -110,8 +110,6 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
110 } 110 }
111 } 111 }
112 } 112 }
113
114 eeh_add_device_tree_late(bus);
115} 113}
116EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); 114EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
117 115
@@ -139,6 +137,8 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
139 137
140 /* Make the discovered devices available */ 138 /* Make the discovered devices available */
141 pci_bus_add_devices(child_bus); 139 pci_bus_add_devices(child_bus);
140
141 eeh_add_device_tree_late(child_bus);
142 return 0; 142 return 0;
143} 143}
144 144
@@ -171,6 +171,7 @@ pcibios_add_pci_devices(struct pci_bus * bus)
171 if (!list_empty(&bus->devices)) { 171 if (!list_empty(&bus->devices)) {
172 pcibios_fixup_new_pci_devices(bus, 0); 172 pcibios_fixup_new_pci_devices(bus, 0);
173 pci_bus_add_devices(bus); 173 pci_bus_add_devices(bus);
174 eeh_add_device_tree_late(bus);
174 } 175 }
175 } else if (mode == PCI_PROBE_NORMAL) { 176 } else if (mode == PCI_PROBE_NORMAL) {
176 /* use legacy probe */ 177 /* use legacy probe */
@@ -179,6 +180,7 @@ pcibios_add_pci_devices(struct pci_bus * bus)
179 if (num) { 180 if (num) {
180 pcibios_fixup_new_pci_devices(bus, 1); 181 pcibios_fixup_new_pci_devices(bus, 1);
181 pci_bus_add_devices(bus); 182 pci_bus_add_devices(bus);
183 eeh_add_device_tree_late(bus);
182 } 184 }
183 185
184 list_for_each_entry(dev, &bus->devices, bus_list) 186 list_for_each_entry(dev, &bus->devices, bus_list)
@@ -210,6 +212,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
210 scan_phb(phb); 212 scan_phb(phb);
211 pcibios_fixup_new_pci_devices(phb->bus, 0); 213 pcibios_fixup_new_pci_devices(phb->bus, 0);
212 pci_bus_add_devices(phb->bus); 214 pci_bus_add_devices(phb->bus);
215 eeh_add_device_tree_late(phb->bus);
213 216
214 return phb; 217 return phb;
215} 218}