// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/reboot.h>
#include <asm/system_misc.h>
#include <linux/amlogic/reboot.h>
#include <asm/compiler.h>
#include <linux/kdebug.h>
#include <linux/arm-smccc.h>
#ifdef CONFIG_AMLOGIC_PM_SETGPIO
#include "../../gpio/gpiolib.h"
#endif
#include <linux/slab.h>

static u32 psci_function_id_restart;
static u32 psci_function_id_poweroff;
static char *kernel_panic;
static struct class *sticky_reg_cls;
static char *sticky_reg_dev = "sticky_reg";
static unsigned int *sticky_reg0;
static unsigned int *sticky_reg1;
#ifdef CONFIG_AMLOGIC_PM_SETGPIO
static struct gpio_desc *poweroff_desc;
static struct gpio_desc *reset_desc;
#endif

static u32 parse_reason(const char *cmd)
{
	u32 reboot_reason = MESON_NORMAL_BOOT;

	if (cmd) {
		if (strcmp(cmd, "recovery") == 0 ||
		    strcmp(cmd, "factory_reset") == 0)
			reboot_reason = MESON_FACTORY_RESET_REBOOT;
		else if (strcmp(cmd, "update") == 0)
			reboot_reason = MESON_UPDATE_REBOOT;
		else if (strcmp(cmd, "fastboot") == 0)
			reboot_reason = MESON_FASTBOOT_REBOOT;
		else if (strcmp(cmd, "bootloader") == 0)
			reboot_reason = MESON_BOOTLOADER_REBOOT;
		else if (strcmp(cmd, "rpmbp") == 0)
			reboot_reason = MESON_RPMBP_REBOOT;
		else if (strcmp(cmd, "report_crash") == 0)
			reboot_reason = MESON_CRASH_REBOOT;
		else if (strcmp(cmd, "uboot_suspend") == 0)
			reboot_reason = MESON_UBOOT_SUSPEND;
		else if (strcmp(cmd, "quiescent") == 0 ||
			 strcmp(cmd, ",quiescent") == 0)
			reboot_reason = MESON_QUIESCENT_REBOOT;
		else if (strcmp(cmd, "recovery,quiescent") == 0 ||
			 strcmp(cmd, "factory_reset,quiescent") == 0 ||
			 strcmp(cmd, "quiescent,recovery") == 0 ||
			 strcmp(cmd, "quiescent,factory_reset") == 0)
			reboot_reason = MESON_RECOVERY_QUIESCENT_REBOOT;
	} else {
		if (kernel_panic) {
			if (strcmp(kernel_panic, "kernel_panic") == 0)
				reboot_reason = MESON_KERNEL_PANIC;
		}
	}
	pr_info("reboot reason %d\n", reboot_reason);
	return reboot_reason;
}

static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
					 u64 arg2)
{
	struct arm_smccc_res res;

	arm_smccc_smc((unsigned long)function_id,
		      (unsigned long)arg0,
		      (unsigned long)arg1,
		      (unsigned long)arg2,
		      0, 0, 0, 0, &res);
	return res.a0;
}

void meson_smc_restart(u64 function_id, u64 reboot_reason)
{
	__invoke_psci_fn_smc(function_id,
			     reboot_reason, 0, 0);
}

void meson_common_restart(char mode, const char *cmd)
{
	u32 reboot_reason = parse_reason(cmd);

#ifdef CONFIG_AMLOGIC_PM_SETGPIO
	if (reboot_reason == MESON_NORMAL_BOOT) {
		/*set GPIOA_7 output high to reboot system*/
		if (!reset_desc)
			pr_warn("no gpio pin for reset\n");
		else
			gpiod_direction_output(reset_desc, 1);
	}
#endif

	if (psci_function_id_restart)
		meson_smc_restart((u64)psci_function_id_restart,
				  (u64)reboot_reason);
}

static void do_aml_restart(enum reboot_mode reboot_mode, const char *cmd)
{
	meson_common_restart(reboot_mode, cmd);
}

static void do_aml_poweroff(void)
{
#ifdef CONFIG_AMLOGIC_PM_SETGPIO
	/*set GPIOA_14 output low when system reboot*/
	if (!poweroff_desc)
		pr_warn("no gpio pin for poweroff\n");
	else
		gpiod_direction_output(poweroff_desc, 0);
#endif
	/* TODO: Add poweroff capability */
	__invoke_psci_fn_smc(0x82000042, 1, 0, 0);
	__invoke_psci_fn_smc(psci_function_id_poweroff,
			     0, 0, 0);
}

