aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/slw.c12
-rw-r--r--hw/xscom.c26
2 files changed, 29 insertions, 9 deletions
diff --git a/hw/slw.c b/hw/slw.c
index b4fb6ec..32481fb 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -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
diff --git a/hw/xscom.c b/hw/xscom.c
index e51f182..9afa952 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -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);