// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
 * SP7021 reset driver
 *
 * Copyright (C) Sunplus Technology Co., Ltd.
 *       All rights reserved.
 */

#include <linux/io.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
#include <linux/reboot.h>

/* HIWORD_MASK_REG BITS */
#define BITS_PER_HWM_REG	16

/* resets HW info: reg_index_shift */
static const u32 sp_resets[] = {
/* SP7021: mo_reset0 ~ mo_reset9 */
	0x00,
	0x02,
	0x03,
	0x04,
	0x05,
	0x06,
	0x07,
	0x08,
	0x09,
	0x0a,
	0x0b,
	0x0d,
	0x0e,
	0x0f,
	0x10,
	0x12,
	0x14,
	0x15,
	0x16,
	0x17,
	0x18,
	0x19,
	0x1a,
	0x1b,
	0x1c,
	0x1d,
	0x1e,
	0x1f,
	0x20,
	0x21,
	0x22,
	0x23,
	0x24,
	0x25,
	0x26,
	0x2a,
	0x2b,
	0x2d,
	0x2e,
	0x30,
	0x31,
	0x32,
	0x33,
	0x3d,
	0x3e,
	0x3f,
	0x42,
	0x44,
	0x4b,
	0x4c,
	0x4d,
	0x4e,
	0x4f,
	0x50,
	0x55,
	0x60,
	0x61,
	0x6a,
	0x6f,
	0x70,
	0x73,
	0x74,
	0x86,
	0x8a,
	0x8b,
	0x8d,
	0x8e,
	0x8f,
	0x90,
	0x92,
	0x93,
	0x94,
	0x95,
	0x96,
	0x97,
	0x98,
	0x99,
};

struct sp_reset {
	struct reset_controller_dev rcdev;
	void __iomem *base;
};

static inline struct sp_reset *to_sp_reset(struct reset_controller_dev *rcdev)
{
	return container_of(rcdev, struct sp_reset, rcdev);
}

static int sp_reset_update(struct reset_controller_dev *rcdev,
			   unsigned long id, bool assert)
{
	struct sp_reset *reset = to_sp_reset(rcdev);
	int index = sp_resets[id] / BITS_PER_HWM_REG;
	int shift = sp_resets[id] % BITS_PER_HWM_REG;
	u32 val;

	val = (1 << (16 + shift)) | (assert << shift);
	writel(val, reset->base + (index * 4));

	return 0;
}

static int sp_reset_assert(struct reset_controller_dev *rcdev,
			   unsigned long id)
{
	return sp_reset_update(rcdev, id, true);
}

static int sp_reset_deassert(struct reset_controller_dev *rcdev,
			     unsigned long id)
{
	return sp_reset_update(rcdev, id, false);
}

static int sp_reset_status(struct reset_controller_dev *rcdev,
			   unsigned long id)
{
	struct sp_reset *reset = to_sp_reset(rcdev);
	int index = sp_resets[id] / BITS_PER_HWM_REG;
	int shift = sp_resets[id] % BITS_PER_HWM_REG;
	u32 reg;

	reg = readl(reset->base + (index * 4));

	return !!(reg & BIT(shift));
}

static const struct reset_control_ops sp_reset_ops = {
	.assert   = sp_reset_assert,
	.deassert = sp_reset_deassert,
	.status   = sp_reset_status,
};

static int sp_restart(struct sys_off_data *data)
{
	struct sp_reset *reset = data->cb_data;

	sp_reset_assert(&reset->rcdev, 0);
	sp_reset_deassert(&reset->rcdev, 0);

	return NOTIFY_DONE;
}

static int sp_reset_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct sp_reset *reset;
	struct resource *res;
	int ret;

	reset = devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL);
	if (!reset)
		return -ENOMEM;

	reset->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(reset->base))
		return PTR_ERR(reset->base);

	reset->rcdev.ops = &sp_reset_ops;
	reset->rcdev.owner = THIS_MODULE;
	reset->rcdev.of_node = dev->of_node;
	reset->rcdev.nr_resets = resource_size(res) / 4 * BITS_PER_HWM_REG;

	ret = devm_reset_controller_register(dev, &reset->rcdev);
	if (ret)
		return ret;

	return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
					     192, sp_restart, reset);
}

static const struct of_device_id sp_reset_dt_ids[] = {
	{.compatible = "sunplus,sp7021-reset",},
	{ /* sentinel */ },
};

static struct platform_driver sp_reset_driver = {
	.probe = sp_reset_probe,
	.driver = {
		.name			= "sunplus-reset",
		.of_match_table		= sp_reset_dt_ids,
		.suppress_bind_attrs	= true,
	},
};
builtin_platform_driver(sp_reset_driver);