static int panic_notify(struct notifier_block *self,
			unsigned long cmd, void *ptr)
{
	kernel_panic = "kernel_panic";

	return NOTIFY_DONE;
}

static struct notifier_block panic_notifier = {
	.notifier_call	= panic_notify,
};

static ssize_t sticky_reg_show(struct device *parent,
			 struct device_attribute *attr, char *buf)
{
	int ret = 0;
	unsigned int reg0_val;
	unsigned int reg1_val;

	if ((sticky_reg0 != 0) && (sticky_reg1 != 0)) {
		reg0_val = readl(sticky_reg0);
		reg1_val = readl(sticky_reg1);
		ret = sprintf(buf, "sticky_reg0=0x%x, sticky_reg1=0x%x\n",
				reg0_val, reg1_val);

	} else {
		ret = sprintf(buf, "invalid sticky register\n");
	}

	return ret;
}

static ssize_t sticky_reg_store(struct device *parent,
		struct device_attribute *attr, const char *buf, size_t size)
{
	int val;

	if (sscanf(buf, "%d", &val) != 1)
		return size;

	if (val == 0) {
		if ((sticky_reg0 != 0) && (sticky_reg1 != 0)) {
			writel(0x0, sticky_reg0);
			writel(0x0, sticky_reg1);
		}
	}

	return size;
}

static DEVICE_ATTR_RW(sticky_reg);

static struct attribute *sticky_reg_attrs[] = {
	&dev_attr_sticky_reg.attr,
	NULL,
};
ATTRIBUTE_GROUPS(sticky_reg);

static int aml_restart_probe(struct platform_device *pdev)
{
	u32 id;
	int ret;
	unsigned int reg;
#ifdef CONFIG_AMLOGIC_PM_SETGPIO
	const char *value;
#endif

	if (!of_property_read_u32(pdev->dev.of_node, "sys_reset", &id)) {
		psci_function_id_restart = id;
		arm_pm_restart = do_aml_restart;
	}

	if (!of_property_read_u32(pdev->dev.of_node, "sys_poweroff", &id)) {
		psci_function_id_poweroff = id;
		pm_power_off = do_aml_poweroff;
	}

#ifdef CONFIG_AMLOGIC_PM_SETGPIO
	ret = of_property_read_string(pdev->dev.of_node, "poweroff-gpios",
				      &value);
	if (ret)
		pr_warn("no poweroff-gpios\n");
	else
		poweroff_desc = of_get_named_gpiod_flags(pdev->dev.of_node,
							 "poweroff-gpios",
							 0, NULL);

	ret = of_property_read_string(pdev->dev.of_node, "reset-gpios",
				      &value);
	if (ret)
		pr_warn("no reset-gpios\n");
	else
		reset_desc = of_get_named_gpiod_flags(pdev->dev.of_node,
						      "reset-gpios", 0, NULL);
#endif

	/* SYSCTRL_STICKY_REG6 */
	if (!of_property_read_u32(pdev->dev.of_node, "sticky_reg0", &reg))
		sticky_reg0 = (unsigned int *)ioremap(reg, 4);

	/* SYSCTRL_STICKY_REG7 */
	if (!of_property_read_u32(pdev->dev.of_node, "sticky_reg1", &reg))
		sticky_reg1 = (unsigned int *)ioremap(reg, 4);

	sticky_reg_cls = kzalloc(sizeof(struct class), GFP_KERNEL);
	if (sticky_reg_cls == NULL) {
		pr_err("%s no mem for zalloc\n", __func__);
		return -1;
	}
	sticky_reg_cls->name = sticky_reg_dev;
	sticky_reg_cls->class_groups = sticky_reg_groups;
	if (class_register(sticky_reg_cls) < 0) {
		pr_err("failed to class_reg for sticky reg\n");
		return -1;
	}

	ret = register_die_notifier(&panic_notifier);
	return ret;
}

static const struct of_device_id of_aml_restart_match[] = {
	{ .compatible = "aml, reboot", },
	{},
};
MODULE_DEVICE_TABLE(of, of_aml_restart_match);

static struct platform_driver aml_restart_driver = {
	.probe = aml_restart_probe,
	.driver = {
		.name = "aml-restart",
		.of_match_table = of_match_ptr(of_aml_restart_match),
	},
};

static int __init aml_restart_init(void)
{
	return platform_driver_register(&aml_restart_driver);
}
device_initcall(aml_restart_init);
