/*
 * intel_bxtwc_tmu.c - 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.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/module.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) {
		dev_err(&pdev->dev, "invalid irq %d\n", irq);
		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");
