summaryrefslogtreecommitdiffstats
path: root/hw/occ.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-02-17 17:45:59 +0800
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-02-18 11:52:41 +1100
commitc48f1a3d7df2dec1c157f1b12b4925bfd666b710 (patch)
tree4feef4e9eadedf31ccefb95d19083a96c9b8f783 /hw/occ.c
parentf2c3e5186178d5e91970a4e8c9ff2a99e6ea9f72 (diff)
downloadtalos-skiboot-c48f1a3d7df2dec1c157f1b12b4925bfd666b710.tar.gz
talos-skiboot-c48f1a3d7df2dec1c157f1b12b4925bfd666b710.zip
occ: Fix potential race when clearing occ interrupt status
Currently, the occ_interrupt handler will clear the interrupt bit along with the interrupt reason. If an irq has occurred between the read and the clear, we'll mask out interrupt bit for that new event This change checks the reason bits after clearing the interrupt bit. If any are set, we re-set the interrupt bit to trigger another interrupt. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/occ.c')
-rw-r--r--hw/occ.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/hw/occ.c b/hw/occ.c
index 5d0e34dd..1e47b8f3 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -533,6 +533,8 @@ static struct fsp_client fsp_occ_client = {
#define OCB_OCI_OCIMISC_IRQ PPC_BIT(0)
#define OCB_OCI_OCIMISC_IRQ_TMGT PPC_BIT(1)
#define OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY PPC_BIT(15)
+#define OCB_OCI_OCIMISC_MASK (OCB_OCI_OCIMISC_IRQ_TMGT | \
+ OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY )
void occ_send_dummy_interrupt(void)
{
@@ -570,6 +572,14 @@ void occ_interrupt(uint32_t chip_id)
/* Dispatch */
if (ireg & OCB_OCI_OCIMISC_IRQ_TMGT)
occ_tmgt_interrupt();
+
+ /* We may have masked-out OCB_OCI_OCIMISC_IRQ in the previous
+ * OCCMISC_AND write. Check if there are any new source bits set,
+ * and trigger another interrupt if so.
+ */
+ rc = xscom_read(chip_id, OCB_OCI_OCCMISC, &ireg);
+ if (!rc && (ireg & OCB_OCI_OCIMISC_MASK))
+ xscom_write(chip_id, OCB_OCI_OCCMISC_OR, OCB_OCI_OCIMISC_IRQ);
}
void occ_fsp_init(void)
OpenPOWER on IntegriCloud