// SPDX-License-Identifier: GPL-2.0
/*
 * Toshiba Visconti GPIO Support
 *
 * (C) Copyright 2020 Toshiba Electronic Devices & Storage Corporation
 * (C) Copyright 2020 TOSHIBA CORPORATION
 *
 * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
 */

#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/bitops.h>

/* register offset */
#define GPIO_DIR	0x00
#define GPIO_IDATA	0x08
#define GPIO_ODATA	0x10
#define GPIO_OSET	0x18
#define GPIO_OCLR	0x20
#define GPIO_INTMODE	0x30

#define BASE_HW_IRQ 24

struct visconti_gpio {
	void __iomem *base;
	spinlock_t lock; /* protect gpio register */
	struct gpio_chip gpio_chip;
	struct irq_chip irq_chip;
};

static int visconti_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct visconti_gpio *priv = gpiochip_get_data(gc);
	u32 offset = irqd_to_hwirq(d);
	u32 bit = BIT(offset);
	u32 intc_type = IRQ_TYPE_EDGE_RISING;
	u32 intmode, odata;
	int ret = 0;
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	odata = readl(priv->base + GPIO_ODATA);
	intmode = readl(priv->base + GPIO_INTMODE);

	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
		odata &= ~bit;
		intmode &= ~bit;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		odata |= bit;
		intmode &= ~bit;
		break;
	case IRQ_TYPE_EDGE_BOTH:
		intmode |= bit;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		intc_type = IRQ_TYPE_LEVEL_HIGH;
		odata &= ~bit;
		intmode &= ~bit;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		intc_type = IRQ_TYPE_LEVEL_HIGH;
		odata |= bit;
		intmode &= ~bit;
		break;
	default:
		ret = -EINVAL;
		goto err;
	}

	writel(odata, priv->base + GPIO_ODATA);
	writel(intmode, priv->base + GPIO_INTMODE);
	irq_set_irq_type(offset, intc_type);

	ret = irq_chip_set_type_parent(d, type);
err:
	spin_unlock_irqrestore(&priv->lock, flags);
	return ret;
}

static int visconti_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
					       unsigned int child,
					       unsigned int child_type,
					       unsigned int *parent,
					       unsigned int *parent_type)
{
	/* Interrupts 0..15 mapped to interrupts 24..39 on the GIC */
	if (child < 16) {
		/* All these interrupts are level high in the CPU */
		*parent_type = IRQ_TYPE_LEVEL_HIGH;
		*parent = child + BASE_HW_IRQ;
		return 0;
	}
	return -EINVAL;
}

static void *visconti_gpio_populate_parent_fwspec(struct gpio_chip *chip,
						  unsigned int parent_hwirq,
						  unsigned int parent_type)
{
	struct irq_fwspec *fwspec;

	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
	if (!fwspec)
		return NULL;

	fwspec->fwnode = chip->irq.parent_domain->fwnode;
	fwspec->param_count = 3;
	fwspec->param[0] = 0;
	fwspec->param[1] = parent_hwirq;
	fwspec->param[2] = parent_type;

	return fwspec;
}

static int visconti_gpio_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct visconti_gpio *priv;
	struct irq_chip *irq_chip;
	struct gpio_irq_chip *girq;
	struct irq_domain *parent;
	struct device_node *irq_parent;
	struct fwnode_handle *fwnode;
	int ret;

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

	spin_lock_init(&priv->lock);

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

	irq_parent = of_irq_find_parent(dev->of_node);
	if (!irq_parent) {
		dev_err(dev, "No IRQ parent node\n");
		return -ENODEV;
	}

	parent = irq_find_host(irq_parent);
	if (!parent) {
		dev_err(dev, "No IRQ parent domain\n");
		return -ENODEV;
	}

	fwnode = of_node_to_fwnode(irq_parent);
	of_node_put(irq_parent);

	ret = bgpio_init(&priv->gpio_chip, dev, 4,
			 priv->base + GPIO_IDATA,
			 priv->base + GPIO_OSET,
			 priv->base + GPIO_OCLR,
			 priv->base + GPIO_DIR,
			 NULL,
			 0);
	if (ret) {
		dev_err(dev, "unable to init generic GPIO\n");
		return ret;
	}

	irq_chip = &priv->irq_chip;
	irq_chip->name = dev_name(dev);
	irq_chip->irq_mask = irq_chip_mask_parent;
	irq_chip->irq_unmask = irq_chip_unmask_parent;
	irq_chip->irq_eoi = irq_chip_eoi_parent;
	irq_chip->irq_set_type = visconti_gpio_irq_set_type;
	irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND;

	girq = &priv->gpio_chip.irq;
	girq->chip = irq_chip;
	girq->fwnode = fwnode;
	girq->parent_domain = parent;
	girq->child_to_parent_hwirq = visconti_gpio_child_to_parent_hwirq;
	girq->populate_parent_alloc_arg = visconti_gpio_populate_parent_fwspec;
	girq->default_type = IRQ_TYPE_NONE;
	girq->handler = handle_level_irq;

	return devm_gpiochip_add_data(dev, &priv->gpio_chip, priv);
}

static const struct of_device_id visconti_gpio_of_match[] = {
	{ .compatible = "toshiba,gpio-tmpv7708", },
	{ /* end of table */ }
};
MODULE_DEVICE_TABLE(of, visconti_gpio_of_match);

static struct platform_driver visconti_gpio_driver = {
	.probe		= visconti_gpio_probe,
	.driver		= {
		.name	= "visconti_gpio",
		.of_match_table = of_match_ptr(visconti_gpio_of_match),
	}
};
module_platform_driver(visconti_gpio_driver);

MODULE_AUTHOR("Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>");
MODULE_DESCRIPTION("Toshiba Visconti GPIO Driver");
MODULE_LICENSE("GPL v2");
