drivers/platform/chrome/cros_usbpd_logger.c

Source file repositories/reference/linux-study-clean/drivers/platform/chrome/cros_usbpd_logger.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/chrome/cros_usbpd_logger.c
Extension
.c
Size
7275 bytes
Lines
270
Domain
Driver Families
Bucket
drivers/platform
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct logger_data {
	struct device *dev;
	struct cros_ec_dev *ec_dev;
	u8 ec_buffer[CROS_USBPD_BUFFER_SIZE];
	struct delayed_work log_work;
	struct workqueue_struct *log_workqueue;
};

static const char * const chg_type_names[] = {
	"None", "PD", "Type-C", "Proprietary", "DCP", "CDP", "SDP",
	"Other", "VBUS"
};

static const char * const role_names[] = {
	"Disconnected", "SRC", "SNK", "SNK (not charging)"
};

static const char * const fault_names[] = {
	"---", "OCP", "fast OCP", "OVP", "Discharge"
};

__printf(3, 4)
static int append_str(char *buf, int pos, const char *fmt, ...)
{
	va_list args;
	int i;

	va_start(args, fmt);
	i = vsnprintf(buf + pos, BUF_SIZE - pos, fmt, args);
	va_end(args);

	return i;
}

static struct ec_response_pd_log *ec_get_log_entry(struct logger_data *logger)
{
	struct cros_ec_dev *ec_dev = logger->ec_dev;
	struct cros_ec_command *msg;
	int ret;

	msg = (struct cros_ec_command *)logger->ec_buffer;

	msg->command = ec_dev->cmd_offset + EC_CMD_PD_GET_LOG_ENTRY;
	msg->insize = CROS_USBPD_LOG_RESP_SIZE;

	ret = cros_ec_cmd_xfer_status(ec_dev->ec_dev, msg);
	if (ret < 0)
		return ERR_PTR(ret);

	return (struct ec_response_pd_log *)msg->data;
}

static void cros_usbpd_print_log_entry(struct ec_response_pd_log *r,
				       ktime_t tstamp)
{
	const char *fault, *role, *chg_type;
	struct usb_chg_measures *meas;
	struct mcdp_info *minfo;
	int role_idx, type_idx;
	char buf[BUF_SIZE + 1];
	struct rtc_time rt;
	int len = 0;
	s32 rem;
	int i;

	/* The timestamp is the number of 1024th of seconds in the past */
	tstamp = ktime_sub_us(tstamp, r->timestamp << PD_LOG_TIMESTAMP_SHIFT);
	rt = rtc_ktime_to_tm(tstamp);

	switch (r->type) {
	case PD_EVENT_MCU_CHARGE:
		if (r->data & CHARGE_FLAGS_OVERRIDE)
			len += append_str(buf, len, "override ");

		if (r->data & CHARGE_FLAGS_DELAYED_OVERRIDE)
			len += append_str(buf, len, "pending_override ");

		role_idx = r->data & CHARGE_FLAGS_ROLE_MASK;
		role = role_idx < ARRAY_SIZE(role_names) ?
			role_names[role_idx] : "Unknown";

		type_idx = (r->data & CHARGE_FLAGS_TYPE_MASK)
			 >> CHARGE_FLAGS_TYPE_SHIFT;

		chg_type = type_idx < ARRAY_SIZE(chg_type_names) ?
			chg_type_names[type_idx] : "???";

		if (role_idx == USB_PD_PORT_POWER_DISCONNECTED ||
		    role_idx == USB_PD_PORT_POWER_SOURCE) {
			len += append_str(buf, len, "%s", role);

Annotation

Implementation Notes