// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Copyright (C) 2014 STMicroelectronics – All Rights Reserved
 *
 *  Author: Lee Jones <lee.jones@linaro.org>
 *
 *  This is a re-write of Christophe Kerello's PMU driver.
 */

#include <dt-bindings/interrupt-controller/irq-st.h>
#include <linux/err.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#define STIH407_SYSCFG_5102		0x198

#define ST_A9_IRQ_MASK			0x001FFFFF
#define ST_A9_IRQ_MAX_CHANS		2

#define ST_A9_IRQ_EN_CTI_0		BIT(0)
#define ST_A9_IRQ_EN_CTI_1		BIT(1)
#define ST_A9_IRQ_EN_PMU_0		BIT(2)
#define ST_A9_IRQ_EN_PMU_1		BIT(3)
#define ST_A9_IRQ_EN_PL310_L2		BIT(4)
#define ST_A9_IRQ_EN_EXT_0		BIT(5)
#define ST_A9_IRQ_EN_EXT_1		BIT(6)
#define ST_A9_IRQ_EN_EXT_2		BIT(7)

#define ST_A9_FIQ_N_SEL(dev, chan)	(dev << (8  + (chan * 3)))
#define ST_A9_IRQ_N_SEL(dev, chan)	(dev << (14 + (chan * 3)))
#define ST_A9_EXTIRQ_INV_SEL(dev)	(dev << 20)

struct st_irq_syscfg {
	struct regmap *regmap;
	unsigned int syscfg;
	unsigned int config;
	bool ext_inverted;
};

static const struct of_device_id st_irq_syscfg_match[] = {
	{
		.compatible = "st,stih407-irq-syscfg",
		.data = (void *)STIH407_SYSCFG_5102,
	},
	{}
};

static int st_irq_xlate(struct platform_device *pdev,
			int device, int channel, bool irq)
{
	struct st_irq_syscfg *ddata = dev_get_drvdata(&pdev->dev);

	/* Set the device enable bit. */
	switch (device) {
	case ST_IRQ_SYSCFG_EXT_0:
		ddata->config |= ST_A9_IRQ_EN_EXT_0;
		break;
	case ST_IRQ_SYSCFG_EXT_1:
		ddata->config |= ST_A9_IRQ_EN_EXT_1;
		break;
	case ST_IRQ_SYSCFG_EXT_2:
		ddata->config |= ST_A9_IRQ_EN_EXT_2;
		break;
	case ST_IRQ_SYSCFG_CTI_0:
		ddata->config |= ST_A9_IRQ_EN_CTI_0;
		break;
	case ST_IRQ_SYSCFG_CTI_1:
		ddata->config |= ST_A9_IRQ_EN_CTI_1;
		break;
	case ST_IRQ_SYSCFG_PMU_0:
		ddata->config |= ST_A9_IRQ_EN_PMU_0;
		break;
	case ST_IRQ_SYSCFG_PMU_1:
		ddata->config |= ST_A9_IRQ_EN_PMU_1;
		break;
	case ST_IRQ_SYSCFG_pl310_L2:
		ddata->config |= ST_A9_IRQ_EN_PL310_L2;
		break;
	case ST_IRQ_SYSCFG_DISABLED:
		return 0;
	default:
		dev_err(&pdev->dev, "Unrecognised device %d\n", device);
		return -EINVAL;
	}

	/* Select IRQ/FIQ channel for device. */
	ddata->config |= irq ?
		ST_A9_IRQ_N_SEL(device, channel) :
		ST_A9_FIQ_N_SEL(device, channel);

	return 0;
}

static int st_irq_syscfg_enable(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct st_irq_syscfg *ddata = dev_get_drvdata(&pdev->dev);
	int channels, ret, i;
	u32 device, invert;

	channels = of_property_count_u32_elems(np, "st,irq-device");
	if (channels != ST_A9_IRQ_MAX_CHANS) {
		dev_err(&pdev->dev, "st,enable-irq-device must have 2 elems\n");
		return -EINVAL;
	}

	channels = of_property_count_u32_elems(np, "st,fiq-device");
	if (channels != ST_A9_IRQ_MAX_CHANS) {
		dev_err(&pdev->dev, "st,enable-fiq-device must have 2 elems\n");
		return -EINVAL;
	}

	for (i = 0; i < ST_A9_IRQ_MAX_CHANS; i++) {
		of_property_read_u32_index(np, "st,irq-device", i, &device);

		ret = st_irq_xlate(pdev, device, i, true);
		if (ret)
			return ret;

		of_property_read_u32_index(np, "st,fiq-device", i, &device);

		ret = st_irq_xlate(pdev, device, i, false);
		if (ret)
			return ret;
	}

	/* External IRQs may be inverted. */
	of_property_read_u32(np, "st,invert-ext", &invert);
	ddata->config |= ST_A9_EXTIRQ_INV_SEL(invert);

	return regmap_update_bits(ddata->regmap, ddata->syscfg,
				  ST_A9_IRQ_MASK, ddata->config);
}

static int st_irq_syscfg_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct st_irq_syscfg *ddata;

	ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
	if (!ddata)
		return -ENOMEM;

	ddata->syscfg = (unsigned int) device_get_match_data(&pdev->dev);

	ddata->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
	if (IS_ERR(ddata->regmap)) {
		dev_err(&pdev->dev, "syscfg phandle missing\n");
		return PTR_ERR(ddata->regmap);
	}

	dev_set_drvdata(&pdev->dev, ddata);

	return st_irq_syscfg_enable(pdev);
}

static int __maybe_unused st_irq_syscfg_resume(struct device *dev)
{
	struct st_irq_syscfg *ddata = dev_get_drvdata(dev);

	return regmap_update_bits(ddata->regmap, ddata->syscfg,
				  ST_A9_IRQ_MASK, ddata->config);
}

static SIMPLE_DEV_PM_OPS(st_irq_syscfg_pm_ops, NULL, st_irq_syscfg_resume);

static struct platform_driver st_irq_syscfg_driver = {
	.driver = {
		.name = "st_irq_syscfg",
		.pm = &st_irq_syscfg_pm_ops,
		.of_match_table = st_irq_syscfg_match,
	},
	.probe = st_irq_syscfg_probe,
};

static int __init st_irq_syscfg_init(void)
{
	return platform_driver_register(&st_irq_syscfg_driver);
}
core_initcall(st_irq_syscfg_init);
