Skyrim doesn't use the platform feature mailbox for communication for I2C arbitration, it relies upon ringing a doorbell. Link: https://lore.kernel.org/linux-i2c/20220916131854.687371-3-jsd@xxxxxxxxxxxx/ Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx> --- v2->v3: * Use CPU ID rather than ACPI ID, this will be pushed to a later patch v1->v2: * New patch doorbell; get status field --- drivers/i2c/busses/i2c-designware-amdpsp.c | 28 ++++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c index 105584abcf8f..2c671973010d 100644 --- a/drivers/i2c/busses/i2c-designware-amdpsp.c +++ b/drivers/i2c/busses/i2c-designware-amdpsp.c @@ -73,34 +73,43 @@ static int psp_send_check_i2c_req(struct psp_i2c_req *req) return check_i2c_req_sts(req); } -static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type) +static int psp_send_i2c_req_amdi0019(enum psp_i2c_req_type i2c_req_type) { struct psp_i2c_req *req; - unsigned long start; int status, ret; /* Allocate command-response buffer */ req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; - req->hdr.payload_size = sizeof(*req); req->type = i2c_req_type; - - start = jiffies; ret = read_poll_timeout(psp_send_check_i2c_req, status, (status != -EBUSY), PSP_I2C_REQ_RETRY_DELAY_US, PSP_I2C_REQ_RETRY_CNT * PSP_I2C_REQ_RETRY_DELAY_US, 0, req); - if (ret) { + kfree(req); + + if (ret) dev_err(psp_i2c_dev, "Timed out waiting for PSP to %s I2C bus\n", (i2c_req_type == PSP_I2C_REQ_ACQUIRE) ? "release" : "acquire"); - goto cleanup; - } - ret = status; + return ret ? ret : status; +} + +static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type) +{ + unsigned long start = jiffies; + int ret; + + /* Use doorbell for Skyrim and mailbox for Cezanne */ + if (boot_cpu_data.x86 == 25 && boot_cpu_data.x86_model == 80) + ret = psp_send_i2c_req_amdi0019(i2c_req_type); + else + ret = psp_ring_platform_doorbell(i2c_req_type); + if (ret) { dev_err(psp_i2c_dev, "PSP communication error\n"); goto cleanup; @@ -115,7 +124,6 @@ static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type) psp_i2c_mbox_fail = true; } - kfree(req); return ret; } -- 2.34.1