// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021, Linaro Limited
 * Copyright (c) 2010-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/mailbox_client.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/slab.h>
#include <linux/soc/qcom/irq.h>
#include <linux/spinlock.h>

/*
 * This is the driver for Qualcomm MPM (MSM Power Manager) interrupt controller,
 * which is commonly found on Qualcomm SoCs built on the RPM architecture.
 * Sitting in always-on domain, MPM monitors the wakeup interrupts when SoC is
 * asleep, and wakes up the AP when one of those interrupts occurs.  This driver
 * doesn't directly access physical MPM registers though.  Instead, the access
 * is bridged via a piece of internal memory (SRAM) that is accessible to both
 * AP and RPM.  This piece of memory is called 'vMPM' in the driver.
 *
 * When SoC is awake, the vMPM is owned by AP and the register setup by this
 * driver all happens on vMPM.  When AP is about to get power collapsed, the
 * driver sends a mailbox notification to RPM, which will take over the vMPM
 * ownership and dump vMPM into physical MPM registers.  On wakeup, AP is woken
 * up by a MPM pin/interrupt, and RPM will copy STATUS registers into vMPM.
 * Then AP start owning vMPM again.
 *
 * vMPM register map:
 *
 *    31                              0
 *    +--------------------------------+
 *    |            TIMER0              | 0x00
 *    +--------------------------------+
 *    |            TIMER1              | 0x04
 *    +--------------------------------+
 *    |            ENABLE0             | 0x08
 *    +--------------------------------+
 *    |              ...               | ...
 *    +--------------------------------+
 *    |            ENABLEn             |
 *    +--------------------------------+
 *    |          FALLING_EDGE0         |
 *    +--------------------------------+
 *    |              ...               |
 *    +--------------------------------+
 *    |            STATUSn             |
 *    +--------------------------------+
 *
 *    n = DIV_ROUND_UP(pin_cnt, 32)
 *
 */

#define MPM_REG_ENABLE		0
#define MPM_REG_FALLING_EDGE	1
#define MPM_REG_RISING_EDGE	2
#define MPM_REG_POLARITY	3
#define MPM_REG_STATUS		4

/* MPM pin map to GIC hwirq */
struct mpm_gic_map {
	int pin;
	irq_hw_number_t hwirq;
};

struct qcom_mpm_priv {
	void __iomem *base;
	raw_spinlock_t lock;
	struct mbox_client mbox_client;
	struct mbox_chan *mbox_chan;
	struct mpm_gic_map *maps;
	unsigned int map_cnt;
	unsigned int reg_stride;
	struct irq_domain *domain;
	struct generic_pm_domain genpd;
};

static u32 qcom_mpm_read(struct qcom_mpm_priv *priv, unsigned int reg,
			 unsigned int index)
{
	unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;

	return readl_relaxed(priv->base + offset);
}

static void qcom_mpm_write(struct qcom_mpm_priv *priv, unsigned int reg,
			   unsigned int index, u32 val)
{
	unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;

	writel_relaxed(val, priv->base + offset);

	/* Ensure the write is completed */
	wmb();
}

static void qcom_mpm_enable_irq(struct irq_data *d, bool en)
{
	struct qcom_mpm_priv *priv = d->chip_data;
	int pin = d->hwirq;
	unsigned int index = pin / 32;
	unsigned int shift = pin % 32;
	unsigned long flags, val;

	raw_spin_lock_irqsave(&priv->lock, flags);

	val = qcom_mpm_read(priv, MPM_REG_ENABLE, index);
	__assign_bit(shift, &val, en);
	qcom_mpm_write(priv, MPM_REG_ENABLE, index, val);

	raw_spin_unlock_irqrestore(&priv->lock, flags);
}

static void qcom_mpm_mask(struct irq_data *d)
{
	qcom_mpm_enable_irq(d, false);

	if (d->parent_data)
		irq_chip_mask_parent(d);
}

static void qcom_mpm_unmask(struct irq_data *d)
{
	qcom_mpm_enable_irq(d, true);

	if (d->parent_data)
		irq_chip_unmask_parent(d);
}

static void mpm_set_type(struct qcom_mpm_priv *priv, bool set, unsigned int reg,
			 unsigned int index, unsigned int shift)
{
	unsigned long flags, val;

	raw_spin_lock_irqsave(&priv->lock, flags);

	val = qcom_mpm_read(priv, reg, index);
	__assign_bit(shift, &val, set);
	qcom_mpm_write(priv, reg, index, val);

	raw_spin_unlock_irqrestore(&priv->lock, flags);
}

