// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PowerNV OPAL high level interfaces
 *
 * Copyright 2011 IBM Corp.
 */

#define pr_fmt(fmt)	"opal: " fmt

#include <linux/printk.h>
#include <linux/types.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/kobject.h>
#include <linux/delay.h>
#include <linux/memblock.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/kmsg_dump.h>
#include <linux/console.h>
#include <linux/sched/debug.h>

#include <asm/machdep.h>
#include <asm/opal.h>
#include <asm/firmware.h>
#include <asm/mce.h>
#include <asm/imc-pmu.h>
#include <asm/bug.h>

#include "powernv.h"

#define OPAL_MSG_QUEUE_MAX 16

struct opal_msg_node {
	struct list_head	list;
	struct opal_msg		msg;
};

static DEFINE_SPINLOCK(msg_list_lock);
static LIST_HEAD(msg_list);

/* /sys/firmware/opal */
struct kobject *opal_kobj;

struct opal {
	u64 base;
	u64 entry;
	u64 size;
} opal;

struct mcheck_recoverable_range {
	u64 start_addr;
	u64 end_addr;
	u64 recover_addr;
};

static int msg_list_size;

static struct mcheck_recoverable_range *mc_recoverable_range;
static int mc_recoverable_range_len;

struct device_node *opal_node;
static DEFINE_SPINLOCK(opal_write_lock);
static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
static uint32_t opal_heartbeat;
static struct task_struct *kopald_tsk;
static struct opal_msg *opal_msg;
static u32 opal_msg_size __ro_after_init;

void __init opal_configure_cores(void)
{
	u64 reinit_flags = 0;

	/* Do the actual re-init, This will clobber all FPRs, VRs, etc...
	 *
	 * It will preserve non volatile GPRs and HSPRG0/1. It will
	 * also restore HIDs and other SPRs to their original value
	 * but it might clobber a bunch.
	 */
#ifdef __BIG_ENDIAN__
	reinit_flags |= OPAL_REINIT_CPUS_HILE_BE;
#else
	reinit_flags |= OPAL_REINIT_CPUS_HILE_LE;
#endif

	/*
	 * POWER9 always support running hash:
	 *  ie. Host hash  supports  hash guests
	 *      Host radix supports  hash/radix guests
	 */
	if (early_cpu_has_feature(CPU_FTR_ARCH_300)) {
		reinit_flags |= OPAL_REINIT_CPUS_MMU_HASH;
		if (early_radix_enabled())
			reinit_flags |= OPAL_REINIT_CPUS_MMU_RADIX;
	}

	opal_reinit_cpus(reinit_flags);

	/* Restore some bits */
	if (cur_cpu_spec->cpu_restore)
		cur_cpu_spec->cpu_restore();
}

int __init early_init_dt_scan_opal(unsigned long node,
				   const char *uname, int depth, void *data)
{
	const void *basep, *entryp, *sizep;
	int basesz, entrysz, runtimesz;

	if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
		return 0;

	basep  = of_get_flat_dt_prop(node, "opal-base-address", &basesz);
	entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz);
	sizep = of_get_flat_dt_prop(node, "opal-runtime-size", &runtimesz);

	if (!basep || !entryp || !sizep)
		return 1;

	opal.base = of_read_number(basep, basesz/4);
	opal.entry = of_read_number(entryp, entrysz/4);
	opal.size = of_read_number(sizep, runtimesz/4);

	pr_debug("OPAL Base  = 0x%llx (basep=%p basesz=%d)\n",
		 opal.base, basep, basesz);
	pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%d)\n",
		 opal.entry, entryp, entrysz);
	pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n",
		 opal.size, sizep, runtimesz);

	if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
		powerpc_firmware_features |= FW_FEATURE_OPAL;
		pr_debug("OPAL detected !\n");
	} else {
		panic("OPAL != V3 detected, no longer supported.\n");
	}

	return 1;
}

