// SPDX-License-Identifier: GPL-2.0+
/*
 * Loongson-2 PM Support
 *
 * Copyright (C) 2023 Loongson Technology Corporation Limited
 */

#include <linux/io.h>
#include <linux/of.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/suspend.h>
#include <linux/interrupt.h>
#include <linux/pm_wakeirq.h>
#include <linux/platform_device.h>
#include <asm/bootinfo.h>
#include <asm/suspend.h>

#define LOONGSON2_PM1_CNT_REG		0x14
#define LOONGSON2_PM1_STS_REG		0x0c
#define LOONGSON2_PM1_ENA_REG		0x10
#define LOONGSON2_GPE0_STS_REG		0x28
#define LOONGSON2_GPE0_ENA_REG		0x2c

#define LOONGSON2_PM1_PWRBTN_STS	BIT(8)
#define LOONGSON2_PM1_PCIEXP_WAKE_STS	BIT(14)
#define LOONGSON2_PM1_WAKE_STS		BIT(15)
#define LOONGSON2_PM1_CNT_INT_EN	BIT(0)
#define LOONGSON2_PM1_PWRBTN_EN		LOONGSON2_PM1_PWRBTN_STS

static struct loongson2_pm {
	void __iomem			*base;
	struct input_dev		*dev;
	bool				suspended;
} loongson2_pm;

#define loongson2_pm_readw(reg)		readw(loongson2_pm.base + reg)
#define loongson2_pm_readl(reg)		readl(loongson2_pm.base + reg)
#define loongson2_pm_writew(val, reg)	writew(val, loongson2_pm.base + reg)
#define loongson2_pm_writel(val, reg)	writel(val, loongson2_pm.base + reg)

static void loongson2_pm_status_clear(void)
{
	u16 value;

	value = loongson2_pm_readw(LOONGSON2_PM1_STS_REG);
	value |= (LOONGSON2_PM1_PWRBTN_STS | LOONGSON2_PM1_PCIEXP_WAKE_STS |
		  LOONGSON2_PM1_WAKE_STS);
	loongson2_pm_writew(value, LOONGSON2_PM1_STS_REG);
	loongson2_pm_writel(loongson2_pm_readl(LOONGSON2_GPE0_STS_REG), LOONGSON2_GPE0_STS_REG);
}

static void loongson2_pm_irq_enable(void)
{
	u16 value;

	value = loongson2_pm_readw(LOONGSON2_PM1_CNT_REG);
	value |= LOONGSON2_PM1_CNT_INT_EN;
	loongson2_pm_writew(value, LOONGSON2_PM1_CNT_REG);

	value = loongson2_pm_readw(LOONGSON2_PM1_ENA_REG);
	value |= LOONGSON2_PM1_PWRBTN_EN;
	loongson2_pm_writew(value, LOONGSON2_PM1_ENA_REG);
}

static int loongson2_suspend_enter(suspend_state_t state)
{
	loongson2_pm_status_clear();
	loongarch_common_suspend();
	loongarch_suspend_enter();
	loongarch_common_resume();
	loongson2_pm_irq_enable();
	pm_set_resume_via_firmware();

	return 0;
}

static int loongson2_suspend_begin(suspend_state_t state)
{
	pm_set_suspend_via_firmware();

	return 0;
}

static int loongson2_suspend_valid_state(suspend_state_t state)
{
	return (state == PM_SUSPEND_MEM);
}

static const struct platform_suspend_ops loongson2_suspend_ops = {
	.valid	= loongson2_suspend_valid_state,
	.begin	= loongson2_suspend_begin,
	.enter	= loongson2_suspend_enter,
};

static int loongson2_power_button_init(struct device *dev, int irq)
{
	int ret;
	struct input_dev *button;

	button = input_allocate_device();
	if (!dev)
		return -ENOMEM;

	button->name = "Power Button";
	button->phys = "pm/button/input0";
	button->id.bustype = BUS_HOST;
	button->dev.parent = NULL;
	input_set_capability(button, EV_KEY, KEY_POWER);

	ret = input_register_device(button);
	if (ret)
		goto free_dev;

	dev_pm_set_wake_irq(&button->dev, irq);
	device_set_wakeup_capable(&button->dev, true);
	device_set_wakeup_enable(&button->dev, true);

	loongson2_pm.dev = button;
	dev_info(dev, "Power Button: Init successful!\n");

	return 0;

free_dev:
	input_free_device(button);

	return ret;
}

static irqreturn_t loongson2_pm_irq_handler(int irq, void *dev_id)
{
	u16 status = loongson2_pm_readw(LOONGSON2_PM1_STS_REG);

	if (!loongson2_pm.suspended && (status & LOONGSON2_PM1_PWRBTN_STS)) {
		pr_info("Power Button pressed...\n");
		input_report_key(loongson2_pm.dev, KEY_POWER, 1);
		input_sync(loongson2_pm.dev);
		input_report_key(loongson2_pm.dev, KEY_POWER, 0);
		input_sync(loongson2_pm.dev);
	}

	loongson2_pm_status_clear();

	return IRQ_HANDLED;
}

static int __maybe_unused loongson2_pm_suspend(struct device *dev)
{
	loongson2_pm.suspended = true;

	return 0;
}

static int __maybe_unused loongson2_pm_resume(struct device *dev)
{
	loongson2_pm.suspended = false;

	return 0;
}
static SIMPLE_DEV_PM_OPS(loongson2_pm_ops, loongson2_pm_suspend, loongson2_pm_resume);

static int loongson2_pm_probe(struct platform_device *pdev)
{
	int irq, retval;
	u64 suspend_addr;
	struct device *dev = &pdev->dev;

	loongson2_pm.base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(loongson2_pm.base))
		return PTR_ERR(loongson2_pm.base);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	if (!device_property_read_u64(dev, "loongson,suspend-address", &suspend_addr))
		loongson_sysconf.suspend_addr = (u64)phys_to_virt(suspend_addr);
	else
		dev_err(dev, "No loongson,suspend-address, could not support S3!\n");

	if (loongson2_power_button_init(dev, irq))
		return -EINVAL;

	retval = devm_request_irq(&pdev->dev, irq, loongson2_pm_irq_handler,
				  IRQF_SHARED, "pm_irq", &loongson2_pm);
	if (retval)
		return retval;

	loongson2_pm_irq_enable();
	loongson2_pm_status_clear();

	if (loongson_sysconf.suspend_addr)
		suspend_set_ops(&loongson2_suspend_ops);

	return 0;
}

static const struct of_device_id loongson2_pm_match[] = {
	{ .compatible = "loongson,ls2k0500-pmc", },
	{ .compatible = "loongson,ls2k1000-pmc", },
	{},
};

static struct platform_driver loongson2_pm_driver = {
	.driver = {
		.name = "ls2k-pm",
		.pm = &loongson2_pm_ops,
		.of_match_table = loongson2_pm_match,
	},
	.probe = loongson2_pm_probe,
};
module_platform_driver(loongson2_pm_driver);

MODULE_DESCRIPTION("Loongson-2 PM driver");
MODULE_LICENSE("GPL");
