aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/eeh_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/eeh_event.c')
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index e98347cb9cc0..4a4752565856 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -56,8 +56,8 @@ DEFINE_MUTEX(eeh_event_mutex);
56static int eeh_event_handler(void * dummy) 56static int eeh_event_handler(void * dummy)
57{ 57{
58 unsigned long flags; 58 unsigned long flags;
59 struct eeh_event *event; 59 struct eeh_event *event;
60 struct pci_dn *pdn; 60 struct eeh_dev *edev;
61 61
62 daemonize("eehd"); 62 daemonize("eehd");
63 set_current_state(TASK_INTERRUPTIBLE); 63 set_current_state(TASK_INTERRUPTIBLE);
@@ -77,23 +77,26 @@ static int eeh_event_handler(void * dummy)
77 77
78 /* Serialize processing of EEH events */ 78 /* Serialize processing of EEH events */
79 mutex_lock(&eeh_event_mutex); 79 mutex_lock(&eeh_event_mutex);
80 eeh_mark_slot(event->dn, EEH_MODE_RECOVERING); 80 edev = event->edev;
81 eeh_mark_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING);
81 82
82 printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", 83 printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
83 eeh_pci_name(event->dev)); 84 eeh_pci_name(edev->pdev));
85
86 edev = handle_eeh_events(event);
84 87
85 pdn = handle_eeh_events(event); 88 eeh_clear_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING);
89 pci_dev_put(edev->pdev);
86 90
87 eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
88 pci_dev_put(event->dev);
89 kfree(event); 91 kfree(event);
90 mutex_unlock(&eeh_event_mutex); 92 mutex_unlock(&eeh_event_mutex);
91 93
92 /* If there are no new errors after an hour, clear the counter. */ 94 /* If there are no new errors after an hour, clear the counter. */
93 if (pdn && pdn->eeh_freeze_count>0) { 95 if (edev && edev->freeze_count>0) {
94 msleep_interruptible(3600*1000); 96 msleep_interruptible(3600*1000);
95 if (pdn->eeh_freeze_count>0) 97 if (edev->freeze_count>0)
96 pdn->eeh_freeze_count--; 98 edev->freeze_count--;
99
97 } 100 }
98 101
99 return 0; 102 return 0;
@@ -114,17 +117,17 @@ static void eeh_thread_launcher(struct work_struct *dummy)
114 117
115/** 118/**
116 * eeh_send_failure_event - Generate a PCI error event 119 * eeh_send_failure_event - Generate a PCI error event
117 * @dev: pci device 120 * @edev: EEH device
118 * 121 *
119 * This routine can be called within an interrupt context; 122 * This routine can be called within an interrupt context;
120 * the actual event will be delivered in a normal context 123 * the actual event will be delivered in a normal context
121 * (from a workqueue). 124 * (from a workqueue).
122 */ 125 */
123int eeh_send_failure_event(struct device_node *dn, 126int eeh_send_failure_event(struct eeh_dev *edev)
124 struct pci_dev *dev)
125{ 127{
126 unsigned long flags; 128 unsigned long flags;
127 struct eeh_event *event; 129 struct eeh_event *event;
130 struct device_node *dn = eeh_dev_to_of_node(edev);
128 const char *location; 131 const char *location;
129 132
130 if (!mem_init_done) { 133 if (!mem_init_done) {
@@ -140,11 +143,10 @@ int eeh_send_failure_event(struct device_node *dn,
140 return 1; 143 return 1;
141 } 144 }
142 145
143 if (dev) 146 if (edev->pdev)
144 pci_dev_get(dev); 147 pci_dev_get(edev->pdev);
145 148
146 event->dn = dn; 149 event->edev = edev;
147 event->dev = dev;
148 150
149 /* We may or may not be called in an interrupt context */ 151 /* We may or may not be called in an interrupt context */
150 spin_lock_irqsave(&eeh_eventlist_lock, flags); 152 spin_lock_irqsave(&eeh_eventlist_lock, flags);