Lines Matching +full:i2c +full:- +full:arbitrator
1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/i2c.h>
5 #include <linux/psp-platform-access.h>
9 #include "i2c-designware-core.h"
43 /* Status field in command-response buffer is updated by PSP */ in check_i2c_req_sts()
44 status = READ_ONCE(req->hdr.status); in check_i2c_req_sts()
50 return -EBUSY; in check_i2c_req_sts()
53 return -EIO; in check_i2c_req_sts()
58 * Errors in x86-PSP i2c-arbitration protocol may occur at two levels:
59 * 1. mailbox communication - PSP is not operational or some IO errors with
61 * 2. i2c-requests - PSP refuses to grant i2c arbitration to x86 for too long.
65 * up and if -EIO is returned the second level will be checked.
72 if (ret == -EIO) in psp_send_i2c_req_cezanne()
82 ret = psp_ring_platform_doorbell(req->type, &req->hdr.status); in psp_send_i2c_req_doorbell()
83 if (ret == -EIO) in psp_send_i2c_req_doorbell()
95 /* Allocate command-response buffer */ in psp_send_i2c_req()
98 return -ENOMEM; in psp_send_i2c_req()
100 req->hdr.payload_size = sizeof(*req); in psp_send_i2c_req()
101 req->type = i2c_req_type; in psp_send_i2c_req()
105 (status != -EBUSY), in psp_send_i2c_req()
110 dev_err(psp_i2c_dev, "Timed out waiting for PSP to %s I2C bus\n", in psp_send_i2c_req()
123 jiffies_to_msecs(jiffies - start)); in psp_send_i2c_req()
127 dev_err(psp_i2c_dev, "Assume i2c bus is for exclusive host usage\n"); in psp_send_i2c_req()
147 jiffies_to_msecs(jiffies - psp_i2c_sem_acquired)); in release_bus()
199 * In case of errors with PSP arbitrator psp_i2c_mbox_fail variable is in psp_acquire_i2c_bus()
201 * communication with PSP. At any case i2c bus is granted to the caller, in psp_acquire_i2c_bus()
221 psp_i2c_access_count--; in psp_release_i2c_bus()
238 * drivers/i2c/i2c-core-base.c, but with PSP acquire and release operations
239 * added. With this in place we can ensure that i2c clients on the bus shared
241 * operations - that is e.g. write-wait-read.
247 rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter)); in i2c_adapter_dw_psp_lock_bus()
255 ret = rt_mutex_trylock(&adapter->bus_lock); in i2c_adapter_dw_psp_trylock_bus()
268 rt_mutex_unlock(&adapter->bus_lock); in i2c_adapter_dw_psp_unlock_bus()
282 return -ENODEV; in i2c_dw_amdpsp_probe_lock_support()
285 return -ENODEV; in i2c_dw_amdpsp_probe_lock_support()
287 if (!(dev->flags & ARBITRATION_SEMAPHORE)) in i2c_dw_amdpsp_probe_lock_support()
288 return -ENODEV; in i2c_dw_amdpsp_probe_lock_support()
292 return -EEXIST; in i2c_dw_amdpsp_probe_lock_support()
296 if (rdev->device == 0x1630) in i2c_dw_amdpsp_probe_lock_support()
303 return -EPROBE_DEFER; in i2c_dw_amdpsp_probe_lock_support()
305 psp_i2c_dev = dev->dev; in i2c_dw_amdpsp_probe_lock_support()
307 dev_info(psp_i2c_dev, "I2C bus managed by AMD PSP\n"); in i2c_dw_amdpsp_probe_lock_support()
310 * Install global locking callbacks for adapter as well as internal i2c in i2c_dw_amdpsp_probe_lock_support()
313 dev->adapter.lock_ops = &i2c_dw_psp_lock_ops; in i2c_dw_amdpsp_probe_lock_support()
314 dev->acquire_lock = psp_acquire_i2c_bus; in i2c_dw_amdpsp_probe_lock_support()
315 dev->release_lock = psp_release_i2c_bus; in i2c_dw_amdpsp_probe_lock_support()