/*
 * Copyright (C) 2014 Linaro Ltd.
 *
 * Author: Linus Walleij <linus.walleij@linaro.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2, as
 * published by the Free Software Foundation.
 *
 */
#include <linux/init.h>
#include <linux/mfd/syscon.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/of.h>

#define INTEGRATOR_HDR_CTRL_OFFSET	0x0C
#define INTEGRATOR_HDR_LOCK_OFFSET	0x14
#define INTEGRATOR_CM_CTRL_RESET	(1 << 3)

#define VERSATILE_SYS_LOCK_OFFSET	0x20
#define VERSATILE_SYS_RESETCTL_OFFSET	0x40

/* Magic unlocking token used on all Versatile boards */
#define VERSATILE_LOCK_VAL		0xA05F

/*
 * We detect the different syscon types from the compatible strings.
 */
enum versatile_reboot {
	INTEGRATOR_REBOOT_CM,
	VERSATILE_REBOOT_CM,
	REALVIEW_REBOOT_EB,
	REALVIEW_REBOOT_PB1176,
	REALVIEW_REBOOT_PB11MP,
	REALVIEW_REBOOT_PBA8,
	REALVIEW_REBOOT_PBX,
};

/* Pointer to the system controller */
static struct regmap *syscon_regmap;
static enum versatile_reboot versatile_reboot_type;

static const struct of_device_id versatile_reboot_of_match[] = {
	{
		.compatible = "arm,core-module-integrator",
		.data = (void *)INTEGRATOR_REBOOT_CM
	},
	{
		.compatible = "arm,core-module-versatile",
		.data = (void *)VERSATILE_REBOOT_CM,
	},
	{
		.compatible = "arm,realview-eb-syscon",
		.data = (void *)REALVIEW_REBOOT_EB,
	},
	{
		.compatible = "arm,realview-pb1176-syscon",
		.data = (void *)REALVIEW_REBOOT_PB1176,
	},
	{
		.compatible = "arm,realview-pb11mp-syscon",
		.data = (void *)REALVIEW_REBOOT_PB11MP,
	},
	{
		.compatible = "arm,realview-pba8-syscon",
		.data = (void *)REALVIEW_REBOOT_PBA8,
	},
	{
		.compatible = "arm,realview-pbx-syscon",
		.data = (void *)REALVIEW_REBOOT_PBX,
	},
	{},
};

static int versatile_reboot(struct notifier_block *this, unsigned long mode,
			    void *cmd)
{
	/* Unlock the reset register */
	/* Then hit reset on the different machines */
	switch (versatile_reboot_type) {
	case INTEGRATOR_REBOOT_CM:
		regmap_write(syscon_regmap, INTEGRATOR_HDR_LOCK_OFFSET,
			     VERSATILE_LOCK_VAL);
		regmap_update_bits(syscon_regmap,
				   INTEGRATOR_HDR_CTRL_OFFSET,
				   INTEGRATOR_CM_CTRL_RESET,
				   INTEGRATOR_CM_CTRL_RESET);
		break;
	case VERSATILE_REBOOT_CM:
		regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
			     VERSATILE_LOCK_VAL);
		regmap_update_bits(syscon_regmap,
				   VERSATILE_SYS_RESETCTL_OFFSET,
				   0x0107,
				   0x0105);
		regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
			     0);
		break;
	case REALVIEW_REBOOT_EB:
		regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
			     VERSATILE_LOCK_VAL);
		regmap_write(syscon_regmap,
			     VERSATILE_SYS_RESETCTL_OFFSET, 0x0008);
		break;
	case REALVIEW_REBOOT_PB1176:
		regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
			     VERSATILE_LOCK_VAL);
		regmap_write(syscon_regmap,
			     VERSATILE_SYS_RESETCTL_OFFSET, 0x0100);
		break;
	case REALVIEW_REBOOT_PB11MP:
	case REALVIEW_REBOOT_PBA8:
		regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
			     VERSATILE_LOCK_VAL);
		regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
			     0x0000);
		regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
			     0x0004);
		break;
	case REALVIEW_REBOOT_PBX:
		regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
			     VERSATILE_LOCK_VAL);
		regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
			     0x00f0);
		regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
			     0x00f4);
		break;
	}
	dsb();

	return NOTIFY_DONE;
}

static struct notifier_block versatile_reboot_nb = {
	.notifier_call = versatile_reboot,
	.priority = 192,
};

static int __init versatile_reboot_probe(void)
{
	const struct of_device_id *reboot_id;
	struct device_node *np;
	int err;

	np = of_find_matching_node_and_match(NULL, versatile_reboot_of_match,
						 &reboot_id);
	if (!np)
		return -ENODEV;
	versatile_reboot_type = (enum versatile_reboot)reboot_id->data;

	syscon_regmap = syscon_node_to_regmap(np);
	if (IS_ERR(syscon_regmap))
		return PTR_ERR(syscon_regmap);

	err = register_restart_handler(&versatile_reboot_nb);
	if (err)
		return err;

	pr_info("versatile reboot driver registered\n");
	return 0;
}
device_initcall(versatile_reboot_probe);
