summaryrefslogtreecommitdiff
path: root/src/southbridge/intel/common/smbus.c
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2020-01-02 16:36:56 +0200
committerKyösti Mälkki <kyosti.malkki@gmail.com>2020-01-09 18:47:06 +0000
commit65f5de2bc44baaa88c7ce1c7525f0a0b9f6bc6e8 (patch)
treeaf958093cead467628de5549ab7e210f1d5a449f /src/southbridge/intel/common/smbus.c
parentb49638dbe4cb8fe2920fc9ca82a0b9e0b169bf27 (diff)
downloadcoreboot-65f5de2bc44baaa88c7ce1c7525f0a0b9f6bc6e8.tar.xz
sb/intel/common: Add SMBUS register read-modify-write
Change-Id: Ibe967d02fd05f4a8f643a5c5b17885701946d1c7 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/38151 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Diffstat (limited to 'src/southbridge/intel/common/smbus.c')
-rw-r--r--src/southbridge/intel/common/smbus.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/southbridge/intel/common/smbus.c b/src/southbridge/intel/common/smbus.c
index 00ff1dd4c2..30d0cd098c 100644
--- a/src/southbridge/intel/common/smbus.c
+++ b/src/southbridge/intel/common/smbus.c
@@ -82,6 +82,15 @@ static u8 host_inb(unsigned int base, u8 reg)
return inb(base + reg);
}
+static void host_and_or(unsigned int base, u8 reg, u8 mask, u8 or)
+{
+ u8 value;
+ value = host_inb(base, reg);
+ value &= mask;
+ value |= or;
+ host_outb(base, reg, value);
+}
+
static int host_completed(u8 status)
{
if (status & SMBHSTSTS_HOST_BUSY)
@@ -129,7 +138,7 @@ static int setup_command(unsigned int smbus_base, u8 ctrl, u8 xmitadd)
SMBUS_WAIT_UNTIL_READY_TIMEOUT);
/* Clear any lingering errors, so the transaction will run. */
- host_outb(smbus_base, SMBHSTSTAT, host_inb(smbus_base, SMBHSTSTAT));
+ host_and_or(smbus_base, SMBHSTSTAT, 0xff, 0);
/* Set up transaction */
/* Disable interrupts */
@@ -147,7 +156,7 @@ static int execute_command(unsigned int smbus_base)
u8 status;
/* Start the command. */
- host_outb(smbus_base, SMBHSTCTL, host_inb(smbus_base, SMBHSTCTL) | SMBHSTCNT_START);
+ host_and_or(smbus_base, SMBHSTCTL, 0xff, SMBHSTCNT_START);
/* Poll for it to start. */
do {
@@ -298,9 +307,8 @@ static int block_cmd_loop(unsigned int smbus_base,
/* Indicate that next byte is the last one. */
if (sw_drives_nak && (bytes + 1 >= max_bytes)) {
- host_outb(smbus_base, SMBHSTCTL,
- host_inb(smbus_base, SMBHSTCTL) |
- SMBHSTCNT_LAST_BYTE);
+ host_and_or(smbus_base, SMBHSTCTL,
+ 0xff, SMBHSTCNT_LAST_BYTE);
}
}