/*
 * 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.
 *
 * 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.
 *
 * Copyright (C) 2012 ARM Limited
 */

#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/stat.h>
#include <linux/vexpress.h>

#include <asm/system_misc.h>

static void vexpress_reset_do(struct device *dev, const char *what)
{
	int err = -ENOENT;
	struct vexpress_config_func *func =
			vexpress_config_func_get_by_dev(dev);

	if (func) {
		unsigned long timeout;

		err = vexpress_config_write(func, 0, 0);

		timeout = jiffies + HZ;
		while (time_before(jiffies, timeout))
			cpu_relax();
	}

	dev_emerg(dev, "Unable to %s (%d)\n", what, err);
}

static struct device *vexpress_power_off_device;

static void vexpress_power_off(void)
{
	vexpress_reset_do(vexpress_power_off_device, "power off");
}

static struct device *vexpress_restart_device;

static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd)
{
	vexpress_reset_do(vexpress_restart_device, "restart");
}

static ssize_t vexpress_reset_active_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", vexpress_restart_device == dev);
}

static ssize_t vexpress_reset_active_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	long value;
	int err = kstrtol(buf, 0, &value);

	if (!err && value)
		vexpress_restart_device = dev;

	return err ? err : count;
}

DEVICE_ATTR(active, S_IRUGO | S_IWUSR, vexpress_reset_active_show,
		vexpress_reset_active_store);


enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT };

static struct of_device_id vexpress_reset_of_match[] = {
	{
		.compatible = "arm,vexpress-reset",
		.data = (void *)FUNC_RESET,
	}, {
		.compatible = "arm,vexpress-shutdown",
		.data = (void *)FUNC_SHUTDOWN
	}, {
		.compatible = "arm,vexpress-reboot",
		.data = (void *)FUNC_REBOOT
	},
	{}
};

static int vexpress_reset_probe(struct platform_device *pdev)
{
	enum vexpress_reset_func func;
	const struct of_device_id *match =
			of_match_device(vexpress_reset_of_match, &pdev->dev);

	if (match)
		func = (enum vexpress_reset_func)match->data;
	else
		func = pdev->id_entry->driver_data;

	switch (func) {
	case FUNC_SHUTDOWN:
		vexpress_power_off_device = &pdev->dev;
		pm_power_off = vexpress_power_off;
		break;
	case FUNC_RESET:
		if (!vexpress_restart_device)
			vexpress_restart_device = &pdev->dev;
		arm_pm_restart = vexpress_restart;
		device_create_file(&pdev->dev, &dev_attr_active);
		break;
	case FUNC_REBOOT:
		vexpress_restart_device = &pdev->dev;
		arm_pm_restart = vexpress_restart;
		device_create_file(&pdev->dev, &dev_attr_active);
		break;
	};

	return 0;
}

static const struct platform_device_id vexpress_reset_id_table[] = {
	{ .name = "vexpress-reset", .driver_data = FUNC_RESET, },
	{ .name = "vexpress-shutdown", .driver_data = FUNC_SHUTDOWN, },
	{ .name = "vexpress-reboot", .driver_data = FUNC_REBOOT, },
	{}
};

static struct platform_driver vexpress_reset_driver = {
	.probe = vexpress_reset_probe,
	.driver = {
		.name = "vexpress-reset",
		.of_match_table = vexpress_reset_of_match,
	},
	.id_table = vexpress_reset_id_table,
};

static int __init vexpress_reset_init(void)
{
	return platform_driver_register(&vexpress_reset_driver);
}
device_initcall(vexpress_reset_init);
