/*
 * Toumaz Xenif TZ1090 PDC GPIO handling.
 *
 * Copyright (C) 2012-2013 Imagination Technologies Ltd.
 *
 * 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.
 */

#include <linux/bitops.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/syscore_ops.h>
#include <asm/global_lock.h>

/* Register offsets from SOC_GPIO_CONTROL0 */
#define REG_SOC_GPIO_CONTROL0	0x00
#define REG_SOC_GPIO_CONTROL1	0x04
#define REG_SOC_GPIO_CONTROL2	0x08
#define REG_SOC_GPIO_CONTROL3	0x0c
#define REG_SOC_GPIO_STATUS	0x80

/* PDC GPIOs go after normal GPIOs */
#define GPIO_PDC_BASE		90
#define GPIO_PDC_NGPIO		7

/* Out of PDC gpios, only syswakes have irqs */
#define GPIO_PDC_IRQ_FIRST	2
#define GPIO_PDC_NIRQ		3

/**
 * struct tz1090_pdc_gpio - GPIO bank private data
 * @chip:	Generic GPIO chip for GPIO bank
 * @reg:	Base of registers, offset for this GPIO bank
 * @irq:	IRQ numbers for Syswake GPIOs
 *
 * This is the main private data for the PDC GPIO driver. It encapsulates a
 * gpio_chip, and the callbacks for the gpio_chip can access the private data
 * with the to_pdc() macro below.
 */
struct tz1090_pdc_gpio {
	struct gpio_chip chip;
	void __iomem *reg;
	int irq[GPIO_PDC_NIRQ];
};
#define to_pdc(c)	container_of(c, struct tz1090_pdc_gpio, chip)

/* Register accesses into the PDC MMIO area */

static inline void pdc_write(struct tz1090_pdc_gpio *priv, unsigned int reg_offs,
		      unsigned int data)
{
	writel(data, priv->reg + reg_offs);
}

static inline unsigned int pdc_read(struct tz1090_pdc_gpio *priv,
			     unsigned int reg_offs)
{
	return readl(priv->reg + reg_offs);
}

/* Generic GPIO interface */

static int tz1090_pdc_gpio_direction_input(struct gpio_chip *chip,
					   unsigned int offset)
{
	struct tz1090_pdc_gpio *priv = to_pdc(chip);
	u32 value;
	int lstat;

	__global_lock2(lstat);
	value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
	value |= BIT(offset);
	pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
	__global_unlock2(lstat);

	return 0;
}

static int tz1090_pdc_gpio_direction_output(struct gpio_chip *chip,
					    unsigned int offset,
					    int output_value)
{
	struct tz1090_pdc_gpio *priv = to_pdc(chip);
	u32 value;
	int lstat;

	__global_lock2(lstat);
	/* EXT_POWER doesn't seem to have an output value bit */
	if (offset < 6) {
		value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
		if (output_value)
			value |= BIT(offset);
		else
			value &= ~BIT(offset);
		pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
	}

	value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
	value &= ~BIT(offset);
	pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
	__global_unlock2(lstat);

	return 0;
}

static int tz1090_pdc_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	struct tz1090_pdc_gpio *priv = to_pdc(chip);
	return pdc_read(priv, REG_SOC_GPIO_STATUS) & BIT(offset);
}

static void tz1090_pdc_gpio_set(struct gpio_chip *chip, unsigned int offset,
				int output_value)
{
	struct tz1090_pdc_gpio *priv = to_pdc(chip);
	u32 value;
	int lstat;

	/* EXT_POWER doesn't seem to have an output value bit */
	if (offset >= 6)
		return;

	__global_lock2(lstat);
	value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
	if (output_value)
		value |= BIT(offset);
	else
		value &= ~BIT(offset);
	pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
	__global_unlock2(lstat);
}

static int tz1090_pdc_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
{
	struct tz1090_pdc_gpio *priv = to_pdc(chip);
	unsigned int syswake = offset - GPIO_PDC_IRQ_FIRST;
	int irq;

	/* only syswakes have irqs */
	if (syswake >= GPIO_PDC_NIRQ)
		return -EINVAL;

	irq = priv->irq[syswake];
	if (!irq)
		return -EINVAL;

	return irq;
}

static int tz1090_pdc_gpio_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct resource *res_regs;
	struct tz1090_pdc_gpio *priv;
	unsigned int i;

	if (!np) {
		dev_err(&pdev->dev, "must be instantiated via devicetree\n");
		return -ENOENT;
	}

	res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res_regs) {
		dev_err(&pdev->dev, "cannot find registers resource\n");
		return -ENOENT;
	}

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "unable to allocate driver data\n");
		return -ENOMEM;
	}

	/* Ioremap the registers */
	priv->reg = devm_ioremap(&pdev->dev, res_regs->start,
				 resource_size(res_regs));
	if (!priv->reg) {
		dev_err(&pdev->dev, "unable to ioremap registers\n");
		return -ENOMEM;
	}

	/* Set up GPIO chip */
	priv->chip.label		= "tz1090-pdc-gpio";
	priv->chip.dev			= &pdev->dev;
	priv->chip.direction_input	= tz1090_pdc_gpio_direction_input;
	priv->chip.direction_output	= tz1090_pdc_gpio_direction_output;
	priv->chip.get			= tz1090_pdc_gpio_get;
	priv->chip.set			= tz1090_pdc_gpio_set;
	priv->chip.free			= gpiochip_generic_free;
	priv->chip.request		= gpiochip_generic_request;
	priv->chip.to_irq		= tz1090_pdc_gpio_to_irq;
	priv->chip.of_node		= np;

	/* GPIO numbering */
	priv->chip.base			= GPIO_PDC_BASE;
	priv->chip.ngpio		= GPIO_PDC_NGPIO;

	/* Map the syswake irqs */
	for (i = 0; i < GPIO_PDC_NIRQ; ++i)
		priv->irq[i] = irq_of_parse_and_map(np, i);

	/* Add the GPIO bank */
	gpiochip_add(&priv->chip);

	return 0;
}

static struct of_device_id tz1090_pdc_gpio_of_match[] = {
	{ .compatible = "img,tz1090-pdc-gpio" },
	{ },
};

static struct platform_driver tz1090_pdc_gpio_driver = {
	.driver = {
		.name		= "tz1090-pdc-gpio",
		.of_match_table	= tz1090_pdc_gpio_of_match,
	},
	.probe		= tz1090_pdc_gpio_probe,
};

static int __init tz1090_pdc_gpio_init(void)
{
	return platform_driver_register(&tz1090_pdc_gpio_driver);
}
subsys_initcall(tz1090_pdc_gpio_init);
