/*
 * PowerNV OPAL asynchronous completion interfaces
 *
 * Copyright 2013 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.
 */

#undef DEBUG

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/gfp.h>
#include <linux/of.h>
#include <asm/machdep.h>
#include <asm/opal.h>

#define N_ASYNC_COMPLETIONS	64

static DECLARE_BITMAP(opal_async_complete_map, N_ASYNC_COMPLETIONS) = {~0UL};
static DECLARE_BITMAP(opal_async_token_map, N_ASYNC_COMPLETIONS);
static DECLARE_WAIT_QUEUE_HEAD(opal_async_wait);
static DEFINE_SPINLOCK(opal_async_comp_lock);
static struct semaphore opal_async_sem;
static struct opal_msg *opal_async_responses;
static unsigned int opal_max_async_tokens;

int __opal_async_get_token(void)
{
	unsigned long flags;
	int token;

	spin_lock_irqsave(&opal_async_comp_lock, flags);
	token = find_first_bit(opal_async_complete_map, opal_max_async_tokens);
	if (token >= opal_max_async_tokens) {
		token = -EBUSY;
		goto out;
	}

	if (__test_and_set_bit(token, opal_async_token_map)) {
		token = -EBUSY;
		goto out;
	}

	__clear_bit(token, opal_async_complete_map);

out:
	spin_unlock_irqrestore(&opal_async_comp_lock, flags);
	return token;
}

int opal_async_get_token_interruptible(void)
{
	int token;

	/* Wait until a token is available */
	if (down_interruptible(&opal_async_sem))
		return -ERESTARTSYS;

	token = __opal_async_get_token();
	if (token < 0)
		up(&opal_async_sem);

	return token;
}
EXPORT_SYMBOL_GPL(opal_async_get_token_interruptible);

int __opal_async_release_token(int token)
{
	unsigned long flags;

	if (token < 0 || token >= opal_max_async_tokens) {
		pr_err("%s: Passed token is out of range, token %d\n",
				__func__, token);
		return -EINVAL;
	}

	spin_lock_irqsave(&opal_async_comp_lock, flags);
	__set_bit(token, opal_async_complete_map);
	__clear_bit(token, opal_async_token_map);
	spin_unlock_irqrestore(&opal_async_comp_lock, flags);

	return 0;
}

int opal_async_release_token(int token)
{
	int ret;

	ret = __opal_async_release_token(token);
	if (ret)
		return ret;

	up(&opal_async_sem);

	return 0;
}
EXPORT_SYMBOL_GPL(opal_async_release_token);

int opal_async_wait_response(uint64_t token, struct opal_msg *msg)
{
	if (token >= opal_max_async_tokens) {
		pr_err("%s: Invalid token passed\n", __func__);
		return -EINVAL;
	}

	if (!msg) {
		pr_err("%s: Invalid message pointer passed\n", __func__);
		return -EINVAL;
	}

	/* Wakeup the poller before we wait for events to speed things
	 * up on platforms or simulators where the interrupts aren't
	 * functional.
	 */
	opal_wake_poller();
	wait_event(opal_async_wait, test_bit(token, opal_async_complete_map));
	memcpy(msg, &opal_async_responses[token], sizeof(*msg));

	return 0;
}
EXPORT_SYMBOL_GPL(opal_async_wait_response);

static int opal_async_comp_event(struct notifier_block *nb,
		unsigned long msg_type, void *msg)
{
	struct opal_msg *comp_msg = msg;
	unsigned long flags;
	uint64_t token;

	if (msg_type != OPAL_MSG_ASYNC_COMP)
		return 0;

	token = be64_to_cpu(comp_msg->params[0]);
	memcpy(&opal_async_responses[token], comp_msg, sizeof(*comp_msg));
	spin_lock_irqsave(&opal_async_comp_lock, flags);
	__set_bit(token, opal_async_complete_map);
	spin_unlock_irqrestore(&opal_async_comp_lock, flags);

	wake_up(&opal_async_wait);

	return 0;
}

static struct notifier_block opal_async_comp_nb = {
		.notifier_call	= opal_async_comp_event,
		.next		= NULL,
		.priority	= 0,
};

int __init opal_async_comp_init(void)
{
	struct device_node *opal_node;
	const __be32 *async;
	int err;

	opal_node = of_find_node_by_path("/ibm,opal");
	if (!opal_node) {
		pr_err("%s: Opal node not found\n", __func__);
		err = -ENOENT;
		goto out;
	}

	async = of_get_property(opal_node, "opal-msg-async-num", NULL);
	if (!async) {
		pr_err("%s: %pOF has no opal-msg-async-num\n",
				__func__, opal_node);
		err = -ENOENT;
		goto out_opal_node;
	}

	opal_max_async_tokens = be32_to_cpup(async);
	if (opal_max_async_tokens > N_ASYNC_COMPLETIONS)
		opal_max_async_tokens = N_ASYNC_COMPLETIONS;

	err = opal_message_notifier_register(OPAL_MSG_ASYNC_COMP,
			&opal_async_comp_nb);
	if (err) {
		pr_err("%s: Can't register OPAL event notifier (%d)\n",
				__func__, err);
		goto out_opal_node;
	}

	opal_async_responses = kzalloc(
			sizeof(*opal_async_responses) * opal_max_async_tokens,
			GFP_KERNEL);
	if (!opal_async_responses) {
		pr_err("%s: Out of memory, failed to do asynchronous "
				"completion init\n", __func__);
		err = -ENOMEM;
		goto out_opal_node;
	}

	/* Initialize to 1 less than the maximum tokens available, as we may
	 * require to pop one during emergency through synchronous call to
	 * __opal_async_get_token()
	 */
	sema_init(&opal_async_sem, opal_max_async_tokens - 1);

out_opal_node:
	of_node_put(opal_node);
out:
	return err;
}
