/*
 * Atmel AT91 SAM9 SoCs reset code
 *
 * Copyright (C) 2007 Atmel Corporation.
 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
 * Copyright (C) 2014 Free Electrons
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/printk.h>

#define AT91_SHDW_CR	0x00		/* Shut Down Control Register */
#define AT91_SHDW_SHDW		BIT(0)			/* Shut Down command */
#define AT91_SHDW_KEY		(0xa5 << 24)		/* KEY Password */

#define AT91_SHDW_MR	0x04		/* Shut Down Mode Register */
#define AT91_SHDW_WKMODE0	GENMASK(2, 0)		/* Wake-up 0 Mode Selection */
#define AT91_SHDW_CPTWK0_MAX	0xf			/* Maximum Counter On Wake Up 0 */
#define AT91_SHDW_CPTWK0	(AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
#define AT91_SHDW_CPTWK0_(x)	((x) << 4)
#define AT91_SHDW_RTTWKEN	BIT(16)			/* Real Time Timer Wake-up Enable */
#define AT91_SHDW_RTCWKEN	BIT(17)			/* Real Time Clock Wake-up Enable */

#define AT91_SHDW_SR	0x08		/* Shut Down Status Register */
#define AT91_SHDW_WAKEUP0	BIT(0)			/* Wake-up 0 Status */
#define AT91_SHDW_RTTWK		BIT(16)			/* Real-time Timer Wake-up */
#define AT91_SHDW_RTCWK		BIT(17)			/* Real-time Clock Wake-up [SAM9RL] */

enum wakeup_type {
	AT91_SHDW_WKMODE0_NONE		= 0,
	AT91_SHDW_WKMODE0_HIGH		= 1,
	AT91_SHDW_WKMODE0_LOW		= 2,
	AT91_SHDW_WKMODE0_ANYLEVEL	= 3,
};

static const char *shdwc_wakeup_modes[] = {
	[AT91_SHDW_WKMODE0_NONE]	= "none",
	[AT91_SHDW_WKMODE0_HIGH]	= "high",
	[AT91_SHDW_WKMODE0_LOW]		= "low",
	[AT91_SHDW_WKMODE0_ANYLEVEL]	= "any",
};

static void __iomem *at91_shdwc_base;

static void __init at91_wakeup_status(void)
{
	u32 reg = readl(at91_shdwc_base + AT91_SHDW_SR);
	char *reason = "unknown";

	/* Simple power-on, just bail out */
	if (!reg)
		return;

	if (reg & AT91_SHDW_RTTWK)
		reason = "RTT";
	else if (reg & AT91_SHDW_RTCWK)
		reason = "RTC";

	pr_info("AT91: Wake-Up source: %s\n", reason);
}

static void at91_poweroff(void)
{
	writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
}

const enum wakeup_type at91_poweroff_get_wakeup_mode(struct device_node *np)
{
	const char *pm;
	int err, i;

	err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
	if (err < 0)
		return AT91_SHDW_WKMODE0_ANYLEVEL;

	for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
		if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
			return i;

	return -ENODEV;
}

static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	enum wakeup_type wakeup_mode;
	u32 mode = 0, tmp;

	wakeup_mode = at91_poweroff_get_wakeup_mode(np);
	if (wakeup_mode < 0) {
		dev_warn(&pdev->dev, "shdwc unknown wakeup mode\n");
		return;
	}

	if (!of_property_read_u32(np, "atmel,wakeup-counter", &tmp)) {
		if (tmp > AT91_SHDW_CPTWK0_MAX) {
			dev_warn(&pdev->dev,
				 "shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n",
				 tmp, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
			tmp = AT91_SHDW_CPTWK0_MAX;
		}
		mode |= AT91_SHDW_CPTWK0_(tmp);
	}

	if (of_property_read_bool(np, "atmel,wakeup-rtc-timer"))
			mode |= AT91_SHDW_RTCWKEN;

	if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
			mode |= AT91_SHDW_RTTWKEN;

	writel(wakeup_mode | mode, at91_shdwc_base + AT91_SHDW_MR);
}

static int at91_poweroff_probe(struct platform_device *pdev)
{
	struct resource *res;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(at91_shdwc_base)) {
		dev_err(&pdev->dev, "Could not map reset controller address\n");
		return PTR_ERR(at91_shdwc_base);
	}

	at91_wakeup_status();

	if (pdev->dev.of_node)
		at91_poweroff_dt_set_wakeup_mode(pdev);

	pm_power_off = at91_poweroff;

	return 0;
}

static struct of_device_id at91_poweroff_of_match[] = {
	{ .compatible = "atmel,at91sam9260-shdwc", },
	{ .compatible = "atmel,at91sam9rl-shdwc", },
	{ .compatible = "atmel,at91sam9x5-shdwc", },
	{ /*sentinel*/ }
};

static struct platform_driver at91_poweroff_driver = {
	.probe = at91_poweroff_probe,
	.driver = {
		.name = "at91-poweroff",
		.of_match_table = at91_poweroff_of_match,
	},
};
module_platform_driver(at91_poweroff_driver);
