aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2015-04-09 13:47:12 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-05-07 17:51:29 +1000
commit9e5747525d909fbf71a68d3593bba06d2bc4e86c (patch)
tree2df9cfe91dcd91c25bdbc4457fbb0ebdf9a8270a /hw
parentc04f054808ce744526494253d3fa03330d53dcfb (diff)
downloadskiboot-9e5747525d909fbf71a68d3593bba06d2bc4e86c.zip
skiboot-9e5747525d909fbf71a68d3593bba06d2bc4e86c.tar.gz
skiboot-9e5747525d909fbf71a68d3593bba06d2bc4e86c.tar.bz2
eeh: Fix eeh event handling
The opal eeh interrupt handlers raise an opal event (OPAL_EVENT_PCI_ERROR) whenever there is some processing required from the OS. The OS then needs to call opal_pci_next_error(...) in a loop passing each phb in turn to clear the event. However opal_pci_next_error(...) clears the event unconditionally meaning it would be possible for eeh events to be cleared without processing them leading to missed events. This patch fixes the problem by keeping track of eeh events on a per-phb basis and only clearing the opal event once all phb eeh events have been cleared. Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/p7ioc-phb.c2
-rw-r--r--hw/p7ioc.c7
2 files changed, 6 insertions, 3 deletions
diff --git a/hw/p7ioc-phb.c b/hw/p7ioc-phb.c
index d84fd15..89592c4 100644
--- a/hw/p7ioc-phb.c
+++ b/hw/p7ioc-phb.c
@@ -2740,7 +2740,7 @@ static void p7ioc_phb_err_interrupt(void *data, uint32_t isn)
PHBDBG(p, "Got interrupt 0x%04x\n", isn);
- opal_update_pending_evt(OPAL_EVENT_PCI_ERROR, OPAL_EVENT_PCI_ERROR);
+ opal_pci_eeh_set_evt(p->phb.opal_id);
/* If the PHB is broken, go away */
if (p->state == P7IOC_PHB_STATE_BROKEN)
diff --git a/hw/p7ioc.c b/hw/p7ioc.c
index 2315e81..48a9dc9 100644
--- a/hw/p7ioc.c
+++ b/hw/p7ioc.c
@@ -575,8 +575,11 @@ static void p7ioc_rgc_interrupt(void *data, uint32_t isn)
/* We will notify OS while getting error from GEM */
if (p7ioc_check_GEM(ioc))
- opal_update_pending_evt(OPAL_EVENT_PCI_ERROR,
- OPAL_EVENT_PCI_ERROR);
+ /* This is a bit hacky but works - we raise the event
+ on a downstream phb as the OS needs to call
+ opal_pci_next_error for all phbs to ensure all events
+ are cleared anyway. */
+ opal_pci_eeh_set_evt(ioc->phbs[0].phb.opal_id);
}
static const struct irq_source_ops p7ioc_rgc_irq_ops = {