drivers/i2c/busses/i2c-designware-amdpsp.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-designware-amdpsp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-designware-amdpsp.c- Extension
.c- Size
- 7353 bytes
- Lines
- 311
- Domain
- Driver Families
- Bucket
- drivers/i2c
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/i2c.hlinux/pci.hlinux/psp-platform-access.hlinux/psp.hlinux/workqueue.hi2c-designware-core.h
Detected Declarations
struct psp_i2c_reqenum psp_i2c_req_typefunction check_i2c_req_stsfunction levelfunction psp_send_i2c_req_doorbellfunction psp_send_i2c_reqfunction release_busfunction psp_release_i2c_bus_deferredfunction psp_acquire_i2c_busfunction psp_release_i2c_busfunction i2c_adapter_dw_psp_lock_busfunction i2c_adapter_dw_psp_trylock_busfunction i2c_adapter_dw_psp_unlock_busfunction i2c_dw_amdpsp_probe_lock_support
Annotated Snippet
struct psp_i2c_req {
struct psp_req_buffer_hdr hdr;
enum psp_i2c_req_type type;
};
static DEFINE_MUTEX(psp_i2c_access_mutex);
static unsigned long psp_i2c_sem_acquired;
static u32 psp_i2c_access_count;
static bool psp_i2c_mbox_fail;
static struct device *psp_i2c_dev;
static int (*_psp_send_i2c_req)(struct psp_i2c_req *req);
/* Helper to verify status returned by PSP */
static int check_i2c_req_sts(struct psp_i2c_req *req)
{
u32 status;
/* Status field in command-response buffer is updated by PSP */
status = READ_ONCE(req->hdr.status);
switch (status) {
case PSP_I2C_REQ_STS_OK:
return 0;
case PSP_I2C_REQ_STS_BUS_BUSY:
return -EBUSY;
case PSP_I2C_REQ_STS_INV_PARAM:
default:
return -EIO;
}
}
/*
* Errors in x86-PSP i2c-arbitration protocol may occur at two levels:
* 1. mailbox communication - PSP is not operational or some IO errors with
* basic communication had happened.
* 2. i2c-requests - PSP refuses to grant i2c arbitration to x86 for too long.
*
* In order to distinguish between these in error handling code all mailbox
* communication errors on the first level (from CCP symbols) will be passed
* up and if -EIO is returned the second level will be checked.
*/
static int psp_send_i2c_req_cezanne(struct psp_i2c_req *req)
{
int ret;
ret = psp_send_platform_access_msg(PSP_I2C_REQ_BUS_CMD, (struct psp_request *)req);
if (ret == -EIO)
return check_i2c_req_sts(req);
return ret;
}
static int psp_send_i2c_req_doorbell(struct psp_i2c_req *req)
{
int ret;
ret = psp_ring_platform_doorbell(req->type, &req->hdr.status);
if (ret == -EIO)
return check_i2c_req_sts(req);
return ret;
}
static int psp_send_i2c_req(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_obj(*req);
if (!req)
return -ENOMEM;
req->hdr.payload_size = sizeof(*req);
req->type = i2c_req_type;
start = jiffies;
ret = read_poll_timeout(_psp_send_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) {
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;
}
Annotation
- Immediate include surface: `linux/i2c.h`, `linux/pci.h`, `linux/psp-platform-access.h`, `linux/psp.h`, `linux/workqueue.h`, `i2c-designware-core.h`.
- Detected declarations: `struct psp_i2c_req`, `enum psp_i2c_req_type`, `function check_i2c_req_sts`, `function level`, `function psp_send_i2c_req_doorbell`, `function psp_send_i2c_req`, `function release_bus`, `function psp_release_i2c_bus_deferred`, `function psp_acquire_i2c_bus`, `function psp_release_i2c_bus`.
- Atlas domain: Driver Families / drivers/i2c.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.