/*
 * PowerNV OPAL Dump Interface
 *
 * Copyright 2013,2014 IBM Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/kobject.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/delay.h>

#include <asm/opal.h>

#define DUMP_TYPE_FSP	0x01

struct dump_obj {
	struct kobject  kobj;
	struct bin_attribute dump_attr;
	uint32_t	id;  /* becomes object name */
	uint32_t	type;
	uint32_t	size;
	char		*buffer;
};
#define to_dump_obj(x) container_of(x, struct dump_obj, kobj)

struct dump_attribute {
	struct attribute attr;
	ssize_t (*show)(struct dump_obj *dump, struct dump_attribute *attr,
			char *buf);
	ssize_t (*store)(struct dump_obj *dump, struct dump_attribute *attr,
			 const char *buf, size_t count);
};
#define to_dump_attr(x) container_of(x, struct dump_attribute, attr)

static ssize_t dump_id_show(struct dump_obj *dump_obj,
			    struct dump_attribute *attr,
			    char *buf)
{
	return sprintf(buf, "0x%x\n", dump_obj->id);
}

static const char* dump_type_to_string(uint32_t type)
{
	switch (type) {
	case 0x01: return "SP Dump";
	case 0x02: return "System/Platform Dump";
	case 0x03: return "SMA Dump";
	default: return "unknown";
	}
}

static ssize_t dump_type_show(struct dump_obj *dump_obj,
			      struct dump_attribute *attr,
			      char *buf)
{
	
	return sprintf(buf, "0x%x %s\n", dump_obj->type,
		       dump_type_to_string(dump_obj->type));
}

static ssize_t dump_ack_show(struct dump_obj *dump_obj,
			     struct dump_attribute *attr,
			     char *buf)
{
	return sprintf(buf, "ack - acknowledge dump\n");
}

/*
 * Send acknowledgement to OPAL
 */
static int64_t dump_send_ack(uint32_t dump_id)
{
	int rc;

	rc = opal_dump_ack(dump_id);
	if (rc)
		pr_warn("%s: Failed to send ack to Dump ID 0x%x (%d)\n",
			__func__, dump_id, rc);
	return rc;
}

static ssize_t dump_ack_store(struct dump_obj *dump_obj,
			      struct dump_attribute *attr,
			      const char *buf,
			      size_t count)
{
	dump_send_ack(dump_obj->id);
	sysfs_remove_file_self(&dump_obj->kobj, &attr->attr);
	kobject_put(&dump_obj->kobj);
	return count;
}

/* Attributes of a dump
 * The binary attribute of the dump itself is dynamic
 * due to the dynamic size of the dump
 */
static struct dump_attribute id_attribute =
	__ATTR(id, 0666, dump_id_show, NULL);
static struct dump_attribute type_attribute =
	__ATTR(type, 0666, dump_type_show, NULL);
static struct dump_attribute ack_attribute =
	__ATTR(acknowledge, 0660, dump_ack_show, dump_ack_store);

static ssize_t init_dump_show(struct dump_obj *dump_obj,
			      struct dump_attribute *attr,
			      char *buf)
{
	return sprintf(buf, "1 - initiate dump\n");
}

static int64_t dump_fips_init(uint8_t type)
{
	int rc;

	rc = opal_dump_init(type);
	if (rc)
		pr_warn("%s: Failed to initiate FipS dump (%d)\n",
			__func__, rc);
	return rc;
}

static ssize_t init_dump_store(struct dump_obj *dump_obj,
			       struct dump_attribute *attr,
			       const char *buf,
			       size_t count)
{
	dump_fips_init(DUMP_TYPE_FSP);
	pr_info("%s: Initiated FSP dump\n", __func__);
	return count;
}

static struct dump_attribute initiate_attribute =
	__ATTR(initiate_dump, 0600, init_dump_show, init_dump_store);

static struct attribute *initiate_attrs[] = {
	&initiate_attribute.attr,
	NULL,
};

static struct attribute_group initiate_attr_group = {
	.attrs = initiate_attrs,
};

static struct kset *dump_kset;

