/*
 * SPEAr platform PLGPIO driver
 *
 * Copyright (C) 2012 ST Microelectronics
 * Viresh Kumar <viresh.kumar@linaro.org>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/spinlock.h>

#define MAX_GPIO_PER_REG		32
#define PIN_OFFSET(pin)			(pin % MAX_GPIO_PER_REG)
#define REG_OFFSET(base, reg, pin)	(base + reg + (pin / MAX_GPIO_PER_REG) \
							* sizeof(int *))

/*
 * plgpio pins in all machines are not one to one mapped, bitwise with registers
 * bits. These set of macros define register masks for which below functions
 * (pin_to_offset and offset_to_pin) are required to be called.
 */
#define PTO_ENB_REG		0x001
#define PTO_WDATA_REG		0x002
#define PTO_DIR_REG		0x004
#define PTO_IE_REG		0x008
#define PTO_RDATA_REG		0x010
#define PTO_MIS_REG		0x020

struct plgpio_regs {
	u32 enb;		/* enable register */
	u32 wdata;		/* write data register */
	u32 dir;		/* direction set register */
	u32 rdata;		/* read data register */
	u32 ie;			/* interrupt enable register */
	u32 mis;		/* mask interrupt status register */
	u32 eit;		/* edge interrupt type */
};

/*
 * struct plgpio: plgpio driver specific structure
 *
 * lock: lock for guarding gpio registers
 * base: base address of plgpio block
 * chip: gpio framework specific chip information structure
 * p2o: function ptr for pin to offset conversion. This is required only for
 *	machines where mapping b/w pin and offset is not 1-to-1.
 * o2p: function ptr for offset to pin conversion. This is required only for
 *	machines where mapping b/w pin and offset is not 1-to-1.
 * p2o_regs: mask of registers for which p2o and o2p are applicable
 * regs: register offsets
 * csave_regs: context save registers for standby/sleep/hibernate cases
 */
struct plgpio {
	spinlock_t		lock;
	void __iomem		*base;
	struct clk		*clk;
	struct gpio_chip	chip;
	int			(*p2o)(int pin);	/* pin_to_offset */
	int			(*o2p)(int offset);	/* offset_to_pin */
	u32			p2o_regs;
	struct plgpio_regs	regs;
#ifdef CONFIG_PM_SLEEP
	struct plgpio_regs	*csave_regs;
#endif
};

/* register manipulation inline functions */
static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg)
{
	u32 offset = PIN_OFFSET(pin);
	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
	u32 val = readl_relaxed(reg_off);

	return !!(val & (1 << offset));
}

static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg)
{
	u32 offset = PIN_OFFSET(pin);
	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
	u32 val = readl_relaxed(reg_off);

	writel_relaxed(val | (1 << offset), reg_off);
}

static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg)
{
	u32 offset = PIN_OFFSET(pin);
	void __iomem *reg_off = REG_OFFSET(base, reg, pin);
	u32 val = readl_relaxed(reg_off);

	writel_relaxed(val & ~(1 << offset), reg_off);
}

/* gpio framework specific routines */
static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
	struct plgpio *plgpio = gpiochip_get_data(chip);
	unsigned long flags;

	/* get correct offset for "offset" pin */
	if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) {
		offset = plgpio->p2o(offset);
		if (offset == -1)
			return -EINVAL;
	}

	spin_lock_irqsave(&plgpio->lock, flags);
	plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir);
	spin_unlock_irqrestore(&plgpio->lock, flags);

	return 0;
}

