arch/powerpc/platforms/powernv/opal-elog.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powernv/opal-elog.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/powernv/opal-elog.c
Extension
.c
Size
8013 bytes
Lines
340
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct elog_obj {
	struct kobject kobj;
	struct bin_attribute raw_attr;
	uint64_t id;
	uint64_t type;
	size_t size;
	char *buffer;
};
#define to_elog_obj(x) container_of(x, struct elog_obj, kobj)

struct elog_attribute {
	struct attribute attr;
	ssize_t (*show)(struct elog_obj *elog, struct elog_attribute *attr,
			char *buf);
	ssize_t (*store)(struct elog_obj *elog, struct elog_attribute *attr,
			 const char *buf, size_t count);
};
#define to_elog_attr(x) container_of(x, struct elog_attribute, attr)

static ssize_t elog_id_show(struct elog_obj *elog_obj,
			    struct elog_attribute *attr,
			    char *buf)
{
	return sysfs_emit(buf, "0x%llx\n", elog_obj->id);
}

static const char *elog_type_to_string(uint64_t type)
{
	switch (type) {
	case 0: return "PEL";
	default: return "unknown";
	}
}

static ssize_t elog_type_show(struct elog_obj *elog_obj,
			      struct elog_attribute *attr,
			      char *buf)
{
	return sysfs_emit(buf, "0x%llx %s\n", elog_obj->type,
			  elog_type_to_string(elog_obj->type));
}

static ssize_t elog_ack_show(struct elog_obj *elog_obj,
			     struct elog_attribute *attr,
			     char *buf)
{
	return sysfs_emit(buf, "ack - acknowledge log message\n");
}

static ssize_t elog_ack_store(struct elog_obj *elog_obj,
			      struct elog_attribute *attr,
			      const char *buf,
			      size_t count)
{
	/*
	 * Try to self remove this attribute. If we are successful,
	 * delete the kobject itself.
	 */
	if (sysfs_remove_file_self(&elog_obj->kobj, &attr->attr)) {
		opal_send_ack_elog(elog_obj->id);
		kobject_put(&elog_obj->kobj);
	}
	return count;
}

static struct elog_attribute id_attribute =
	__ATTR(id, 0444, elog_id_show, NULL);
static struct elog_attribute type_attribute =
	__ATTR(type, 0444, elog_type_show, NULL);
static struct elog_attribute ack_attribute =
	__ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store);

static struct kset *elog_kset;

static ssize_t elog_attr_show(struct kobject *kobj,
			      struct attribute *attr,
			      char *buf)
{
	struct elog_attribute *attribute;
	struct elog_obj *elog;

	attribute = to_elog_attr(attr);
	elog = to_elog_obj(kobj);

	if (!attribute->show)
		return -EIO;

	return attribute->show(elog, attribute, buf);
}

Annotation

Implementation Notes