linux/drivers/i2c/busses/i2c-designware-amdpsp.c

// SPDX-License-Identifier: GPL-2.0

#include <linux/i2c.h>
#include <linux/pci.h>
#include <linux/psp-platform-access.h>
#include <linux/psp.h>
#include <linux/workqueue.h>

#include "i2c-designware-core.h"

#define PSP_I2C_RESERVATION_TIME_MS

#define PSP_I2C_REQ_RETRY_CNT
#define PSP_I2C_REQ_RETRY_DELAY_US
#define PSP_I2C_REQ_STS_OK
#define PSP_I2C_REQ_STS_BUS_BUSY
#define PSP_I2C_REQ_STS_INV_PARAM

enum psp_i2c_req_type {};

struct psp_i2c_req {};

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)
{}

/*
 * 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)
{}

static int psp_send_i2c_req_doorbell(struct psp_i2c_req *req)
{}

static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type)
{}

static void release_bus(void)
{}

static void psp_release_i2c_bus_deferred(struct work_struct *work)
{}
static DECLARE_DELAYED_WORK(release_queue, psp_release_i2c_bus_deferred);

static int psp_acquire_i2c_bus(void)
{}

static void psp_release_i2c_bus(void)
{}

/*
 * Locking methods are based on the default implementation from
 * drivers/i2c/i2c-core-base.c, but with psp acquire and release operations
 * added. With this in place we can ensure that i2c clients on the bus shared
 * with psp are able to lock HW access to the bus for arbitrary number of
 * operations - that is e.g. write-wait-read.
 */
static void i2c_adapter_dw_psp_lock_bus(struct i2c_adapter *adapter,
					unsigned int flags)
{}

static int i2c_adapter_dw_psp_trylock_bus(struct i2c_adapter *adapter,
					  unsigned int flags)
{}

static void i2c_adapter_dw_psp_unlock_bus(struct i2c_adapter *adapter,
					  unsigned int flags)
{}

static const struct i2c_lock_operations i2c_dw_psp_lock_ops =;

int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev)
{}