static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset,
		int value)
{
	struct plgpio *plgpio = gpiochip_get_data(chip);
	unsigned long flags;
	unsigned dir_offset = offset, wdata_offset = offset, tmp;

	/* get correct offset for "offset" pin */
	if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) {
		tmp = plgpio->p2o(offset);
		if (tmp == -1)
			return -EINVAL;

		if (plgpio->p2o_regs & PTO_DIR_REG)
			dir_offset = tmp;
		if (plgpio->p2o_regs & PTO_WDATA_REG)
			wdata_offset = tmp;
	}

	spin_lock_irqsave(&plgpio->lock, flags);
	if (value)
		plgpio_reg_set(plgpio->base, wdata_offset,
				plgpio->regs.wdata);
	else
		plgpio_reg_reset(plgpio->base, wdata_offset,
				plgpio->regs.wdata);

	plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir);
	spin_unlock_irqrestore(&plgpio->lock, flags);

	return 0;
}

static int plgpio_get_value(struct gpio_chip *chip, unsigned offset)
{
	struct plgpio *plgpio = gpiochip_get_data(chip);

	if (offset >= chip->ngpio)
		return -EINVAL;

	/* get correct offset for "offset" pin */
	if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) {
		offset = plgpio->p2o(offset);
		if (offset == -1)
			return -EINVAL;
	}

	return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata);
}

static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
{
	struct plgpio *plgpio = gpiochip_get_data(chip);

	if (offset >= chip->ngpio)
		return;

	/* get correct offset for "offset" pin */
	if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) {
		offset = plgpio->p2o(offset);
		if (offset == -1)
			return;
	}

	if (value)
		plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata);
	else
		plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata);
}

static int plgpio_request(struct gpio_chip *chip, unsigned offset)
{
	struct plgpio *plgpio = gpiochip_get_data(chip);
	int gpio = chip->base + offset;
	unsigned long flags;
	int ret = 0;

	if (offset >= chip->ngpio)
		return -EINVAL;

	ret = pinctrl_request_gpio(gpio);
	if (ret)
		return ret;

	if (!IS_ERR(plgpio->clk)) {
		ret = clk_enable(plgpio->clk);
		if (ret)
			goto err0;
	}

	if (plgpio->regs.enb == -1)
		return 0;

	/*
	 * put gpio in IN mode before enabling it. This make enabling gpio safe
	 */
	ret = plgpio_direction_input(chip, offset);
	if (ret)
		goto err1;

	/* get correct offset for "offset" pin */
	if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
		offset = plgpio->p2o(offset);
		if (offset == -1) {
			ret = -EINVAL;
			goto err1;
		}
	}

	spin_lock_irqsave(&plgpio->lock, flags);
	plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb);
	spin_unlock_irqrestore(&plgpio->lock, flags);
	return 0;

err1:
	if (!IS_ERR(plgpio->clk))
		clk_disable(plgpio->clk);
err0:
	pinctrl_free_gpio(gpio);
	return ret;
}

static void plgpio_free(struct gpio_chip *chip, unsigned offset)
{
	struct plgpio *plgpio = gpiochip_get_data(chip);
	int gpio = chip->base + offset;
	unsigned long flags;

	if (offset >= chip->ngpio)
		return;

	if (plgpio->regs.enb == -1)
		goto disable_clk;

	/* get correct offset for "offset" pin */
	if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) {
		offset = plgpio->p2o(offset);
		if (offset == -1)
			return;
	}

	spin_lock_irqsave(&plgpio->lock, flags);
	plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb);
	spin_unlock_irqrestore(&plgpio->lock, flags);

disable_clk:
	if (!IS_ERR(plgpio->clk))
		clk_disable(plgpio->clk);

	pinctrl_free_gpio(gpio);
}

/* PLGPIO IRQ */
static void plgpio_irq_disable(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct plgpio *plgpio = gpiochip_get_data(gc);
	int offset = d->hwirq;
	unsigned long flags;

	/* get correct offset for "offset" pin */
	if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
		offset = plgpio->p2o(offset);
		if (offset == -1)
			return;
	}

	spin_lock_irqsave(&plgpio->lock, flags);
	plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie);
	spin_unlock_irqrestore(&plgpio->lock, flags);
}