static int qcom_mpm_set_type(struct irq_data *d, unsigned int type)
{
	struct qcom_mpm_priv *priv = d->chip_data;
	int pin = d->hwirq;
	unsigned int index = pin / 32;
	unsigned int shift = pin % 32;

	if (type & IRQ_TYPE_EDGE_RISING)
		mpm_set_type(priv, true, MPM_REG_RISING_EDGE, index, shift);
	else
		mpm_set_type(priv, false, MPM_REG_RISING_EDGE, index, shift);

	if (type & IRQ_TYPE_EDGE_FALLING)
		mpm_set_type(priv, true, MPM_REG_FALLING_EDGE, index, shift);
	else
		mpm_set_type(priv, false, MPM_REG_FALLING_EDGE, index, shift);

	if (type & IRQ_TYPE_LEVEL_HIGH)
		mpm_set_type(priv, true, MPM_REG_POLARITY, index, shift);
	else
		mpm_set_type(priv, false, MPM_REG_POLARITY, index, shift);

	if (!d->parent_data)
		return 0;

	if (type & IRQ_TYPE_EDGE_BOTH)
		type = IRQ_TYPE_EDGE_RISING;

	if (type & IRQ_TYPE_LEVEL_MASK)
		type = IRQ_TYPE_LEVEL_HIGH;

	return irq_chip_set_type_parent(d, type);
}

static struct irq_chip qcom_mpm_chip = {
	.name			= "mpm",
	.irq_eoi		= irq_chip_eoi_parent,
	.irq_mask		= qcom_mpm_mask,
	.irq_unmask		= qcom_mpm_unmask,
	.irq_retrigger		= irq_chip_retrigger_hierarchy,
	.irq_set_type		= qcom_mpm_set_type,
	.irq_set_affinity	= irq_chip_set_affinity_parent,
	.flags			= IRQCHIP_MASK_ON_SUSPEND |
				  IRQCHIP_SKIP_SET_WAKE,
};

static struct mpm_gic_map *get_mpm_gic_map(struct qcom_mpm_priv *priv, int pin)
{
	struct mpm_gic_map *maps = priv->maps;
	int i;

	for (i = 0; i < priv->map_cnt; i++) {
		if (maps[i].pin == pin)
			return &maps[i];
	}

	return NULL;
}

static int qcom_mpm_alloc(struct irq_domain *domain, unsigned int virq,
			  unsigned int nr_irqs, void *data)
{
	struct qcom_mpm_priv *priv = domain->host_data;
	struct irq_fwspec *fwspec = data;
	struct irq_fwspec parent_fwspec;
	struct mpm_gic_map *map;
	irq_hw_number_t pin;
	unsigned int type;
	int  ret;

	ret = irq_domain_translate_twocell(domain, fwspec, &pin, &type);
	if (ret)
		return ret;

	ret = irq_domain_set_hwirq_and_chip(domain, virq, pin,
					    &qcom_mpm_chip, priv);
	if (ret)
		return ret;

	map = get_mpm_gic_map(priv, pin);
	if (map == NULL)
		return irq_domain_disconnect_hierarchy(domain->parent, virq);

	if (type & IRQ_TYPE_EDGE_BOTH)
		type = IRQ_TYPE_EDGE_RISING;

	if (type & IRQ_TYPE_LEVEL_MASK)
		type = IRQ_TYPE_LEVEL_HIGH;

	parent_fwspec.fwnode = domain->parent->fwnode;
	parent_fwspec.param_count = 3;
	parent_fwspec.param[0] = 0;
	parent_fwspec.param[1] = map->hwirq;
	parent_fwspec.param[2] = type;

	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
					    &parent_fwspec);
}

static const struct irq_domain_ops qcom_mpm_ops = {
	.alloc		= qcom_mpm_alloc,
	.free		= irq_domain_free_irqs_common,
	.translate	= irq_domain_translate_twocell,
};

/* Triggered by RPM when system resumes from deep sleep */
static irqreturn_t qcom_mpm_handler(int irq, void *dev_id)
{
	struct qcom_mpm_priv *priv = dev_id;
	unsigned long enable, pending;
	irqreturn_t ret = IRQ_NONE;
	unsigned long flags;
	int i, j;

	for (i = 0; i < priv->reg_stride; i++) {
		raw_spin_lock_irqsave(&priv->lock, flags);
		enable = qcom_mpm_read(priv, MPM_REG_ENABLE, i);
		pending = qcom_mpm_read(priv, MPM_REG_STATUS, i);
		pending &= enable;
		raw_spin_unlock_irqrestore(&priv->lock, flags);

		for_each_set_bit(j, &pending, 32) {
			unsigned int pin = 32 * i + j;
			struct irq_desc *desc = irq_resolve_mapping(priv->domain, pin);
			struct irq_data *d = &desc->irq_data;

			if (!irqd_is_level_type(d))
				irq_set_irqchip_state(d->irq,
						IRQCHIP_STATE_PENDING, true);
			ret = IRQ_HANDLED;
		}
	}

	return ret;
}

static int mpm_pd_power_off(struct generic_pm_domain *genpd)
{
	struct qcom_mpm_priv *priv = container_of(genpd, struct qcom_mpm_priv,
						  genpd);
	int i, ret;

	for (i = 0; i < priv->reg_stride; i++)
		qcom_mpm_write(priv, MPM_REG_STATUS, i, 0);

	/* Notify RPM to write vMPM into HW */
	ret = mbox_send_message(priv->mbox_chan, NULL);
	if (ret < 0)
		return ret;

	return 0;
}

static bool gic_hwirq_is_mapped(struct mpm_gic_map *maps, int cnt, u32 hwirq)
{
	int i;

	for (i = 0; i < cnt; i++)
		if (maps[i].hwirq == hwirq)
			return true;

	return false;
}

