// SPDX-License-Identifier: GPL-2.0
/*
 * Intel BXT Whiskey Cove PMIC TMU driver
 *
 * Copyright (C) 2016 Intel Corporation. All rights reserved.
 *
 * This driver adds TMU (Time Management Unit) support for Intel BXT platform.
 * It enables the alarm wake-up functionality in the TMU unit of Whiskey Cove
 * PMIC.
 */

#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/mfd/intel_soc_pmic.h>

#define BXTWC_TMUIRQ		0x4fb6
#define BXTWC_MIRQLVL1		0x4e0e
#define BXTWC_MTMUIRQ_REG	0x4fb7
#define BXTWC_MIRQLVL1_MTMU	BIT(1)
#define BXTWC_TMU_WK_ALRM	BIT(1)
#define BXTWC_TMU_SYS_ALRM	BIT(2)
#define BXTWC_TMU_ALRM_MASK	(BXTWC_TMU_WK_ALRM | BXTWC_TMU_SYS_ALRM)
#define BXTWC_TMU_ALRM_IRQ	(BXTWC_TMU_WK_ALRM | BXTWC_TMU_SYS_ALRM)

struct wcove_tmu {
	int irq;
	struct device *dev;
	struct regmap *regmap;
};

static irqreturn_t bxt_wcove_tmu_irq_handler(int irq, void *data)
{
	struct wcove_tmu *wctmu = data;
	unsigned int tmu_irq;

	/* Read TMU interrupt reg */
	regmap_read(wctmu->regmap, BXTWC_TMUIRQ, &tmu_irq);
	if (tmu_irq & BXTWC_TMU_ALRM_IRQ) {
		/* clear TMU irq */
		regmap_write(wctmu->regmap, BXTWC_TMUIRQ, tmu_irq);
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}

static int bxt_wcove_tmu_probe(struct platform_device *pdev)
{
	struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
	struct regmap_irq_chip_data *regmap_irq_chip;
	struct wcove_tmu *wctmu;
	int ret, virq, irq;

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

	wctmu->dev = &pdev->dev;
	wctmu->regmap = pmic->regmap;

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

	regmap_irq_chip = pmic->irq_chip_data_tmu;
	virq = regmap_irq_get_virq(regmap_irq_chip, irq);
	if (virq < 0) {
		dev_err(&pdev->dev,
			"failed to get virtual interrupt=%d\n", irq);
		return virq;
	}

	ret = devm_request_threaded_irq(&pdev->dev, virq,
					NULL, bxt_wcove_tmu_irq_handler,
					IRQF_ONESHOT, "bxt_wcove_tmu", wctmu);
	if (ret) {
		dev_err(&pdev->dev, "request irq failed: %d,virq: %d\n",
							ret, virq);
		return ret;
	}
	wctmu->irq = virq;

	/* Unmask TMU second level Wake & System alarm */
	regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG,
				  BXTWC_TMU_ALRM_MASK, 0);

	platform_set_drvdata(pdev, wctmu);
	return 0;
}

static int bxt_wcove_tmu_remove(struct platform_device *pdev)
{
	struct wcove_tmu *wctmu = platform_get_drvdata(pdev);
	unsigned int val;

	/* Mask TMU interrupts */
	regmap_read(wctmu->regmap, BXTWC_MIRQLVL1, &val);
	regmap_write(wctmu->regmap, BXTWC_MIRQLVL1,
			val | BXTWC_MIRQLVL1_MTMU);
	regmap_read(wctmu->regmap, BXTWC_MTMUIRQ_REG, &val);
	regmap_write(wctmu->regmap, BXTWC_MTMUIRQ_REG,
			val | BXTWC_TMU_ALRM_MASK);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int bxtwc_tmu_suspend(struct device *dev)
{
	struct wcove_tmu *wctmu = dev_get_drvdata(dev);

	enable_irq_wake(wctmu->irq);
	return 0;
}

static int bxtwc_tmu_resume(struct device *dev)
{
	struct wcove_tmu *wctmu = dev_get_drvdata(dev);

	disable_irq_wake(wctmu->irq);
	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(bxtwc_tmu_pm_ops, bxtwc_tmu_suspend, bxtwc_tmu_resume);

static const struct platform_device_id bxt_wcove_tmu_id_table[] = {
	{ .name = "bxt_wcove_tmu" },
	{},
};
MODULE_DEVICE_TABLE(platform, bxt_wcove_tmu_id_table);

static struct platform_driver bxt_wcove_tmu_driver = {
	.probe = bxt_wcove_tmu_probe,
	.remove = bxt_wcove_tmu_remove,
	.driver = {
		.name = "bxt_wcove_tmu",
		.pm     = &bxtwc_tmu_pm_ops,
	},
	.id_table = bxt_wcove_tmu_id_table,
};

module_platform_driver(bxt_wcove_tmu_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Nilesh Bacchewar <nilesh.bacchewar@intel.com>");
MODULE_DESCRIPTION("BXT Whiskey Cove TMU Driver");