int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
				   const char *uname, int depth, void *data)
{
	int i, psize, size;
	const __be32 *prop;

	if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
		return 0;

	prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &psize);

	if (!prop)
		return 1;

	pr_debug("Found machine check recoverable ranges.\n");

	/*
	 * Calculate number of available entries.
	 *
	 * Each recoverable address range entry is (start address, len,
	 * recovery address), 2 cells each for start and recovery address,
	 * 1 cell for len, totalling 5 cells per entry.
	 */
	mc_recoverable_range_len = psize / (sizeof(*prop) * 5);

	/* Sanity check */
	if (!mc_recoverable_range_len)
		return 1;

	/* Size required to hold all the entries. */
	size = mc_recoverable_range_len *
			sizeof(struct mcheck_recoverable_range);

	/*
	 * Allocate a buffer to hold the MC recoverable ranges.
	 */
	mc_recoverable_range = memblock_alloc(size, __alignof__(u64));
	if (!mc_recoverable_range)
		panic("%s: Failed to allocate %u bytes align=0x%lx\n",
		      __func__, size, __alignof__(u64));

	for (i = 0; i < mc_recoverable_range_len; i++) {
		mc_recoverable_range[i].start_addr =
					of_read_number(prop + (i * 5) + 0, 2);
		mc_recoverable_range[i].end_addr =
					mc_recoverable_range[i].start_addr +
					of_read_number(prop + (i * 5) + 2, 1);
		mc_recoverable_range[i].recover_addr =
					of_read_number(prop + (i * 5) + 3, 2);

		pr_debug("Machine check recoverable range: %llx..%llx: %llx\n",
				mc_recoverable_range[i].start_addr,
				mc_recoverable_range[i].end_addr,
				mc_recoverable_range[i].recover_addr);
	}
	return 1;
}

static int __init opal_register_exception_handlers(void)
{
#ifdef __BIG_ENDIAN__
	u64 glue;

	if (!(powerpc_firmware_features & FW_FEATURE_OPAL))
		return -ENODEV;

	/* Hookup some exception handlers except machine check. We use the
	 * fwnmi area at 0x7000 to provide the glue space to OPAL
	 */
	glue = 0x7000;

	/*
	 * Only ancient OPAL firmware requires this.
	 * Specifically, firmware from FW810.00 (released June 2014)
	 * through FW810.20 (Released October 2014).
	 *
	 * Check if we are running on newer (post Oct 2014) firmware that
	 * exports the OPAL_HANDLE_HMI token. If yes, then don't ask OPAL to
	 * patch the HMI interrupt and we catch it directly in Linux.
	 *
	 * For older firmware (i.e < FW810.20), we fallback to old behavior and
	 * let OPAL patch the HMI vector and handle it inside OPAL firmware.
	 *
	 * For newer firmware we catch/handle the HMI directly in Linux.
	 */
	if (!opal_check_token(OPAL_HANDLE_HMI)) {
		pr_info("Old firmware detected, OPAL handles HMIs.\n");
		opal_register_exception_handler(
				OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
				0, glue);
		glue += 128;
	}

	/*
	 * Only applicable to ancient firmware, all modern
	 * (post March 2015/skiboot 5.0) firmware will just return
	 * OPAL_UNSUPPORTED.
	 */
	opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
#endif

	return 0;
}
machine_early_initcall(powernv, opal_register_exception_handlers);

static void queue_replay_msg(void *msg)
{
	struct opal_msg_node *msg_node;

	if (msg_list_size < OPAL_MSG_QUEUE_MAX) {
		msg_node = kzalloc(sizeof(*msg_node), GFP_ATOMIC);
		if (msg_node) {
			INIT_LIST_HEAD(&msg_node->list);
			memcpy(&msg_node->msg, msg, sizeof(struct opal_msg));
			list_add_tail(&msg_node->list, &msg_list);
			msg_list_size++;
		} else
			pr_warn_once("message queue no memory\n");

		if (msg_list_size >= OPAL_MSG_QUEUE_MAX)
			pr_warn_once("message queue full\n");
	}
}

static void dequeue_replay_msg(enum opal_msg_type msg_type)
{
	struct opal_msg_node *msg_node, *tmp;

	list_for_each_entry_safe(msg_node, tmp, &msg_list, list) {
		if (be32_to_cpu(msg_node->msg.msg_type) != msg_type)
			continue;

		atomic_notifier_call_chain(&opal_msg_notifier_head[msg_type],
					msg_type,
					&msg_node->msg);

		list_del(&msg_node->list);
		kfree(msg_node);
		msg_list_size--;
	}
}

/*
 * Opal message notifier based on message type. Allow subscribers to get
 * notified for specific messgae type.
 */
int opal_message_notifier_register(enum opal_msg_type msg_type,
					struct notifier_block *nb)
{
	int ret;
	unsigned long flags;

	if (!nb || msg_type >= OPAL_MSG_TYPE_MAX) {
		pr_warn("%s: Invalid arguments, msg_type:%d\n",
			__func__, msg_type);
		return -EINVAL;
	}

	spin_lock_irqsave(&msg_list_lock, flags);
	ret = atomic_notifier_chain_register(
		&opal_msg_notifier_head[msg_type], nb);