static void plgpio_irq_enable(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct plgpio *plgpio = gpiochip_get_data(gc);
	int offset = d->hwirq;
	unsigned long flags;

	/* get correct offset for "offset" pin */
	if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) {
		offset = plgpio->p2o(offset);
		if (offset == -1)
			return;
	}

	spin_lock_irqsave(&plgpio->lock, flags);
	plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie);
	spin_unlock_irqrestore(&plgpio->lock, flags);
}

static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct plgpio *plgpio = gpiochip_get_data(gc);
	int offset = d->hwirq;
	void __iomem *reg_off;
	unsigned int supported_type = 0, val;

	if (offset >= plgpio->chip.ngpio)
		return -EINVAL;

	if (plgpio->regs.eit == -1)
		supported_type = IRQ_TYPE_LEVEL_HIGH;
	else
		supported_type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;

	if (!(trigger & supported_type))
		return -EINVAL;

	if (plgpio->regs.eit == -1)
		return 0;

	reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset);
	val = readl_relaxed(reg_off);

	offset = PIN_OFFSET(offset);
	if (trigger & IRQ_TYPE_EDGE_RISING)
		writel_relaxed(val | (1 << offset), reg_off);
	else
		writel_relaxed(val & ~(1 << offset), reg_off);

	return 0;
}

static struct irq_chip plgpio_irqchip = {
	.name		= "PLGPIO",
	.irq_enable	= plgpio_irq_enable,
	.irq_disable	= plgpio_irq_disable,
	.irq_set_type	= plgpio_irq_set_type,
};

static void plgpio_irq_handler(struct irq_desc *desc)
{
	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
	struct plgpio *plgpio = gpiochip_get_data(gc);
	struct irq_chip *irqchip = irq_desc_get_chip(desc);
	int regs_count, count, pin, offset, i = 0;
	unsigned long pending;

	count = plgpio->chip.ngpio;
	regs_count = DIV_ROUND_UP(count, MAX_GPIO_PER_REG);

	chained_irq_enter(irqchip, desc);
	/* check all plgpio MIS registers for a possible interrupt */
	for (; i < regs_count; i++) {
		pending = readl_relaxed(plgpio->base + plgpio->regs.mis +
				i * sizeof(int *));
		if (!pending)
			continue;

		/* clear interrupts */
		writel_relaxed(~pending, plgpio->base + plgpio->regs.mis +
				i * sizeof(int *));
		/*
		 * clear extra bits in last register having gpios < MAX/REG
		 * ex: Suppose there are max 102 plgpios. then last register
		 * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits
		 * so, we must not take other 28 bits into consideration for
		 * checking interrupt. so clear those bits.
		 */
		count = count - i * MAX_GPIO_PER_REG;
		if (count < MAX_GPIO_PER_REG)
			pending &= (1 << count) - 1;

		for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) {
			/* get correct pin for "offset" */
			if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) {
				pin = plgpio->o2p(offset);
				if (pin == -1)
					continue;
			} else
				pin = offset;

			/* get correct irq line number */
			pin = i * MAX_GPIO_PER_REG + pin;
			generic_handle_irq(
				irq_find_mapping(gc->irqdomain, pin));
		}
	}
	chained_irq_exit(irqchip, desc);
}

/*
 * pin to offset and offset to pin converter functions
 *
 * In spear310 there is inconsistency among bit positions in plgpio regiseters,
 * for different plgpio pins. For example: for pin 27, bit offset is 23, pin
 * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1
 */
static int spear310_p2o(int pin)
{
	int offset = pin;

	if (pin <= 27)
		offset += 4;
	else if (pin <= 33)
		offset = -1;
	else if (pin <= 97)
		offset -= 2;
	else if (pin <= 101)
		offset = 101 - pin;
	else
		offset = -1;

	return offset;
}

static int spear310_o2p(int offset)
{
	if (offset <= 3)
		return 101 - offset;
	else if (offset <= 31)
		return offset - 4;
	else
		return offset + 2;
}

