aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-12-05 07:42:09 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2014-12-05 10:54:27 +1100
commit1c72cd1a0ca1b0de32c16f11517193ac582fab98 (patch)
tree2154000a5cc072e0610dcc11e7507521d817a0c8
parent1ee766ac7733ef975e3d40c4ccb5886299a0eb5b (diff)
downloadskiboot-1c72cd1a0ca1b0de32c16f11517193ac582fab98.zip
skiboot-1c72cd1a0ca1b0de32c16f11517193ac582fab98.tar.gz
skiboot-1c72cd1a0ca1b0de32c16f11517193ac582fab98.tar.bz2
occ: Fix clearing of OCC interrupt on remote fix
If the OCC interrupt comes from another chip, we incorrectly try to clear it on the local one. This causes hangs at boot on some machines. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--hw/occ.c6
-rw-r--r--hw/psi.c2
-rw-r--r--include/skiboot.h2
3 files changed, 5 insertions, 5 deletions
diff --git a/hw/occ.c b/hw/occ.c
index 34949d0..846b585 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -524,13 +524,13 @@ static void occ_tmgt_interrupt(void)
printf("OCC: TMGT interrupt !\n");
}
-void occ_interrupt(void)
+void occ_interrupt(uint32_t chip_id)
{
uint64_t ireg;
int64_t rc;
/* The OCC interrupt is used to mux up to 15 different sources */
- rc = xscom_readme(OCB_OCI_OCCMISC, &ireg);
+ rc = xscom_read(chip_id, OCB_OCI_OCCMISC, &ireg);
if (rc) {
prerror("OCC: Failed to read interrupt status !\n");
/* Should we mask it in the XIVR ? */
@@ -539,7 +539,7 @@ void occ_interrupt(void)
prlog(PR_TRACE, "OCC: IRQ received: %04llx\n", ireg >> 48);
/* Clear the bits */
- xscom_writeme(OCB_OCI_OCCMISC_AND, ~ireg);
+ xscom_write(chip_id, OCB_OCI_OCCMISC_AND, ~ireg);
/* Dispatch */
if (ireg & OCB_OCI_OCIMISC_IRQ_TMGT)
diff --git a/hw/psi.c b/hw/psi.c
index 1dba69a..70403fd 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -278,7 +278,7 @@ static void handle_extra_interrupt(struct psi *psi)
* when available.
*/
if (val & PSIHB_IRQ_STAT_OCC)
- occ_interrupt();
+ occ_interrupt(psi->chip_id);
if (val & PSIHB_IRQ_STAT_FSI)
printf("PSI: FSI irq received\n");
if (val & PSIHB_IRQ_STAT_LPC) {
diff --git a/include/skiboot.h b/include/skiboot.h
index 0991ca3..1b55638 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -210,7 +210,7 @@ extern void uart_setup_linux_passthrough(void);
extern void uart_setup_opal_console(void);
/* OCC interrupt */
-extern void occ_interrupt(void);
+extern void occ_interrupt(uint32_t chip_id);
extern void occ_send_dummy_interrupt(void);
/* Flatten device-tree */