	/*
	 * If the registration succeeded, replay any queued messages that came
	 * in prior to the notifier chain registration. msg_list_lock held here
	 * to ensure they're delivered prior to any subsequent messages.
	 */
	if (ret == 0)
		dequeue_replay_msg(msg_type);

	spin_unlock_irqrestore(&msg_list_lock, flags);

	return ret;
}
EXPORT_SYMBOL_GPL(opal_message_notifier_register);

int opal_message_notifier_unregister(enum opal_msg_type msg_type,
				     struct notifier_block *nb)
{
	return atomic_notifier_chain_unregister(
			&opal_msg_notifier_head[msg_type], nb);
}
EXPORT_SYMBOL_GPL(opal_message_notifier_unregister);

static void opal_message_do_notify(uint32_t msg_type, void *msg)
{
	unsigned long flags;
	bool queued = false;

	spin_lock_irqsave(&msg_list_lock, flags);
	if (opal_msg_notifier_head[msg_type].head == NULL) {
		/*
		 * Queue up the msg since no notifiers have registered
		 * yet for this msg_type.
		 */
		queue_replay_msg(msg);
		queued = true;
	}
	spin_unlock_irqrestore(&msg_list_lock, flags);

	if (queued)
		return;

	/* notify subscribers */
	atomic_notifier_call_chain(&opal_msg_notifier_head[msg_type],
					msg_type, msg);
}

static void opal_handle_message(void)
{
	s64 ret;
	u32 type;

	ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
	/* No opal message pending. */
	if (ret == OPAL_RESOURCE)
		return;

	/* check for errors. */
	if (ret) {
		pr_warn("%s: Failed to retrieve opal message, err=%lld\n",
			__func__, ret);
		return;
	}

	type = be32_to_cpu(opal_msg->msg_type);

	/* Sanity check */
	if (type >= OPAL_MSG_TYPE_MAX) {
		pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
		return;
	}
	opal_message_do_notify(type, (void *)opal_msg);
}

static irqreturn_t opal_message_notify(int irq, void *data)
{
	opal_handle_message();
	return IRQ_HANDLED;
}

static int __init opal_message_init(struct device_node *opal_node)
{
	int ret, i, irq;

	ret = of_property_read_u32(opal_node, "opal-msg-size", &opal_msg_size);
	if (ret) {
		pr_notice("Failed to read opal-msg-size property\n");
		opal_msg_size = sizeof(struct opal_msg);
	}

	opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
	if (!opal_msg) {
		opal_msg_size = sizeof(struct opal_msg);
		/* Try to allocate fixed message size */
		opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
		BUG_ON(opal_msg == NULL);
	}

	for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
		ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);

	irq = opal_event_request(ilog2(OPAL_EVENT_MSG_PENDING));
	if (!irq) {
		pr_err("%s: Can't register OPAL event irq (%d)\n",
		       __func__, irq);
		return irq;
	}

	ret = request_irq(irq, opal_message_notify,
			IRQ_TYPE_LEVEL_HIGH, "opal-msg", NULL);
	if (ret) {
		pr_err("%s: Can't request OPAL event irq (%d)\n",
		       __func__, ret);
		return ret;
	}

	return 0;
}

int opal_get_chars(uint32_t vtermno, char *buf, int count)
{
	s64 rc;
	__be64 evt, len;

	if (!opal.entry)
		return -ENODEV;
	opal_poll_events(&evt);
	if ((be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_INPUT) == 0)
		return 0;
	len = cpu_to_be64(count);
	rc = opal_console_read(vtermno, &len, buf);
	if (rc == OPAL_SUCCESS)
		return be64_to_cpu(len);
	return 0;
}

static int __opal_put_chars(uint32_t vtermno, const char *data, int total_len, bool atomic)
{
	unsigned long flags = 0 /* shut up gcc */;
	int written;
	__be64 olen;
	s64 rc;

	if (!opal.entry)
		return -ENODEV;

	if (atomic)
		spin_lock_irqsave(&opal_write_lock, flags);
	rc = opal_console_write_buffer_space(vtermno, &olen);
	if (rc || be64_to_cpu(olen) < total_len) {
		/* Closed -> drop characters */
		if (rc)
			written = total_len;
		else
			written = -EAGAIN;
		goto out;
	}

	/* Should not get a partial write here because space is available. */
	olen = cpu_to_be64(total_len);
	rc = opal_console_write(vtermno, &olen, data);
	if (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
		if (rc == OPAL_BUSY_EVENT)
			opal_poll_events(NULL);
		written = -EAGAIN;
		goto out;
	}

	/* Closed or other error drop */
	if (rc != OPAL_SUCCESS) {
		written = opal_error_code(rc);
		goto out;
	}

	written = be64_to_cpu(olen);
	if (written < total_len) {
		if (atomic) {
			/* Should not happen */
			pr_warn("atomic console write returned partial "
				"len=%d written=%d\n", total_len, written);
		}
		if (!written)
			written = -EAGAIN;
	}

out:
	if (atomic)
		spin_unlock_irqrestore(&opal_write_lock, flags);

	return written;
}

