/*
 * OPAL asynchronus Memory error handling support in PowreNV.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Copyright 2013 IBM Corporation
 * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
 */

#undef DEBUG

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/mm.h>
#include <linux/slab.h>

#include <asm/machdep.h>
#include <asm/opal.h>
#include <asm/cputable.h>

static int opal_mem_err_nb_init;
static LIST_HEAD(opal_memory_err_list);
static DEFINE_SPINLOCK(opal_mem_err_lock);

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

static void handle_memory_error_event(struct OpalMemoryErrorData *merr_evt)
{
	uint64_t paddr_start, paddr_end;

	pr_debug("%s: Retrieved memory error event, type: 0x%x\n",
		  __func__, merr_evt->type);
	switch (merr_evt->type) {
	case OPAL_MEM_ERR_TYPE_RESILIENCE:
		paddr_start = be64_to_cpu(merr_evt->u.resilience.physical_address_start);
		paddr_end = be64_to_cpu(merr_evt->u.resilience.physical_address_end);
		break;
	case OPAL_MEM_ERR_TYPE_DYN_DALLOC:
		paddr_start = be64_to_cpu(merr_evt->u.dyn_dealloc.physical_address_start);
		paddr_end = be64_to_cpu(merr_evt->u.dyn_dealloc.physical_address_end);
		break;
	default:
		return;
	}

	for (; paddr_start < paddr_end; paddr_start += PAGE_SIZE) {
		memory_failure(paddr_start >> PAGE_SHIFT, 0, 0);
	}
}

static void handle_memory_error(void)
{
	unsigned long flags;
	struct OpalMemoryErrorData *merr_evt;
	struct OpalMsgNode *msg_node;

	spin_lock_irqsave(&opal_mem_err_lock, flags);
	while (!list_empty(&opal_memory_err_list)) {
		 msg_node = list_entry(opal_memory_err_list.next,
					   struct OpalMsgNode, list);
		list_del(&msg_node->list);
		spin_unlock_irqrestore(&opal_mem_err_lock, flags);

		merr_evt = (struct OpalMemoryErrorData *)
					&msg_node->msg.params[0];
		handle_memory_error_event(merr_evt);
		kfree(msg_node);
		spin_lock_irqsave(&opal_mem_err_lock, flags);
	}
	spin_unlock_irqrestore(&opal_mem_err_lock, flags);
}

static void mem_error_handler(struct work_struct *work)
{
	handle_memory_error();
}

static DECLARE_WORK(mem_error_work, mem_error_handler);

/*
 * opal_memory_err_event - notifier handler that queues up the opal message
 * to be preocessed later.
 */
static int opal_memory_err_event(struct notifier_block *nb,
			  unsigned long msg_type, void *msg)
{
	unsigned long flags;
	struct OpalMsgNode *msg_node;

	if (msg_type != OPAL_MSG_MEM_ERR)
		return 0;

	msg_node = kzalloc(sizeof(*msg_node), GFP_ATOMIC);
	if (!msg_node) {
		pr_err("MEMORY_ERROR: out of memory, Opal message event not"
		       "handled\n");
		return -ENOMEM;
	}
	memcpy(&msg_node->msg, msg, sizeof(struct opal_msg));

	spin_lock_irqsave(&opal_mem_err_lock, flags);
	list_add(&msg_node->list, &opal_memory_err_list);
	spin_unlock_irqrestore(&opal_mem_err_lock, flags);

	schedule_work(&mem_error_work);
	return 0;
}

static struct notifier_block opal_mem_err_nb = {
	.notifier_call	= opal_memory_err_event,
	.next		= NULL,
	.priority	= 0,
};

static int __init opal_mem_err_init(void)
{
	int ret;

	if (!opal_mem_err_nb_init) {
		ret = opal_message_notifier_register(
					OPAL_MSG_MEM_ERR, &opal_mem_err_nb);
		if (ret) {
			pr_err("%s: Can't register OPAL event notifier (%d)\n",
			       __func__, ret);
			return ret;
		}
		opal_mem_err_nb_init = 1;
	}
	return 0;
}
machine_device_initcall(powernv, opal_mem_err_init);
