/*
 * 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 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>");