int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
{
	return __opal_put_chars(vtermno, data, total_len, false);
}

/*
 * opal_put_chars_atomic will not perform partial-writes. Data will be
 * atomically written to the terminal or not at all. This is not strictly
 * true at the moment because console space can race with OPAL's console
 * writes.
 */
int opal_put_chars_atomic(uint32_t vtermno, const char *data, int total_len)
{
	return __opal_put_chars(vtermno, data, total_len, true);
}

static s64 __opal_flush_console(uint32_t vtermno)
{
	s64 rc;

	if (!opal_check_token(OPAL_CONSOLE_FLUSH)) {
		__be64 evt;

		/*
		 * If OPAL_CONSOLE_FLUSH is not implemented in the firmware,
		 * the console can still be flushed by calling the polling
		 * function while it has OPAL_EVENT_CONSOLE_OUTPUT events.
		 */
		WARN_ONCE(1, "opal: OPAL_CONSOLE_FLUSH missing.\n");

		opal_poll_events(&evt);
		if (!(be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_OUTPUT))
			return OPAL_SUCCESS;
		return OPAL_BUSY;

	} else {
		rc = opal_console_flush(vtermno);
		if (rc == OPAL_BUSY_EVENT) {
			opal_poll_events(NULL);
			rc = OPAL_BUSY;
		}
		return rc;
	}

}

/*
 * opal_flush_console spins until the console is flushed
 */
int opal_flush_console(uint32_t vtermno)
{
	for (;;) {
		s64 rc = __opal_flush_console(vtermno);

		if (rc == OPAL_BUSY || rc == OPAL_PARTIAL) {
			mdelay(1);
			continue;
		}

		return opal_error_code(rc);
	}
}

/*
 * opal_flush_chars is an hvc interface that sleeps until the console is
 * flushed if wait, otherwise it will return -EBUSY if the console has data,
 * -EAGAIN if it has data and some of it was flushed.
 */
int opal_flush_chars(uint32_t vtermno, bool wait)
{
	for (;;) {
		s64 rc = __opal_flush_console(vtermno);

		if (rc == OPAL_BUSY || rc == OPAL_PARTIAL) {
			if (wait) {
				msleep(OPAL_BUSY_DELAY_MS);
				continue;
			}
			if (rc == OPAL_PARTIAL)
				return -EAGAIN;
		}

		return opal_error_code(rc);
	}
}

static int opal_recover_mce(struct pt_regs *regs,
					struct machine_check_event *evt)
{
	int recovered = 0;

	if (regs_is_unrecoverable(regs)) {
		/* If MSR_RI isn't set, we cannot recover */
		pr_err("Machine check interrupt unrecoverable: MSR(RI=0)\n");
		recovered = 0;
	} else if (evt->disposition == MCE_DISPOSITION_RECOVERED) {
		/* Platform corrected itself */
		recovered = 1;
	} else if (evt->severity == MCE_SEV_FATAL) {
		/* Fatal machine check */
		pr_err("Machine check interrupt is fatal\n");
		recovered = 0;
	}

	if (!recovered && evt->sync_error) {
		/*
		 * Try to kill processes if we get a synchronous machine check
		 * (e.g., one caused by execution of this instruction). This
		 * will devolve into a panic if we try to kill init or are in
		 * an interrupt etc.
		 *
		 * TODO: Queue up this address for hwpoisioning later.
		 * TODO: This is not quite right for d-side machine
		 *       checks ->nip is not necessarily the important
		 *       address.
		 */
		if ((user_mode(regs))) {
			_exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip);
			recovered = 1;
		} else if (die_will_crash()) {
			/*
			 * die() would kill the kernel, so better to go via
			 * the platform reboot code that will log the
			 * machine check.
			 */
			recovered = 0;
		} else {
			die_mce("Machine check", regs, SIGBUS);
			recovered = 1;
		}
	}

	return recovered;
}

