/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2012 Cavium, Inc.
 *
 * Copyright (C) 2009 Wind River Systems,
 *   written by Ralf Baechle <ralf@linux-mips.org>
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/edac.h>

#include "edac_core.h"
#include "edac_module.h"

#include <asm/octeon/cvmx.h>
#include <asm/mipsregs.h>

extern int register_co_cache_error_notifier(struct notifier_block *nb);
extern int unregister_co_cache_error_notifier(struct notifier_block *nb);

extern unsigned long long cache_err_dcache[NR_CPUS];

struct co_cache_error {
	struct notifier_block notifier;
	struct edac_device_ctl_info *ed;
};

/**
 * EDAC CPU cache error callback
 *
 * @event: non-zero if unrecoverable.
 */
static int  co_cache_error_event(struct notifier_block *this,
	unsigned long event, void *ptr)
{
	struct co_cache_error *p = container_of(this, struct co_cache_error,
						notifier);

	unsigned int core = cvmx_get_core_num();
	unsigned int cpu = smp_processor_id();
	u64 icache_err = read_octeon_c0_icacheerr();
	u64 dcache_err;

	if (event) {
		dcache_err = cache_err_dcache[core];
		cache_err_dcache[core] = 0;
	} else {
		dcache_err = read_octeon_c0_dcacheerr();
	}

	if (icache_err & 1) {
		edac_device_printk(p->ed, KERN_ERR,
				   "CacheErr (Icache):%llx, core %d/cpu %d, cp0_errorepc == %lx\n",
				   (unsigned long long)icache_err, core, cpu,
				   read_c0_errorepc());
		write_octeon_c0_icacheerr(0);
		edac_device_handle_ce(p->ed, cpu, 1, "icache");
	}
	if (dcache_err & 1) {
		edac_device_printk(p->ed, KERN_ERR,
				   "CacheErr (Dcache):%llx, core %d/cpu %d, cp0_errorepc == %lx\n",
				   (unsigned long long)dcache_err, core, cpu,
				   read_c0_errorepc());
		if (event)
			edac_device_handle_ue(p->ed, cpu, 0, "dcache");
		else
			edac_device_handle_ce(p->ed, cpu, 0, "dcache");

		/* Clear the error indication */
		if (OCTEON_IS_MODEL(OCTEON_FAM_2))
			write_octeon_c0_dcacheerr(1);
		else
			write_octeon_c0_dcacheerr(0);
	}

	return NOTIFY_STOP;
}

static int __devinit co_cache_error_probe(struct platform_device *pdev)
{
	struct co_cache_error *p = devm_kzalloc(&pdev->dev, sizeof(*p),
						GFP_KERNEL);
	if (!p)
		return -ENOMEM;

	p->notifier.notifier_call = co_cache_error_event;
	platform_set_drvdata(pdev, p);

	p->ed = edac_device_alloc_ctl_info(0, "cpu", num_possible_cpus(),
					   "cache", 2, 0, NULL, 0,
					   edac_device_alloc_index());
	if (!p->ed)
		goto err;

	p->ed->dev = &pdev->dev;

	p->ed->dev_name = dev_name(&pdev->dev);

	p->ed->mod_name = "octeon-cpu";
	p->ed->ctl_name = "cache";

	if (edac_device_add_device(p->ed)) {
		pr_err("%s: edac_device_add_device() failed\n", __func__);
		goto err1;
	}

	register_co_cache_error_notifier(&p->notifier);

	return 0;

err1:
	edac_device_free_ctl_info(p->ed);
err:
	return -ENXIO;
}

static int co_cache_error_remove(struct platform_device *pdev)
{
	struct co_cache_error *p = platform_get_drvdata(pdev);

	unregister_co_cache_error_notifier(&p->notifier);
	edac_device_del_device(&pdev->dev);
	edac_device_free_ctl_info(p->ed);
	return 0;
}

static struct platform_driver co_cache_error_driver = {
	.probe = co_cache_error_probe,
	.remove = co_cache_error_remove,
	.driver = {
		   .name = "octeon_pc_edac",
	}
};
module_platform_driver(co_cache_error_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