static ssize_t dump_attr_show(struct kobject *kobj,
			      struct attribute *attr,
			      char *buf)
{
	struct dump_attribute *attribute;
	struct dump_obj *dump;

	attribute = to_dump_attr(attr);
	dump = to_dump_obj(kobj);

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

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

static ssize_t dump_attr_store(struct kobject *kobj,
			       struct attribute *attr,
			       const char *buf, size_t len)
{
	struct dump_attribute *attribute;
	struct dump_obj *dump;

	attribute = to_dump_attr(attr);
	dump = to_dump_obj(kobj);

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

	return attribute->store(dump, attribute, buf, len);
}

static const struct sysfs_ops dump_sysfs_ops = {
	.show = dump_attr_show,
	.store = dump_attr_store,
};

static void dump_release(struct kobject *kobj)
{
	struct dump_obj *dump;

	dump = to_dump_obj(kobj);
	vfree(dump->buffer);
	kfree(dump);
}

static struct attribute *dump_default_attrs[] = {
	&id_attribute.attr,
	&type_attribute.attr,
	&ack_attribute.attr,
	NULL,
};

static struct kobj_type dump_ktype = {
	.sysfs_ops = &dump_sysfs_ops,
	.release = &dump_release,
	.default_attrs = dump_default_attrs,
};

static void free_dump_sg_list(struct opal_sg_list *list)
{
	struct opal_sg_list *sg1;
	while (list) {
		sg1 = list->next;
		kfree(list);
		list = sg1;
	}
	list = NULL;
}

static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump)
{
	struct opal_sg_list *sg1, *list = NULL;
	void *addr;
	int64_t size;

	addr = dump->buffer;
	size = dump->size;

	sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
	if (!sg1)
		goto nomem;

	list = sg1;
	sg1->num_entries = 0;
	while (size > 0) {
		/* Translate virtual address to physical address */
		sg1->entry[sg1->num_entries].data =
			(void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);

		if (size > PAGE_SIZE)
			sg1->entry[sg1->num_entries].length = PAGE_SIZE;
		else
			sg1->entry[sg1->num_entries].length = size;

		sg1->num_entries++;
		if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
			sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
			if (!sg1->next)
				goto nomem;

			sg1 = sg1->next;
			sg1->num_entries = 0;
		}
		addr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
	return list;

nomem:
	pr_err("%s : Failed to allocate memory\n", __func__);
	free_dump_sg_list(list);
	return NULL;
}

static void sglist_to_phy_addr(struct opal_sg_list *list)
{
	struct opal_sg_list *sg, *next;

	for (sg = list; sg; sg = next) {
		next = sg->next;
		/* Don't translate NULL pointer for last entry */
		if (sg->next)
			sg->next = (struct opal_sg_list *)__pa(sg->next);
		else
			sg->next = NULL;

		/* Convert num_entries to length */
		sg->num_entries =
			sg->num_entries * sizeof(struct opal_sg_entry) + 16;
	}
}

static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type)
{
	int rc;
	*type = 0xffffffff;

	rc = opal_dump_info2(id, size, type);

	if (rc == OPAL_PARAMETER)
		rc = opal_dump_info(id, size);

	if (rc)
		pr_warn("%s: Failed to get dump info (%d)\n",
			__func__, rc);
	return rc;
}

static int64_t dump_read_data(struct dump_obj *dump)
{
	struct opal_sg_list *list;
	uint64_t addr;
	int64_t rc;

	/* Allocate memory */
	dump->buffer = vzalloc(PAGE_ALIGN(dump->size));
	if (!dump->buffer) {
		pr_err("%s : Failed to allocate memory\n", __func__);
		rc = -ENOMEM;
		goto out;
	}

	/* Generate SG list */
	list = dump_data_to_sglist(dump);
	if (!list) {
		rc = -ENOMEM;
		goto out;
	}

	/* Translate sg list addr to real address */
	sglist_to_phy_addr(list);

	/* First entry address */
	addr = __pa(list);

	/* Fetch data */
	rc = OPAL_BUSY_EVENT;
	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
		rc = opal_dump_read(dump->id, addr);
		if (rc == OPAL_BUSY_EVENT) {
			opal_poll_events(NULL);
			msleep(20);
		}
	}

	if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL)
		pr_warn("%s: Extract dump failed for ID 0x%x\n",
			__func__, dump->id);

	/* Free SG list */
	free_dump_sg_list(list);

out:
	return rc;
}