void __noreturn pnv_platform_error_reboot(struct pt_regs *regs, const char *msg)
{
	panic_flush_kmsg_start();

	pr_emerg("Hardware platform error: %s\n", msg);
	if (regs)
		show_regs(regs);
	smp_send_stop();

	panic_flush_kmsg_end();

	/*
	 * Don't bother to shut things down because this will
	 * xstop the system.
	 */
	if (opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, msg)
						== OPAL_UNSUPPORTED) {
		pr_emerg("Reboot type %d not supported for %s\n",
				OPAL_REBOOT_PLATFORM_ERROR, msg);
	}

	/*
	 * We reached here. There can be three possibilities:
	 * 1. We are running on a firmware level that do not support
	 *    opal_cec_reboot2()
	 * 2. We are running on a firmware level that do not support
	 *    OPAL_REBOOT_PLATFORM_ERROR reboot type.
	 * 3. We are running on FSP based system that does not need
	 *    opal to trigger checkstop explicitly for error analysis.
	 *    The FSP PRD component would have already got notified
	 *    about this error through other channels.
	 * 4. We are running on a newer skiboot that by default does
	 *    not cause a checkstop, drops us back to the kernel to
	 *    extract context and state at the time of the error.
	 */

	panic(msg);
}

int opal_machine_check(struct pt_regs *regs)
{
	struct machine_check_event evt;

	if (!get_mce_event(&evt, MCE_EVENT_RELEASE))
		return 0;

	/* Print things out */
	if (evt.version != MCE_V1) {
		pr_err("Machine Check Exception, Unknown event version %d !\n",
		       evt.version);
		return 0;
	}
	machine_check_print_event_info(&evt, user_mode(regs), false);

	if (opal_recover_mce(regs, &evt))
		return 1;

	pnv_platform_error_reboot(regs, "Unrecoverable Machine Check exception");
}

/* Early hmi handler called in real mode. */
int opal_hmi_exception_early(struct pt_regs *regs)
{
	s64 rc;

	/*
	 * call opal hmi handler. Pass paca address as token.
	 * The return value OPAL_SUCCESS is an indication that there is
	 * an HMI event generated waiting to pull by Linux.
	 */
	rc = opal_handle_hmi();
	if (rc == OPAL_SUCCESS) {
		local_paca->hmi_event_available = 1;
		return 1;
	}
	return 0;
}

int opal_hmi_exception_early2(struct pt_regs *regs)
{
	s64 rc;
	__be64 out_flags;

	/*
	 * call opal hmi handler.
	 * Check 64-bit flag mask to find out if an event was generated,
	 * and whether TB is still valid or not etc.
	 */
	rc = opal_handle_hmi2(&out_flags);
	if (rc != OPAL_SUCCESS)
		return 0;

	if (be64_to_cpu(out_flags) & OPAL_HMI_FLAGS_NEW_EVENT)
		local_paca->hmi_event_available = 1;
	if (be64_to_cpu(out_flags) & OPAL_HMI_FLAGS_TOD_TB_FAIL)
		tb_invalid = true;
	return 1;
}

/* HMI exception handler called in virtual mode when irqs are next enabled. */
int opal_handle_hmi_exception(struct pt_regs *regs)
{
	/*
	 * Check if HMI event is available.
	 * if Yes, then wake kopald to process them.
	 */
	if (!local_paca->hmi_event_available)
		return 0;

	local_paca->hmi_event_available = 0;
	opal_wake_poller();

	return 1;
}

static uint64_t find_recovery_address(uint64_t nip)
{
	int i;

	for (i = 0; i < mc_recoverable_range_len; i++)
		if ((nip >= mc_recoverable_range[i].start_addr) &&
		    (nip < mc_recoverable_range[i].end_addr))
		    return mc_recoverable_range[i].recover_addr;
	return 0;
}

bool opal_mce_check_early_recovery(struct pt_regs *regs)
{
	uint64_t recover_addr = 0;

	if (!opal.base || !opal.size)
		goto out;

	if ((regs->nip >= opal.base) &&
			(regs->nip < (opal.base + opal.size)))
		recover_addr = find_recovery_address(regs->nip);

	/*
	 * Setup regs->nip to rfi into fixup address.
	 */
	if (recover_addr)
		regs_set_return_ip(regs, recover_addr);

out:
	return !!recover_addr;
}

static int __init opal_sysfs_init(void)
{
	opal_kobj = kobject_create_and_add("opal", firmware_kobj);
	if (!opal_kobj) {
		pr_warn("kobject_create_and_add opal failed\n");
		return -ENOMEM;
	}

	return 0;
}