static int qcom_mpm_init(struct device_node *np, struct device_node *parent)
{
	struct platform_device *pdev = of_find_device_by_node(np);
	struct device *dev = &pdev->dev;
	struct irq_domain *parent_domain;
	struct generic_pm_domain *genpd;
	struct qcom_mpm_priv *priv;
	unsigned int pin_cnt;
	int i, irq;
	int ret;

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

	ret = of_property_read_u32(np, "qcom,mpm-pin-count", &pin_cnt);
	if (ret) {
		dev_err(dev, "failed to read qcom,mpm-pin-count: %d\n", ret);
		return ret;
	}

	priv->reg_stride = DIV_ROUND_UP(pin_cnt, 32);

	ret = of_property_count_u32_elems(np, "qcom,mpm-pin-map");
	if (ret < 0) {
		dev_err(dev, "failed to read qcom,mpm-pin-map: %d\n", ret);
		return ret;
	}

	if (ret % 2) {
		dev_err(dev, "invalid qcom,mpm-pin-map\n");
		return -EINVAL;
	}

	priv->map_cnt = ret / 2;
	priv->maps = devm_kcalloc(dev, priv->map_cnt, sizeof(*priv->maps),
				  GFP_KERNEL);
	if (!priv->maps)
		return -ENOMEM;

	for (i = 0; i < priv->map_cnt; i++) {
		u32 pin, hwirq;

		of_property_read_u32_index(np, "qcom,mpm-pin-map", i * 2, &pin);
		of_property_read_u32_index(np, "qcom,mpm-pin-map", i * 2 + 1, &hwirq);

		if (gic_hwirq_is_mapped(priv->maps, i, hwirq)) {
			dev_warn(dev, "failed to map pin %d as GIC hwirq %d is already mapped\n",
				 pin, hwirq);
			continue;
		}

		priv->maps[i].pin = pin;
		priv->maps[i].hwirq = hwirq;
	}

	raw_spin_lock_init(&priv->lock);

	priv->base = devm_platform_ioremap_resource(pdev, 0);
	if (!priv->base)
		return PTR_ERR(priv->base);

	for (i = 0; i < priv->reg_stride; i++) {
		qcom_mpm_write(priv, MPM_REG_ENABLE, i, 0);
		qcom_mpm_write(priv, MPM_REG_FALLING_EDGE, i, 0);
		qcom_mpm_write(priv, MPM_REG_RISING_EDGE, i, 0);
		qcom_mpm_write(priv, MPM_REG_POLARITY, i, 0);
		qcom_mpm_write(priv, MPM_REG_STATUS, i, 0);
	}

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

	genpd = &priv->genpd;
	genpd->flags = GENPD_FLAG_IRQ_SAFE;
	genpd->power_off = mpm_pd_power_off;

	genpd->name = devm_kasprintf(dev, GFP_KERNEL, "%s", dev_name(dev));
	if (!genpd->name)
		return -ENOMEM;

	ret = pm_genpd_init(genpd, NULL, false);
	if (ret) {
		dev_err(dev, "failed to init genpd: %d\n", ret);
		return ret;
	}

	ret = of_genpd_add_provider_simple(np, genpd);
	if (ret) {
		dev_err(dev, "failed to add genpd provider: %d\n", ret);
		goto remove_genpd;
	}

	priv->mbox_client.dev = dev;
	priv->mbox_chan = mbox_request_channel(&priv->mbox_client, 0);
	if (IS_ERR(priv->mbox_chan)) {
		ret = PTR_ERR(priv->mbox_chan);
		dev_err(dev, "failed to acquire IPC channel: %d\n", ret);
		return ret;
	}

	parent_domain = irq_find_host(parent);
	if (!parent_domain) {
		dev_err(dev, "failed to find MPM parent domain\n");
		ret = -ENXIO;
		goto free_mbox;
	}

	priv->domain = irq_domain_create_hierarchy(parent_domain,
				IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP, pin_cnt,
				of_node_to_fwnode(np), &qcom_mpm_ops, priv);
	if (!priv->domain) {
		dev_err(dev, "failed to create MPM domain\n");
		ret = -ENOMEM;
		goto free_mbox;
	}

	irq_domain_update_bus_token(priv->domain, DOMAIN_BUS_WAKEUP);

	ret = devm_request_irq(dev, irq, qcom_mpm_handler, IRQF_NO_SUSPEND,
			       "qcom_mpm", priv);
	if (ret) {
		dev_err(dev, "failed to request irq: %d\n", ret);
		goto remove_domain;
	}

	return 0;

remove_domain:
	irq_domain_remove(priv->domain);
free_mbox:
	mbox_free_channel(priv->mbox_chan);
remove_genpd:
	pm_genpd_remove(genpd);
	return ret;
}

IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_mpm)
IRQCHIP_MATCH("qcom,mpm", qcom_mpm_init)
IRQCHIP_PLATFORM_DRIVER_END(qcom_mpm)
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. MSM Power Manager");
MODULE_LICENSE("GPL v2");