static int plgpio_probe_dt(struct platform_device *pdev, struct plgpio *plgpio)
{
	struct device_node *np = pdev->dev.of_node;
	int ret = -EINVAL;
	u32 val;

	if (of_machine_is_compatible("st,spear310")) {
		plgpio->p2o = spear310_p2o;
		plgpio->o2p = spear310_o2p;
		plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG |
			PTO_RDATA_REG | PTO_MIS_REG;
	}

	if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) {
		plgpio->chip.ngpio = val;
	} else {
		dev_err(&pdev->dev, "DT: Invalid ngpio field\n");
		goto end;
	}

	if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val))
		plgpio->regs.enb = val;
	else
		plgpio->regs.enb = -1;

	if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) {
		plgpio->regs.wdata = val;
	} else {
		dev_err(&pdev->dev, "DT: Invalid wdata reg\n");
		goto end;
	}

	if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) {
		plgpio->regs.dir = val;
	} else {
		dev_err(&pdev->dev, "DT: Invalid dir reg\n");
		goto end;
	}

	if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) {
		plgpio->regs.ie = val;
	} else {
		dev_err(&pdev->dev, "DT: Invalid ie reg\n");
		goto end;
	}

	if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) {
		plgpio->regs.rdata = val;
	} else {
		dev_err(&pdev->dev, "DT: Invalid rdata reg\n");
		goto end;
	}

	if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) {
		plgpio->regs.mis = val;
	} else {
		dev_err(&pdev->dev, "DT: Invalid mis reg\n");
		goto end;
	}

	if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val))
		plgpio->regs.eit = val;
	else
		plgpio->regs.eit = -1;

	return 0;

end:
	return ret;
}
static int plgpio_probe(struct platform_device *pdev)
{
	struct plgpio *plgpio;
	struct resource *res;
	int ret, irq;

	plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
	if (!plgpio) {
		dev_err(&pdev->dev, "memory allocation fail\n");
		return -ENOMEM;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	plgpio->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(plgpio->base))
		return PTR_ERR(plgpio->base);

	ret = plgpio_probe_dt(pdev, plgpio);
	if (ret) {
		dev_err(&pdev->dev, "DT probe failed\n");
		return ret;
	}

	plgpio->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(plgpio->clk))
		dev_warn(&pdev->dev, "clk_get() failed, work without it\n");

#ifdef CONFIG_PM_SLEEP
	plgpio->csave_regs = devm_kzalloc(&pdev->dev,
			sizeof(*plgpio->csave_regs) *
			DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG),
			GFP_KERNEL);
	if (!plgpio->csave_regs) {
		dev_err(&pdev->dev, "csave registers memory allocation fail\n");
		return -ENOMEM;
	}
#endif

	platform_set_drvdata(pdev, plgpio);
	spin_lock_init(&plgpio->lock);

	plgpio->chip.base = -1;
	plgpio->chip.request = plgpio_request;
	plgpio->chip.free = plgpio_free;
	plgpio->chip.direction_input = plgpio_direction_input;
	plgpio->chip.direction_output = plgpio_direction_output;
	plgpio->chip.get = plgpio_get_value;
	plgpio->chip.set = plgpio_set_value;
	plgpio->chip.label = dev_name(&pdev->dev);
	plgpio->chip.parent = &pdev->dev;
	plgpio->chip.owner = THIS_MODULE;
	plgpio->chip.of_node = pdev->dev.of_node;

	if (!IS_ERR(plgpio->clk)) {
		ret = clk_prepare(plgpio->clk);
		if (ret) {
			dev_err(&pdev->dev, "clk prepare failed\n");
			return ret;
		}
	}

	ret = gpiochip_add_data(&plgpio->chip, plgpio);
	if (ret) {
		dev_err(&pdev->dev, "unable to add gpio chip\n");
		goto unprepare_clk;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_info(&pdev->dev, "PLGPIO registered without IRQs\n");
		return 0;
	}

	ret = gpiochip_irqchip_add(&plgpio->chip,
				   &plgpio_irqchip,
				   0,
				   handle_simple_irq,
				   IRQ_TYPE_NONE);
	if (ret) {
		dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n");
		goto remove_gpiochip;
	}

	gpiochip_set_chained_irqchip(&plgpio->chip,
				     &plgpio_irqchip,
				     irq,
				     plgpio_irq_handler);

	dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");

	return 0;