static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
				struct bin_attribute *bin_attr, char *buf,
				loff_t off, size_t count)
{
	return memory_read_from_buffer(buf, count, &off, bin_attr->private,
				       bin_attr->size);
}

static int opal_add_one_export(struct kobject *parent, const char *export_name,
			       struct device_node *np, const char *prop_name)
{
	struct bin_attribute *attr = NULL;
	const char *name = NULL;
	u64 vals[2];
	int rc;

	rc = of_property_read_u64_array(np, prop_name, &vals[0], 2);
	if (rc)
		goto out;

	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
	if (!attr) {
		rc = -ENOMEM;
		goto out;
	}
	name = kstrdup(export_name, GFP_KERNEL);
	if (!name) {
		rc = -ENOMEM;
		goto out;
	}

	sysfs_bin_attr_init(attr);
	attr->attr.name = name;
	attr->attr.mode = 0400;
	attr->read = export_attr_read;
	attr->private = __va(vals[0]);
	attr->size = vals[1];

	rc = sysfs_create_bin_file(parent, attr);
out:
	if (rc) {
		kfree(name);
		kfree(attr);
	}

	return rc;
}

static void opal_add_exported_attrs(struct device_node *np,
				    struct kobject *kobj)
{
	struct device_node *child;
	struct property *prop;

	for_each_property_of_node(np, prop) {
		int rc;

		if (!strcmp(prop->name, "name") ||
		    !strcmp(prop->name, "phandle"))
			continue;

		rc = opal_add_one_export(kobj, prop->name, np, prop->name);
		if (rc) {
			pr_warn("Unable to add export %pOF/%s, rc = %d!\n",
				np, prop->name, rc);
		}
	}

	for_each_child_of_node(np, child) {
		struct kobject *child_kobj;

		child_kobj = kobject_create_and_add(child->name, kobj);
		if (!child_kobj) {
			pr_err("Unable to create export dir for %pOF\n", child);
			continue;
		}

		opal_add_exported_attrs(child, child_kobj);
	}
}

/*
 * opal_export_attrs: creates a sysfs node for each property listed in
 * the device-tree under /ibm,opal/firmware/exports/
 * All new sysfs nodes are created under /opal/exports/.
 * This allows for reserved memory regions (e.g. HDAT) to be read.
 * The new sysfs nodes are only readable by root.
 */
static void opal_export_attrs(void)
{
	struct device_node *np;
	struct kobject *kobj;
	int rc;

	np = of_find_node_by_path("/ibm,opal/firmware/exports");
	if (!np)
		return;

	/* Create new 'exports' directory - /sys/firmware/opal/exports */
	kobj = kobject_create_and_add("exports", opal_kobj);
	if (!kobj) {
		pr_warn("kobject_create_and_add() of exports failed\n");
		of_node_put(np);
		return;
	}

	opal_add_exported_attrs(np, kobj);

	/*
	 * NB: symbol_map existed before the generic export interface so it
	 * lives under the top level opal_kobj.
	 */
	rc = opal_add_one_export(opal_kobj, "symbol_map",
				 np->parent, "symbol-map");
	if (rc)
		pr_warn("Error %d creating OPAL symbols file\n", rc);

	of_node_put(np);
}

static void __init opal_dump_region_init(void)
{
	void *addr;
	uint64_t size;
	int rc;

	if (!opal_check_token(OPAL_REGISTER_DUMP_REGION))
		return;

	/* Register kernel log buffer */
	addr = log_buf_addr_get();
	if (addr == NULL)
		return;

	size = log_buf_len_get();
	if (size == 0)
		return;

	rc = opal_register_dump_region(OPAL_DUMP_REGION_LOG_BUF,
				       __pa(addr), size);
	/* Don't warn if this is just an older OPAL that doesn't
	 * know about that call
	 */
	if (rc && rc != OPAL_UNSUPPORTED)
		pr_warn("DUMP: Failed to register kernel log buffer. "
			"rc = %d\n", rc);
}

static void __init opal_pdev_init(const char *compatible)
{
	struct device_node *np;

	for_each_compatible_node(np, NULL, compatible)
		of_platform_device_create(np, NULL, NULL);
}

static void __init opal_imc_init_dev(void)
{
	struct device_node *np;

	np = of_find_compatible_node(NULL, NULL, IMC_DTB_COMPAT);
	if (np)
		of_platform_device_create(np, NULL, NULL);

	of_node_put(np);
}

