/*
 * Copyright (c) 2014 MediaTek Inc.
 * Author: Joe.C <yingjoe.chen@mediatek.com>
 *
 * 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/irq.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#include "irqchip.h"

struct mtk_sysirq_chip_data {
	spinlock_t lock;
	void __iomem *intpol_base;
};

static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type)
{
	irq_hw_number_t hwirq = data->hwirq;
	struct mtk_sysirq_chip_data *chip_data = data->chip_data;
	u32 offset, reg_index, value;
	unsigned long flags;
	int ret;

	offset = hwirq & 0x1f;
	reg_index = hwirq >> 5;

	spin_lock_irqsave(&chip_data->lock, flags);
	value = readl_relaxed(chip_data->intpol_base + reg_index * 4);
	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
		if (type == IRQ_TYPE_LEVEL_LOW)
			type = IRQ_TYPE_LEVEL_HIGH;
		else
			type = IRQ_TYPE_EDGE_RISING;
		value |= (1 << offset);
	} else {
		value &= ~(1 << offset);
	}
	writel(value, chip_data->intpol_base + reg_index * 4);

	data = data->parent_data;
	ret = data->chip->irq_set_type(data, type);
	spin_unlock_irqrestore(&chip_data->lock, flags);
	return ret;
}

static struct irq_chip mtk_sysirq_chip = {
	.name			= "MT_SYSIRQ",
	.irq_mask		= irq_chip_mask_parent,
	.irq_unmask		= irq_chip_unmask_parent,
	.irq_eoi		= irq_chip_eoi_parent,
	.irq_set_type		= mtk_sysirq_set_type,
	.irq_retrigger		= irq_chip_retrigger_hierarchy,
	.irq_set_affinity	= irq_chip_set_affinity_parent,
};

static int mtk_sysirq_domain_xlate(struct irq_domain *d,
				   struct device_node *controller,
				   const u32 *intspec, unsigned int intsize,
				   unsigned long *out_hwirq,
				   unsigned int *out_type)
{
	if (intsize != 3)
		return -EINVAL;

	/* sysirq doesn't support PPI */
	if (intspec[0])
		return -EINVAL;

	*out_hwirq = intspec[1];
	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
	return 0;
}

static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
				   unsigned int nr_irqs, void *arg)
{
	int i;
	irq_hw_number_t hwirq;
	struct of_phandle_args *irq_data = arg;
	struct of_phandle_args gic_data = *irq_data;

	if (irq_data->args_count != 3)
		return -EINVAL;

	/* sysirq doesn't support PPI */
	if (irq_data->args[0])
		return -EINVAL;

	hwirq = irq_data->args[1];
	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
					      &mtk_sysirq_chip,
					      domain->host_data);

	gic_data.np = domain->parent->of_node;
	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
}

static struct irq_domain_ops sysirq_domain_ops = {
	.xlate = mtk_sysirq_domain_xlate,
	.alloc = mtk_sysirq_domain_alloc,
	.free = irq_domain_free_irqs_common,
};

static int __init mtk_sysirq_of_init(struct device_node *node,
				     struct device_node *parent)
{
	struct irq_domain *domain, *domain_parent;
	struct mtk_sysirq_chip_data *chip_data;
	int ret, size, intpol_num;
	struct resource res;

	domain_parent = irq_find_host(parent);
	if (!domain_parent) {
		pr_err("mtk_sysirq: interrupt-parent not found\n");
		return -EINVAL;
	}

	ret = of_address_to_resource(node, 0, &res);
	if (ret)
		return ret;

	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
	if (!chip_data)
		return -ENOMEM;

	size = resource_size(&res);
	intpol_num = size * 8;
	chip_data->intpol_base = ioremap(res.start, size);
	if (!chip_data->intpol_base) {
		pr_err("mtk_sysirq: unable to map sysirq register\n");
		ret = PTR_ERR(chip_data->intpol_base);
		goto out_free;
	}

	domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
					  &sysirq_domain_ops, chip_data);
	if (!domain) {
		ret = -ENOMEM;
		goto out_unmap;
	}
	spin_lock_init(&chip_data->lock);

	return 0;

out_unmap:
	iounmap(chip_data->intpol_base);
out_free:
	kfree(chip_data);
	return ret;
}
IRQCHIP_DECLARE(mtk_sysirq, "mediatek,mt6577-sysirq", mtk_sysirq_of_init);