static ssize_t dump_attr_read(struct file *filep, struct kobject *kobj,
			      struct bin_attribute *bin_attr,
			      char *buffer, loff_t pos, size_t count)
{
	ssize_t rc;

	struct dump_obj *dump = to_dump_obj(kobj);

	if (!dump->buffer) {
		rc = dump_read_data(dump);

		if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL) {
			vfree(dump->buffer);
			dump->buffer = NULL;

			return -EIO;
		}
		if (rc == OPAL_PARTIAL) {
			/* On a partial read, we just return EIO
			 * and rely on userspace to ask us to try
			 * again.
			 */
			pr_info("%s: Platform dump partially read.ID = 0x%x\n",
				__func__, dump->id);
			return -EIO;
		}
	}

	memcpy(buffer, dump->buffer + pos, count);

	/* You may think we could free the dump buffer now and retrieve
	 * it again later if needed, but due to current firmware limitation,
	 * that's not the case. So, once read into userspace once,
	 * we keep the dump around until it's acknowledged by userspace.
	 */

	return count;
}

static struct dump_obj *create_dump_obj(uint32_t id, size_t size,
					uint32_t type)
{
	struct dump_obj *dump;
	int rc;

	dump = kzalloc(sizeof(*dump), GFP_KERNEL);
	if (!dump)
		return NULL;

	dump->kobj.kset = dump_kset;

	kobject_init(&dump->kobj, &dump_ktype);

	sysfs_bin_attr_init(&dump->dump_attr);

	dump->dump_attr.attr.name = "dump";
	dump->dump_attr.attr.mode = 0400;
	dump->dump_attr.size = size;
	dump->dump_attr.read = dump_attr_read;

	dump->id = id;
	dump->size = size;
	dump->type = type;

	rc = kobject_add(&dump->kobj, NULL, "0x%x-0x%x", type, id);
	if (rc) {
		kobject_put(&dump->kobj);
		return NULL;
	}

	rc = sysfs_create_bin_file(&dump->kobj, &dump->dump_attr);
	if (rc) {
		kobject_put(&dump->kobj);
		return NULL;
	}

	pr_info("%s: New platform dump. ID = 0x%x Size %u\n",
		__func__, dump->id, dump->size);

	kobject_uevent(&dump->kobj, KOBJ_ADD);

	return dump;
}

static int process_dump(void)
{
	int rc;
	uint32_t dump_id, dump_size, dump_type;
	struct dump_obj *dump;
	char name[22];

	rc = dump_read_info(&dump_id, &dump_size, &dump_type);
	if (rc != OPAL_SUCCESS)
		return rc;

	sprintf(name, "0x%x-0x%x", dump_type, dump_id);

	/* we may get notified twice, let's handle
	 * that gracefully and not create two conflicting
	 * entries.
	 */
	if (kset_find_obj(dump_kset, name))
		return 0;

	dump = create_dump_obj(dump_id, dump_size, dump_type);
	if (!dump)
		return -1;

	return 0;
}

static void dump_work_fn(struct work_struct *work)
{
	process_dump();
}

static DECLARE_WORK(dump_work, dump_work_fn);

static void schedule_process_dump(void)
{
	schedule_work(&dump_work);
}

/*
 * New dump available notification
 *
 * Once we get notification, we add sysfs entries for it.
 * We only fetch the dump on demand, and create sysfs asynchronously.
 */
static int dump_event(struct notifier_block *nb,
		      unsigned long events, void *change)
{
	if (events & OPAL_EVENT_DUMP_AVAIL)
		schedule_process_dump();

	return 0;
}

static struct notifier_block dump_nb = {
	.notifier_call  = dump_event,
	.next           = NULL,
	.priority       = 0
};

void __init opal_platform_dump_init(void)
{
	int rc;

	dump_kset = kset_create_and_add("dump", NULL, opal_kobj);
	if (!dump_kset) {
		pr_warn("%s: Failed to create dump kset\n", __func__);
		return;
	}

	rc = sysfs_create_group(&dump_kset->kobj, &initiate_attr_group);
	if (rc) {
		pr_warn("%s: Failed to create initiate dump attr group\n",
			__func__);
		kobject_put(&dump_kset->kobj);
		return;
	}

	rc = opal_notifier_register(&dump_nb);
	if (rc) {
		pr_warn("%s: Can't register OPAL event notifier (%d)\n",
			__func__, rc);
		return;
	}

	opal_dump_resend_notification();
}