static int kopald(void *unused)
{
	unsigned long timeout = msecs_to_jiffies(opal_heartbeat) + 1;

	set_freezable();
	do {
		try_to_freeze();

		opal_handle_events();

		set_current_state(TASK_INTERRUPTIBLE);
		if (opal_have_pending_events())
			__set_current_state(TASK_RUNNING);
		else
			schedule_timeout(timeout);

	} while (!kthread_should_stop());

	return 0;
}

void opal_wake_poller(void)
{
	if (kopald_tsk)
		wake_up_process(kopald_tsk);
}

static void __init opal_init_heartbeat(void)
{
	/* Old firwmware, we assume the HVC heartbeat is sufficient */
	if (of_property_read_u32(opal_node, "ibm,heartbeat-ms",
				 &opal_heartbeat) != 0)
		opal_heartbeat = 0;

	if (opal_heartbeat)
		kopald_tsk = kthread_run(kopald, NULL, "kopald");
}

static int __init opal_init(void)
{
	struct device_node *np, *consoles, *leds;
	int rc;

	opal_node = of_find_node_by_path("/ibm,opal");
	if (!opal_node) {
		pr_warn("Device node not found\n");
		return -ENODEV;
	}

	/* Register OPAL consoles if any ports */
	consoles = of_find_node_by_path("/ibm,opal/consoles");
	if (consoles) {
		for_each_child_of_node(consoles, np) {
			if (!of_node_name_eq(np, "serial"))
				continue;
			of_platform_device_create(np, NULL, NULL);
		}
		of_node_put(consoles);
	}

	/* Initialise OPAL messaging system */
	opal_message_init(opal_node);

	/* Initialise OPAL asynchronous completion interface */
	opal_async_comp_init();

	/* Initialise OPAL sensor interface */
	opal_sensor_init();

	/* Initialise OPAL hypervisor maintainence interrupt handling */
	opal_hmi_handler_init();

	/* Create i2c platform devices */
	opal_pdev_init("ibm,opal-i2c");

	/* Handle non-volatile memory devices */
	opal_pdev_init("pmem-region");

	/* Setup a heatbeat thread if requested by OPAL */
	opal_init_heartbeat();

	/* Detect In-Memory Collection counters and create devices*/
	opal_imc_init_dev();

	/* Create leds platform devices */
	leds = of_find_node_by_path("/ibm,opal/leds");
	if (leds) {
		of_platform_device_create(leds, "opal_leds", NULL);
		of_node_put(leds);
	}

	/* Initialise OPAL message log interface */
	opal_msglog_init();

	/* Create "opal" kobject under /sys/firmware */
	rc = opal_sysfs_init();
	if (rc == 0) {
		/* Setup dump region interface */
		opal_dump_region_init();
		/* Setup error log interface */
		rc = opal_elog_init();
		/* Setup code update interface */
		opal_flash_update_init();
		/* Setup platform dump extract interface */
		opal_platform_dump_init();
		/* Setup system parameters interface */
		opal_sys_param_init();
		/* Setup message log sysfs interface. */
		opal_msglog_sysfs_init();
		/* Add all export properties*/
		opal_export_attrs();
	}

	/* Initialize platform devices: IPMI backend, PRD & flash interface */
	opal_pdev_init("ibm,opal-ipmi");
	opal_pdev_init("ibm,opal-flash");
	opal_pdev_init("ibm,opal-prd");

	/* Initialise platform device: oppanel interface */
	opal_pdev_init("ibm,opal-oppanel");

	/* Initialise OPAL kmsg dumper for flushing console on panic */
	opal_kmsg_init();

	/* Initialise OPAL powercap interface */
	opal_powercap_init();

	/* Initialise OPAL Power-Shifting-Ratio interface */
	opal_psr_init();

	/* Initialise OPAL sensor groups */
	opal_sensor_groups_init();

	/* Initialise OPAL Power control interface */
	opal_power_control_init();

	/* Initialize OPAL secure variables */
	opal_pdev_init("ibm,secvar-backend");

	return 0;
}
machine_subsys_initcall(powernv, opal_init);

void opal_shutdown(void)
{
	long rc = OPAL_BUSY;

	opal_event_shutdown();

	/*
	 * Then sync with OPAL which ensure anything that can
	 * potentially write to our memory has completed such
	 * as an ongoing dump retrieval
	 */
	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
		rc = opal_sync_host_reboot();
		if (rc == OPAL_BUSY)
			opal_poll_events(NULL);
		else
			mdelay(10);
	}

	/* Unregister memory dump region */
	if (opal_check_token(OPAL_UNREGISTER_DUMP_REGION))
		opal_unregister_dump_region(OPAL_DUMP_REGION_LOG_BUF);
}

