diff options
author | Alistair Popple <alistair@popple.id.au> | 2017-08-04 14:15:19 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-08-04 17:13:10 +1000 |
commit | e3f7d42c77bfc3b899d3d636b372e1292b790656 (patch) | |
tree | 85448dddb6c16bc11c4a48c9ddd76a9fa30e6a2a | |
parent | 1c974200eb5e9c81e841733e99848885f917b108 (diff) | |
download | skiboot-e3f7d42c77bfc3b899d3d636b372e1292b790656.zip skiboot-e3f7d42c77bfc3b899d3d636b372e1292b790656.tar.gz skiboot-e3f7d42c77bfc3b899d3d636b372e1292b790656.tar.bz2 |
xscom: Add xscom_write_mask() function
It is common for xscom registers to only contain specific bit fields that
need to be modified without altering the rest of the register. This adds a
convenience function to perform xscom read-modify-write operations under a
mask.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | hw/xscom.c | 15 | ||||
-rw-r--r-- | include/xscom.h | 2 |
2 files changed, 16 insertions, 1 deletions
@@ -577,6 +577,21 @@ int _xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val, bool take_loc } opal_call(OPAL_XSCOM_WRITE, xscom_write, 3); +/* + * Perform a xscom read-modify-write. + */ +int xscom_write_mask(uint32_t partid, uint64_t pcb_addr, uint64_t val, uint64_t mask) +{ + int rc; + uint64_t old_val; + + rc = xscom_read(partid, pcb_addr, &old_val); + if (rc) + return rc; + val = (old_val & ~mask) | (val & mask); + return xscom_write(partid, pcb_addr, val); +} + int xscom_readme(uint64_t pcb_addr, uint64_t *val) { return xscom_read(this_cpu()->chip_id, pcb_addr, val); diff --git a/include/xscom.h b/include/xscom.h index 743a47b..5a5d0b9 100644 --- a/include/xscom.h +++ b/include/xscom.h @@ -230,7 +230,7 @@ static inline int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val) static inline int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) { return _xscom_write(partid, pcb_addr, val, true); } - +extern int xscom_write_mask(uint32_t partid, uint64_t pcb_addr, uint64_t val, uint64_t mask); /* This chip SCOM access */ extern int xscom_readme(uint64_t pcb_addr, uint64_t *val); |