remove_gpiochip:
	dev_info(&pdev->dev, "Remove gpiochip\n");
	gpiochip_remove(&plgpio->chip);
unprepare_clk:
	if (!IS_ERR(plgpio->clk))
		clk_unprepare(plgpio->clk);

	return ret;
}

#ifdef CONFIG_PM_SLEEP
static int plgpio_suspend(struct device *dev)
{
	struct plgpio *plgpio = dev_get_drvdata(dev);
	int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG);
	void __iomem *off;

	for (i = 0; i < reg_count; i++) {
		off = plgpio->base + i * sizeof(int *);

		if (plgpio->regs.enb != -1)
			plgpio->csave_regs[i].enb =
				readl_relaxed(plgpio->regs.enb + off);
		if (plgpio->regs.eit != -1)
			plgpio->csave_regs[i].eit =
				readl_relaxed(plgpio->regs.eit + off);
		plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata +
				off);
		plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir +
				off);
		plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off);
	}

	return 0;
}

/*
 * This is used to correct the values in end registers. End registers contain
 * extra bits that might be used for other purpose in platform. So, we shouldn't
 * overwrite these bits. This macro, reads given register again, preserves other
 * bit values (non-plgpio bits), and retain captured value (plgpio bits).
 */
#define plgpio_prepare_reg(__reg, _off, _mask, _tmp)		\
{								\
	_tmp = readl_relaxed(plgpio->regs.__reg + _off);		\
	_tmp &= ~_mask;						\
	plgpio->csave_regs[i].__reg =				\
		_tmp | (plgpio->csave_regs[i].__reg & _mask);	\
}

static int plgpio_resume(struct device *dev)
{
	struct plgpio *plgpio = dev_get_drvdata(dev);
	int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG);
	void __iomem *off;
	u32 mask, tmp;

	for (i = 0; i < reg_count; i++) {
		off = plgpio->base + i * sizeof(int *);

		if (i == reg_count - 1) {
			mask = (1 << (plgpio->chip.ngpio - i *
						MAX_GPIO_PER_REG)) - 1;

			if (plgpio->regs.enb != -1)
				plgpio_prepare_reg(enb, off, mask, tmp);

			if (plgpio->regs.eit != -1)
				plgpio_prepare_reg(eit, off, mask, tmp);

			plgpio_prepare_reg(wdata, off, mask, tmp);
			plgpio_prepare_reg(dir, off, mask, tmp);
			plgpio_prepare_reg(ie, off, mask, tmp);
		}

		writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata +
				off);
		writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir +
				off);

		if (plgpio->regs.eit != -1)
			writel_relaxed(plgpio->csave_regs[i].eit,
					plgpio->regs.eit + off);

		writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off);

		if (plgpio->regs.enb != -1)
			writel_relaxed(plgpio->csave_regs[i].enb,
					plgpio->regs.enb + off);
	}

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(plgpio_dev_pm_ops, plgpio_suspend, plgpio_resume);

static const struct of_device_id plgpio_of_match[] = {
	{ .compatible = "st,spear-plgpio" },
	{}
};

static struct platform_driver plgpio_driver = {
	.probe = plgpio_probe,
	.driver = {
		.name = "spear-plgpio",
		.pm = &plgpio_dev_pm_ops,
		.of_match_table = plgpio_of_match,
	},
};

static int __init plgpio_init(void)
{
	return platform_driver_register(&plgpio_driver);
}
subsys_initcall(plgpio_init);