/* Export this so that test modules can use it */
EXPORT_SYMBOL_GPL(opal_invalid_call);
EXPORT_SYMBOL_GPL(opal_xscom_read);
EXPORT_SYMBOL_GPL(opal_xscom_write);
EXPORT_SYMBOL_GPL(opal_ipmi_send);
EXPORT_SYMBOL_GPL(opal_ipmi_recv);
EXPORT_SYMBOL_GPL(opal_flash_read);
EXPORT_SYMBOL_GPL(opal_flash_write);
EXPORT_SYMBOL_GPL(opal_flash_erase);
EXPORT_SYMBOL_GPL(opal_prd_msg);
EXPORT_SYMBOL_GPL(opal_check_token);

/* Convert a region of vmalloc memory to an opal sg list */
struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
					     unsigned long vmalloc_size)
{
	struct opal_sg_list *sg, *first = NULL;
	unsigned long i = 0;

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

	first = sg;

	while (vmalloc_size > 0) {
		uint64_t data = vmalloc_to_pfn(vmalloc_addr) << PAGE_SHIFT;
		uint64_t length = min(vmalloc_size, PAGE_SIZE);

		sg->entry[i].data = cpu_to_be64(data);
		sg->entry[i].length = cpu_to_be64(length);
		i++;

		if (i >= SG_ENTRIES_PER_NODE) {
			struct opal_sg_list *next;

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

			sg->length = cpu_to_be64(
					i * sizeof(struct opal_sg_entry) + 16);
			i = 0;
			sg->next = cpu_to_be64(__pa(next));
			sg = next;
		}

		vmalloc_addr += length;
		vmalloc_size -= length;
	}

	sg->length = cpu_to_be64(i * sizeof(struct opal_sg_entry) + 16);

	return first;

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

void opal_free_sg_list(struct opal_sg_list *sg)
{
	while (sg) {
		uint64_t next = be64_to_cpu(sg->next);

		kfree(sg);

		if (next)
			sg = __va(next);
		else
			sg = NULL;
	}
}

int opal_error_code(int rc)
{
	switch (rc) {
	case OPAL_SUCCESS:		return 0;

	case OPAL_PARAMETER:		return -EINVAL;
	case OPAL_ASYNC_COMPLETION:	return -EINPROGRESS;
	case OPAL_BUSY:
	case OPAL_BUSY_EVENT:		return -EBUSY;
	case OPAL_NO_MEM:		return -ENOMEM;
	case OPAL_PERMISSION:		return -EPERM;

	case OPAL_UNSUPPORTED:		return -EIO;
	case OPAL_HARDWARE:		return -EIO;
	case OPAL_INTERNAL_ERROR:	return -EIO;
	case OPAL_TIMEOUT:		return -ETIMEDOUT;
	default:
		pr_err("%s: unexpected OPAL error %d\n", __func__, rc);
		return -EIO;
	}
}

void powernv_set_nmmu_ptcr(unsigned long ptcr)
{
	int rc;

	if (firmware_has_feature(FW_FEATURE_OPAL)) {
		rc = opal_nmmu_set_ptcr(-1UL, ptcr);
		if (rc != OPAL_SUCCESS && rc != OPAL_UNSUPPORTED)
			pr_warn("%s: Unable to set nest mmu ptcr\n", __func__);
	}
}

EXPORT_SYMBOL_GPL(opal_poll_events);
EXPORT_SYMBOL_GPL(opal_rtc_read);
EXPORT_SYMBOL_GPL(opal_rtc_write);
EXPORT_SYMBOL_GPL(opal_tpo_read);
EXPORT_SYMBOL_GPL(opal_tpo_write);
EXPORT_SYMBOL_GPL(opal_i2c_request);
/* Export these symbols for PowerNV LED class driver */
EXPORT_SYMBOL_GPL(opal_leds_get_ind);
EXPORT_SYMBOL_GPL(opal_leds_set_ind);
/* Export this symbol for PowerNV Operator Panel class driver */
EXPORT_SYMBOL_GPL(opal_write_oppanel_async);
/* Export this for KVM */
EXPORT_SYMBOL_GPL(opal_int_set_mfrr);
EXPORT_SYMBOL_GPL(opal_int_eoi);
EXPORT_SYMBOL_GPL(opal_error_code);
/* Export the below symbol for NX compression */
EXPORT_SYMBOL(opal_nx_coproc_init);
