aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include/asm
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2012-02-27 15:04:04 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-03-08 19:39:29 -0500
commiteb740b5f3e6559a8f1c22e2505914d07f9632881 (patch)
tree6e463d4ba852359d82b33a61040e240430280fa6 /arch/powerpc/include/asm
parentdef9d83da4f8587dbad5ea57c57d91e53a51006a (diff)
powerpc/eeh: Introduce EEH device
Original EEH implementation depends on struct pci_dn heavily. However, EEH shouldn't depend on that actually because EEH needn't share much information with other PCI components. That's to say, EEH should have worked independently. The patch introduces struct eeh_dev so that EEH core components needn't be working based on struct pci_dn in future. Also, struct pci_dn, struct eeh_dev instances are created in dynamic fasion and the binding with EEH device, OF node, PCI device is implemented as well. The EEH devices are created after PHBs are detected and initialized, but PCI emunation hasn't started yet. Apart from that, PHB might be created dynamically through DLPAR component and the EEH devices should be creatd as well. Another case might be OF node is created dynamically by DR (Dynamic Reconfiguration), which has been defined by PAPR. For those OF nodes created by DR, EEH devices should be also created accordingly. The binding between EEH device and OF node is done while the EEH device is initially created. The binding between EEH device and PCI device should be done after PCI emunation is done. Besides, PCI hotplug also needs the binding so that the EEH devices could be traced from the newly coming PCI buses or PCI devices. Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/include/asm')
-rw-r--r--arch/powerpc/include/asm/device.h3
-rw-r--r--arch/powerpc/include/asm/eeh.h57
2 files changed, 53 insertions, 7 deletions
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index d57c08acedfc..63d5ca49cece 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -31,6 +31,9 @@ struct dev_archdata {
31#ifdef CONFIG_SWIOTLB 31#ifdef CONFIG_SWIOTLB
32 dma_addr_t max_direct_dma_addr; 32 dma_addr_t max_direct_dma_addr;
33#endif 33#endif
34#ifdef CONFIG_EEH
35 struct eeh_dev *edev;
36#endif
34}; 37};
35 38
36struct pdev_archdata { 39struct pdev_archdata {
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index ad8f31834e00..daaad91ed576 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -32,6 +32,43 @@ struct device_node;
32#ifdef CONFIG_EEH 32#ifdef CONFIG_EEH
33 33
34/* 34/*
35 * The struct is used to trace EEH state for the associated
36 * PCI device node or PCI device. In future, it might
37 * represent PE as well so that the EEH device to form
38 * another tree except the currently existing tree of PCI
39 * buses and PCI devices
40 */
41#define EEH_MODE_SUPPORTED (1<<0) /* EEH supported on the device */
42#define EEH_MODE_NOCHECK (1<<1) /* EEH check should be skipped */
43#define EEH_MODE_ISOLATED (1<<2) /* The device has been isolated */
44#define EEH_MODE_RECOVERING (1<<3) /* Recovering the device */
45#define EEH_MODE_IRQ_DISABLED (1<<4) /* Interrupt disabled */
46
47struct eeh_dev {
48 int mode; /* EEH mode */
49 int class_code; /* Class code of the device */
50 int config_addr; /* Config address */
51 int pe_config_addr; /* PE config address */
52 int check_count; /* Times of ignored error */
53 int freeze_count; /* Times of froze up */
54 int false_positives; /* Times of reported #ff's */
55 u32 config_space[16]; /* Saved PCI config space */
56 struct pci_controller *phb; /* Associated PHB */
57 struct device_node *dn; /* Associated device node */
58 struct pci_dev *pdev; /* Associated PCI device */
59};
60
61static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
62{
63 return edev->dn;
64}
65
66static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev)
67{
68 return edev->pdev;
69}
70
71/*
35 * The struct is used to trace the registered EEH operation 72 * The struct is used to trace the registered EEH operation
36 * callback functions. Actually, those operation callback 73 * callback functions. Actually, those operation callback
37 * functions are heavily platform dependent. That means the 74 * functions are heavily platform dependent. That means the
@@ -70,19 +107,15 @@ struct eeh_ops {
70extern struct eeh_ops *eeh_ops; 107extern struct eeh_ops *eeh_ops;
71extern int eeh_subsystem_enabled; 108extern int eeh_subsystem_enabled;
72 109
73/* Values for eeh_mode bits in device_node */
74#define EEH_MODE_SUPPORTED (1<<0)
75#define EEH_MODE_NOCHECK (1<<1)
76#define EEH_MODE_ISOLATED (1<<2)
77#define EEH_MODE_RECOVERING (1<<3)
78#define EEH_MODE_IRQ_DISABLED (1<<4)
79
80/* 110/*
81 * Max number of EEH freezes allowed before we consider the device 111 * Max number of EEH freezes allowed before we consider the device
82 * to be permanently disabled. 112 * to be permanently disabled.
83 */ 113 */
84#define EEH_MAX_ALLOWED_FREEZES 5 114#define EEH_MAX_ALLOWED_FREEZES 5
85 115
116void * __devinit eeh_dev_init(struct device_node *dn, void *data);
117void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb);
118void __init eeh_dev_phb_init(void);
86void __init eeh_init(void); 119void __init eeh_init(void);
87#ifdef CONFIG_PPC_PSERIES 120#ifdef CONFIG_PPC_PSERIES
88int __init eeh_pseries_init(void); 121int __init eeh_pseries_init(void);
@@ -113,6 +146,16 @@ void eeh_remove_bus_device(struct pci_dev *);
113#define EEH_IO_ERROR_VALUE(size) (~0U >> ((4 - (size)) * 8)) 146#define EEH_IO_ERROR_VALUE(size) (~0U >> ((4 - (size)) * 8))
114 147
115#else /* !CONFIG_EEH */ 148#else /* !CONFIG_EEH */
149
150static inline void *eeh_dev_init(struct device_node *dn, void *data)
151{
152 return NULL;
153}
154
155static inline void eeh_dev_phb_init_dynamic(struct pci_controller *phb) { }
156
157static inline void eeh_dev_phb_init(void) { }
158
116static inline void eeh_init(void) { } 159static inline void eeh_init(void) { }
117 160
118#ifdef CONFIG_PPC_PSERIES 161#ifdef CONFIG_PPC_PSERIES