diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/slw.c | 12 | ||||
-rw-r--r-- | hw/xscom.c | 26 |
2 files changed, 29 insertions, 9 deletions
@@ -1242,11 +1242,13 @@ void slw_update_timer_expiry(uint64_t new_target) do { /* Grab generation and spin if odd */ + _xscom_lock(); for (;;) { - rc = xscom_read(slw_timer_chip, 0xE0006, &gen); + rc = _xscom_read(slw_timer_chip, 0xE0006, &gen, false); if (rc) { prerror("SLW: Error %lld reading tmr gen " " count\n", rc); + _xscom_unlock(); return; } if (!(gen & 1)) @@ -1271,25 +1273,29 @@ void slw_update_timer_expiry(uint64_t new_target) */ prerror("SLW: timer stuck, falling back to OPAL pollers. You will likely have slower I2C and may have experienced increased jitter.\n"); prlog(PR_DEBUG, "SLW: Stuck with odd generation !\n"); + _xscom_unlock(); slw_has_timer = false; slw_dump_timer_ffdc(); return; } } - rc = xscom_write(slw_timer_chip, 0x5003A, req); + rc = _xscom_write(slw_timer_chip, 0x5003A, req, false); if (rc) { prerror("SLW: Error %lld writing tmr request\n", rc); + _xscom_unlock(); return; } /* Re-check gen count */ - rc = xscom_read(slw_timer_chip, 0xE0006, &gen2); + rc = _xscom_read(slw_timer_chip, 0xE0006, &gen2, false); if (rc) { prerror("SLW: Error %lld re-reading tmr gen " " count\n", rc); + _xscom_unlock(); return; } + _xscom_unlock(); } while(gen != gen2); /* Check if the timer is working. If at least 1ms has elapsed @@ -402,10 +402,20 @@ static uint32_t xscom_decode_chiplet(uint32_t partid, uint64_t *pcb_addr) return gcid; } +void _xscom_lock(void) +{ + lock(&xscom_lock); +} + +void _xscom_unlock(void) +{ + unlock(&xscom_lock); +} + /* * External API */ -int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val) +int _xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val, bool take_lock) { uint32_t gcid; int rc; @@ -445,7 +455,8 @@ int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val) } /* HW822317 requires us to do global locking */ - lock(&xscom_lock); + if (take_lock) + lock(&xscom_lock); /* Direct vs indirect access */ if (pcb_addr & XSCOM_ADDR_IND_FLAG) @@ -454,13 +465,14 @@ int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val) rc = __xscom_read(gcid, pcb_addr & 0x7fffffff, val); /* Unlock it */ - unlock(&xscom_lock); + if (take_lock) + unlock(&xscom_lock); return rc; } opal_call(OPAL_XSCOM_READ, xscom_read, 3); -int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) +int _xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val, bool take_lock) { uint32_t gcid; int rc; @@ -488,7 +500,8 @@ int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) } /* HW822317 requires us to do global locking */ - lock(&xscom_lock); + if (take_lock) + lock(&xscom_lock); /* Direct vs indirect access */ if (pcb_addr & XSCOM_ADDR_IND_FLAG) @@ -497,7 +510,8 @@ int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) rc = __xscom_write(gcid, pcb_addr & 0x7fffffff, val); /* Unlock it */ - unlock(&xscom_lock); + if (take_lock) + unlock(&xscom_lock); return rc; } opal_call(OPAL_XSCOM_WRITE, xscom_write, 3); |