/*
 * Copyright (C) 2014-2015 Broadcom Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * This file contains the Broadcom Cygnus GPIO driver that supports 3
 * GPIO controllers on Cygnus including the ASIU GPIO controller, the
 * chipCommonG GPIO controller, and the always-on GPIO controller. Basic
 * PINCONF such as bias pull up/down, and drive strength are also supported
 * in this driver.
 *
 * Pins from the ASIU GPIO can be individually muxed to GPIO function,
 * through the interaction with the Cygnus IOMUX controller
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/ioport.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>

#include "../pinctrl-utils.h"

#define CYGNUS_GPIO_DATA_IN_OFFSET   0x00
#define CYGNUS_GPIO_DATA_OUT_OFFSET  0x04
#define CYGNUS_GPIO_OUT_EN_OFFSET    0x08
#define CYGNUS_GPIO_INT_TYPE_OFFSET  0x0c
#define CYGNUS_GPIO_INT_DE_OFFSET    0x10
#define CYGNUS_GPIO_INT_EDGE_OFFSET  0x14
#define CYGNUS_GPIO_INT_MSK_OFFSET   0x18
#define CYGNUS_GPIO_INT_STAT_OFFSET  0x1c
#define CYGNUS_GPIO_INT_MSTAT_OFFSET 0x20
#define CYGNUS_GPIO_INT_CLR_OFFSET   0x24
#define CYGNUS_GPIO_PAD_RES_OFFSET   0x34
#define CYGNUS_GPIO_RES_EN_OFFSET    0x38

/* drive strength control for ASIU GPIO */
#define CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58

/* drive strength control for CCM/CRMU (AON) GPIO */
#define CYGNUS_GPIO_DRV0_CTRL_OFFSET  0x00

#define GPIO_BANK_SIZE 0x200
#define NGPIOS_PER_BANK 32
#define GPIO_BANK(pin) ((pin) / NGPIOS_PER_BANK)

#define CYGNUS_GPIO_REG(pin, reg) (GPIO_BANK(pin) * GPIO_BANK_SIZE + (reg))
#define CYGNUS_GPIO_SHIFT(pin) ((pin) % NGPIOS_PER_BANK)

#define GPIO_DRV_STRENGTH_BIT_SHIFT  20
#define GPIO_DRV_STRENGTH_BITS       3
#define GPIO_DRV_STRENGTH_BIT_MASK   ((1 << GPIO_DRV_STRENGTH_BITS) - 1)

/*
 * Cygnus GPIO core
 *
 * @dev: pointer to device
 * @base: I/O register base for Cygnus GPIO controller
 * @io_ctrl: I/O register base for certain type of Cygnus GPIO controller that
 * has the PINCONF support implemented outside of the GPIO block
 * @lock: lock to protect access to I/O registers
 * @gc: GPIO chip
 * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs
 * @pinmux_is_supported: flag to indicate this GPIO controller contains pins
 * that can be individually muxed to GPIO
 * @pctl: pointer to pinctrl_dev
 * @pctldesc: pinctrl descriptor
 */
struct cygnus_gpio {
	struct device *dev;

	void __iomem *base;
	void __iomem *io_ctrl;

	spinlock_t lock;

	struct gpio_chip gc;
	unsigned num_banks;

	bool pinmux_is_supported;

	struct pinctrl_dev *pctl;
	struct pinctrl_desc pctldesc;
};

static inline struct cygnus_gpio *to_cygnus_gpio(struct gpio_chip *gc)
{
	return container_of(gc, struct cygnus_gpio, gc);
}

/*
 * Mapping from PINCONF pins to GPIO pins is 1-to-1
 */
static inline unsigned cygnus_pin_to_gpio(unsigned pin)
{
	return pin;
}

/**
 *  cygnus_set_bit - set or clear one bit (corresponding to the GPIO pin) in a
 *  Cygnus GPIO register
 *
 *  @cygnus_gpio: Cygnus GPIO device
 *  @reg: register offset
 *  @gpio: GPIO pin
 *  @set: set or clear
 */
static inline void cygnus_set_bit(struct cygnus_gpio *chip, unsigned int reg,
				  unsigned gpio, bool set)
{
	unsigned int offset = CYGNUS_GPIO_REG(gpio, reg);
	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
	u32 val;

	val = readl(chip->base + offset);
	if (set)
		val |= BIT(shift);
	else
		val &= ~BIT(shift);
	writel(val, chip->base + offset);
}

static inline bool cygnus_get_bit(struct cygnus_gpio *chip, unsigned int reg,
				  unsigned gpio)
{
	unsigned int offset = CYGNUS_GPIO_REG(gpio, reg);
	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);

	return !!(readl(chip->base + offset) & BIT(shift));
}

static void cygnus_gpio_irq_handler(struct irq_desc *desc)
{
	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
	int i, bit;

	chained_irq_enter(irq_chip, desc);

	/* go through the entire GPIO banks and handle all interrupts */
	for (i = 0; i < chip->num_banks; i++) {
		unsigned long val = readl(chip->base + (i * GPIO_BANK_SIZE) +
					  CYGNUS_GPIO_INT_MSTAT_OFFSET);

		for_each_set_bit(bit, &val, NGPIOS_PER_BANK) {
			unsigned pin = NGPIOS_PER_BANK * i + bit;
			int child_irq = irq_find_mapping(gc->irqdomain, pin);

			/*
			 * Clear the interrupt before invoking the
			 * handler, so we do not leave any window
			 */
			writel(BIT(bit), chip->base + (i * GPIO_BANK_SIZE) +
			       CYGNUS_GPIO_INT_CLR_OFFSET);

			generic_handle_irq(child_irq);
		}
	}

	chained_irq_exit(irq_chip, desc);
}


static void cygnus_gpio_irq_ack(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned gpio = d->hwirq;
	unsigned int offset = CYGNUS_GPIO_REG(gpio,
			CYGNUS_GPIO_INT_CLR_OFFSET);
	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
	u32 val = BIT(shift);

	writel(val, chip->base + offset);
}

/**
 *  cygnus_gpio_irq_set_mask - mask/unmask a GPIO interrupt
 *
 *  @d: IRQ chip data
 *  @unmask: mask/unmask GPIO interrupt
 */
static void cygnus_gpio_irq_set_mask(struct irq_data *d, bool unmask)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned gpio = d->hwirq;

	cygnus_set_bit(chip, CYGNUS_GPIO_INT_MSK_OFFSET, gpio, unmask);
}

static void cygnus_gpio_irq_mask(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned long flags;

	spin_lock_irqsave(&chip->lock, flags);
	cygnus_gpio_irq_set_mask(d, false);
	spin_unlock_irqrestore(&chip->lock, flags);
}

static void cygnus_gpio_irq_unmask(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned long flags;

	spin_lock_irqsave(&chip->lock, flags);
	cygnus_gpio_irq_set_mask(d, true);
	spin_unlock_irqrestore(&chip->lock, flags);
}

static int cygnus_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned gpio = d->hwirq;
	bool level_triggered = false;
	bool dual_edge = false;
	bool rising_or_high = false;
	unsigned long flags;

	switch (type & IRQ_TYPE_SENSE_MASK) {
	case IRQ_TYPE_EDGE_RISING:
		rising_or_high = true;
		break;

	case IRQ_TYPE_EDGE_FALLING:
		break;

	case IRQ_TYPE_EDGE_BOTH:
		dual_edge = true;
		break;

	case IRQ_TYPE_LEVEL_HIGH:
		level_triggered = true;
		rising_or_high = true;
		break;

	case IRQ_TYPE_LEVEL_LOW:
		level_triggered = true;
		break;

	default:
		dev_err(chip->dev, "invalid GPIO IRQ type 0x%x\n",
			type);
		return -EINVAL;
	}

	spin_lock_irqsave(&chip->lock, flags);
	cygnus_set_bit(chip, CYGNUS_GPIO_INT_TYPE_OFFSET, gpio,
		       level_triggered);
	cygnus_set_bit(chip, CYGNUS_GPIO_INT_DE_OFFSET, gpio, dual_edge);
	cygnus_set_bit(chip, CYGNUS_GPIO_INT_EDGE_OFFSET, gpio,
		       rising_or_high);
	spin_unlock_irqrestore(&chip->lock, flags);

	dev_dbg(chip->dev,
		"gpio:%u level_triggered:%d dual_edge:%d rising_or_high:%d\n",
		gpio, level_triggered, dual_edge, rising_or_high);

	return 0;
}

static struct irq_chip cygnus_gpio_irq_chip = {
	.name = "bcm-cygnus-gpio",
	.irq_ack = cygnus_gpio_irq_ack,
	.irq_mask = cygnus_gpio_irq_mask,
	.irq_unmask = cygnus_gpio_irq_unmask,
	.irq_set_type = cygnus_gpio_irq_set_type,
};

/*
 * Request the Cygnus IOMUX pinmux controller to mux individual pins to GPIO
 */
static int cygnus_gpio_request(struct gpio_chip *gc, unsigned offset)
{
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned gpio = gc->base + offset;

	/* not all Cygnus GPIO pins can be muxed individually */
	if (!chip->pinmux_is_supported)
		return 0;

	return pinctrl_request_gpio(gpio);
}

static void cygnus_gpio_free(struct gpio_chip *gc, unsigned offset)
{
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned gpio = gc->base + offset;

	if (!chip->pinmux_is_supported)
		return;

	pinctrl_free_gpio(gpio);
}

static int cygnus_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
{
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned long flags;

	spin_lock_irqsave(&chip->lock, flags);
	cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, false);
	spin_unlock_irqrestore(&chip->lock, flags);

	dev_dbg(chip->dev, "gpio:%u set input\n", gpio);

	return 0;
}

static int cygnus_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
					int val)
{
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned long flags;

	spin_lock_irqsave(&chip->lock, flags);
	cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, true);
	cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
	spin_unlock_irqrestore(&chip->lock, flags);

	dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val);

	return 0;
}

static void cygnus_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
{
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned long flags;

	spin_lock_irqsave(&chip->lock, flags);
	cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
	spin_unlock_irqrestore(&chip->lock, flags);

	dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val);
}

static int cygnus_gpio_get(struct gpio_chip *gc, unsigned gpio)
{
	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
	unsigned int offset = CYGNUS_GPIO_REG(gpio,
					      CYGNUS_GPIO_DATA_IN_OFFSET);
	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);

	return !!(readl(chip->base + offset) & BIT(shift));
}

static int cygnus_get_groups_count(struct pinctrl_dev *pctldev)
{
	return 1;
}

/*
 * Only one group: "gpio_grp", since this local pinctrl device only performs
 * GPIO specific PINCONF configurations
 */
static const char *cygnus_get_group_name(struct pinctrl_dev *pctldev,
					 unsigned selector)
{
	return "gpio_grp";
}

static const struct pinctrl_ops cygnus_pctrl_ops = {
	.get_groups_count = cygnus_get_groups_count,
	.get_group_name = cygnus_get_group_name,
	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
	.dt_free_map = pinctrl_utils_dt_free_map,
};

static int cygnus_gpio_set_pull(struct cygnus_gpio *chip, unsigned gpio,
				bool disable, bool pull_up)
{
	unsigned long flags;

	spin_lock_irqsave(&chip->lock, flags);

	if (disable) {
		cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, false);
	} else {
		cygnus_set_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio,
			       pull_up);
		cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, true);
	}

	spin_unlock_irqrestore(&chip->lock, flags);

	dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);

	return 0;
}

static void cygnus_gpio_get_pull(struct cygnus_gpio *chip, unsigned gpio,
				 bool *disable, bool *pull_up)
{
	unsigned long flags;

	spin_lock_irqsave(&chip->lock, flags);
	*disable = !cygnus_get_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio);
	*pull_up = cygnus_get_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio);
	spin_unlock_irqrestore(&chip->lock, flags);
}

static int cygnus_gpio_set_strength(struct cygnus_gpio *chip, unsigned gpio,
				    unsigned strength)
{
	void __iomem *base;
	unsigned int i, offset, shift;
	u32 val;
	unsigned long flags;

	/* make sure drive strength is supported */
	if (strength < 2 ||  strength > 16 || (strength % 2))
		return -ENOTSUPP;

	if (chip->io_ctrl) {
		base = chip->io_ctrl;
		offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET;
	} else {
		base = chip->base;
		offset = CYGNUS_GPIO_REG(gpio,
					 CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET);
	}

	shift = CYGNUS_GPIO_SHIFT(gpio);

	dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio,
		strength);

	spin_lock_irqsave(&chip->lock, flags);
	strength = (strength / 2) - 1;
	for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
		val = readl(base + offset);
		val &= ~BIT(shift);
		val |= ((strength >> i) & 0x1) << shift;
		writel(val, base + offset);
		offset += 4;
	}
	spin_unlock_irqrestore(&chip->lock, flags);

	return 0;
}

static int cygnus_gpio_get_strength(struct cygnus_gpio *chip, unsigned gpio,
				    u16 *strength)
{
	void __iomem *base;
	unsigned int i, offset, shift;
	u32 val;
	unsigned long flags;

	if (chip->io_ctrl) {
		base = chip->io_ctrl;
		offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET;
	} else {
		base = chip->base;
		offset = CYGNUS_GPIO_REG(gpio,
					 CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET);
	}

	shift = CYGNUS_GPIO_SHIFT(gpio);

	spin_lock_irqsave(&chip->lock, flags);
	*strength = 0;
	for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
		val = readl(base + offset) & BIT(shift);
		val >>= shift;
		*strength += (val << i);
		offset += 4;
	}

	/* convert to mA */
	*strength = (*strength + 1) * 2;
	spin_unlock_irqrestore(&chip->lock, flags);

	return 0;
}

static int cygnus_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
				 unsigned long *config)
{
	struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param = pinconf_to_config_param(*config);
	unsigned gpio = cygnus_pin_to_gpio(pin);
	u16 arg;
	bool disable, pull_up;
	int ret;

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
		if (disable)
			return 0;
		else
			return -EINVAL;

	case PIN_CONFIG_BIAS_PULL_UP:
		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
		if (!disable && pull_up)
			return 0;
		else
			return -EINVAL;

	case PIN_CONFIG_BIAS_PULL_DOWN:
		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
		if (!disable && !pull_up)
			return 0;
		else
			return -EINVAL;

	case PIN_CONFIG_DRIVE_STRENGTH:
		ret = cygnus_gpio_get_strength(chip, gpio, &arg);
		if (ret)
			return ret;
		else
			*config = pinconf_to_config_packed(param, arg);

		return 0;

	default:
		return -ENOTSUPP;
	}

	return -ENOTSUPP;
}

static int cygnus_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
				 unsigned long *configs, unsigned num_configs)
{
	struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param;
	u16 arg;
	unsigned i, gpio = cygnus_pin_to_gpio(pin);
	int ret = -ENOTSUPP;

	for (i = 0; i < num_configs; i++) {
		param = pinconf_to_config_param(configs[i]);
		arg = pinconf_to_config_argument(configs[i]);

		switch (param) {
		case PIN_CONFIG_BIAS_DISABLE:
			ret = cygnus_gpio_set_pull(chip, gpio, true, false);
			if (ret < 0)
				goto out;
			break;

		case PIN_CONFIG_BIAS_PULL_UP:
			ret = cygnus_gpio_set_pull(chip, gpio, false, true);
			if (ret < 0)
				goto out;
			break;

		case PIN_CONFIG_BIAS_PULL_DOWN:
			ret = cygnus_gpio_set_pull(chip, gpio, false, false);
			if (ret < 0)
				goto out;
			break;

		case PIN_CONFIG_DRIVE_STRENGTH:
			ret = cygnus_gpio_set_strength(chip, gpio, arg);
			if (ret < 0)
				goto out;
			break;

		default:
			dev_err(chip->dev, "invalid configuration\n");
			return -ENOTSUPP;
		}
	} /* for each config */

out:
	return ret;
}

static const struct pinconf_ops cygnus_pconf_ops = {
	.is_generic = true,
	.pin_config_get = cygnus_pin_config_get,
	.pin_config_set = cygnus_pin_config_set,
};

/*
 * Map a GPIO in the local gpio_chip pin space to a pin in the Cygnus IOMUX
 * pinctrl pin space
 */
struct cygnus_gpio_pin_range {
	unsigned offset;
	unsigned pin_base;
	unsigned num_pins;
};

#define CYGNUS_PINRANGE(o, p, n) { .offset = o, .pin_base = p, .num_pins = n }

/*
 * Pin mapping table for mapping local GPIO pins to Cygnus IOMUX pinctrl pins
 */
static const struct cygnus_gpio_pin_range cygnus_gpio_pintable[] = {
	CYGNUS_PINRANGE(0, 42, 1),
	CYGNUS_PINRANGE(1, 44, 3),
	CYGNUS_PINRANGE(4, 48, 1),
	CYGNUS_PINRANGE(5, 50, 3),
	CYGNUS_PINRANGE(8, 126, 1),
	CYGNUS_PINRANGE(9, 155, 1),
	CYGNUS_PINRANGE(10, 152, 1),
	CYGNUS_PINRANGE(11, 154, 1),
	CYGNUS_PINRANGE(12, 153, 1),
	CYGNUS_PINRANGE(13, 127, 3),
	CYGNUS_PINRANGE(16, 140, 1),
	CYGNUS_PINRANGE(17, 145, 7),
	CYGNUS_PINRANGE(24, 130, 10),
	CYGNUS_PINRANGE(34, 141, 4),
	CYGNUS_PINRANGE(38, 54, 1),
	CYGNUS_PINRANGE(39, 56, 3),
	CYGNUS_PINRANGE(42, 60, 3),
	CYGNUS_PINRANGE(45, 64, 3),
	CYGNUS_PINRANGE(48, 68, 2),
	CYGNUS_PINRANGE(50, 84, 6),
	CYGNUS_PINRANGE(56, 94, 6),
	CYGNUS_PINRANGE(62, 72, 1),
	CYGNUS_PINRANGE(63, 70, 1),
	CYGNUS_PINRANGE(64, 80, 1),
	CYGNUS_PINRANGE(65, 74, 3),
	CYGNUS_PINRANGE(68, 78, 1),
	CYGNUS_PINRANGE(69, 82, 1),
	CYGNUS_PINRANGE(70, 156, 17),
	CYGNUS_PINRANGE(87, 104, 12),
	CYGNUS_PINRANGE(99, 102, 2),
	CYGNUS_PINRANGE(101, 90, 4),
	CYGNUS_PINRANGE(105, 116, 6),
	CYGNUS_PINRANGE(111, 100, 2),
	CYGNUS_PINRANGE(113, 122, 4),
	CYGNUS_PINRANGE(123, 11, 1),
	CYGNUS_PINRANGE(124, 38, 4),
	CYGNUS_PINRANGE(128, 43, 1),
	CYGNUS_PINRANGE(129, 47, 1),
	CYGNUS_PINRANGE(130, 49, 1),
	CYGNUS_PINRANGE(131, 53, 1),
	CYGNUS_PINRANGE(132, 55, 1),
	CYGNUS_PINRANGE(133, 59, 1),
	CYGNUS_PINRANGE(134, 63, 1),
	CYGNUS_PINRANGE(135, 67, 1),
	CYGNUS_PINRANGE(136, 71, 1),
	CYGNUS_PINRANGE(137, 73, 1),
	CYGNUS_PINRANGE(138, 77, 1),
	CYGNUS_PINRANGE(139, 79, 1),
	CYGNUS_PINRANGE(140, 81, 1),
	CYGNUS_PINRANGE(141, 83, 1),
	CYGNUS_PINRANGE(142, 10, 1)
};

/*
 * The Cygnus IOMUX controller mainly supports group based mux configuration,
 * but certain pins can be muxed to GPIO individually. Only the ASIU GPIO
 * controller can support this, so it's an optional configuration
 *
 * Return -ENODEV means no support and that's fine
 */
static int cygnus_gpio_pinmux_add_range(struct cygnus_gpio *chip)
{
	struct device_node *node = chip->dev->of_node;
	struct device_node *pinmux_node;
	struct platform_device *pinmux_pdev;
	struct gpio_chip *gc = &chip->gc;
	int i, ret = 0;

	/* parse DT to find the phandle to the pinmux controller */
	pinmux_node = of_parse_phandle(node, "pinmux", 0);
	if (!pinmux_node)
		return -ENODEV;

	pinmux_pdev = of_find_device_by_node(pinmux_node);
	/* no longer need the pinmux node */
	of_node_put(pinmux_node);
	if (!pinmux_pdev) {
		dev_err(chip->dev, "failed to get pinmux device\n");
		return -EINVAL;
	}

	/* now need to create the mapping between local GPIO and PINMUX pins */
	for (i = 0; i < ARRAY_SIZE(cygnus_gpio_pintable); i++) {
		ret = gpiochip_add_pin_range(gc, dev_name(&pinmux_pdev->dev),
					     cygnus_gpio_pintable[i].offset,
					     cygnus_gpio_pintable[i].pin_base,
					     cygnus_gpio_pintable[i].num_pins);
		if (ret) {
			dev_err(chip->dev, "unable to add GPIO pin range\n");
			goto err_put_device;
		}
	}

	chip->pinmux_is_supported = true;

	/* no need for pinmux_pdev device reference anymore */
	put_device(&pinmux_pdev->dev);
	return 0;

err_put_device:
	put_device(&pinmux_pdev->dev);
	gpiochip_remove_pin_ranges(gc);
	return ret;
}

/*
 * Cygnus GPIO controller supports some PINCONF related configurations such as
 * pull up, pull down, and drive strength, when the pin is configured to GPIO
 *
 * Here a local pinctrl device is created with simple 1-to-1 pin mapping to the
 * local GPIO pins
 */
static int cygnus_gpio_register_pinconf(struct cygnus_gpio *chip)
{
	struct pinctrl_desc *pctldesc = &chip->pctldesc;
	struct pinctrl_pin_desc *pins;
	struct gpio_chip *gc = &chip->gc;
	int i;

	pins = devm_kcalloc(chip->dev, gc->ngpio, sizeof(*pins), GFP_KERNEL);
	if (!pins)
		return -ENOMEM;

	for (i = 0; i < gc->ngpio; i++) {
		pins[i].number = i;
		pins[i].name = devm_kasprintf(chip->dev, GFP_KERNEL,
					      "gpio-%d", i);
		if (!pins[i].name)
			return -ENOMEM;
	}

	pctldesc->name = dev_name(chip->dev);
	pctldesc->pctlops = &cygnus_pctrl_ops;
	pctldesc->pins = pins;
	pctldesc->npins = gc->ngpio;
	pctldesc->confops = &cygnus_pconf_ops;

	chip->pctl = pinctrl_register(pctldesc, chip->dev, chip);
	if (IS_ERR(chip->pctl)) {
		dev_err(chip->dev, "unable to register pinctrl device\n");
		return PTR_ERR(chip->pctl);
	}

	return 0;
}

static void cygnus_gpio_unregister_pinconf(struct cygnus_gpio *chip)
{
	if (chip->pctl)
		pinctrl_unregister(chip->pctl);
}

struct cygnus_gpio_data {
	unsigned num_gpios;
};

static const struct cygnus_gpio_data cygnus_cmm_gpio_data = {
	.num_gpios = 24,
};

static const struct cygnus_gpio_data cygnus_asiu_gpio_data = {
	.num_gpios = 146,
};

static const struct cygnus_gpio_data cygnus_crmu_gpio_data = {
	.num_gpios = 6,
};

static const struct of_device_id cygnus_gpio_of_match[] = {
	{
		.compatible = "brcm,cygnus-ccm-gpio",
		.data = &cygnus_cmm_gpio_data,
	},
	{
		.compatible = "brcm,cygnus-asiu-gpio",
		.data = &cygnus_asiu_gpio_data,
	},
	{
		.compatible = "brcm,cygnus-crmu-gpio",
		.data = &cygnus_crmu_gpio_data,
	}
};

static int cygnus_gpio_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct cygnus_gpio *chip;
	struct gpio_chip *gc;
	u32 ngpios;
	int irq, ret;
	const struct of_device_id *match;
	const struct cygnus_gpio_data *gpio_data;

	match = of_match_device(cygnus_gpio_of_match, dev);
	if (!match)
		return -ENODEV;
	gpio_data = match->data;
	ngpios = gpio_data->num_gpios;

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

	chip->dev = dev;
	platform_set_drvdata(pdev, chip);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	chip->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(chip->base)) {
		dev_err(dev, "unable to map I/O memory\n");
		return PTR_ERR(chip->base);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res) {
		chip->io_ctrl = devm_ioremap_resource(dev, res);
		if (IS_ERR(chip->io_ctrl)) {
			dev_err(dev, "unable to map I/O memory\n");
			return PTR_ERR(chip->io_ctrl);
		}
	}

	spin_lock_init(&chip->lock);

	gc = &chip->gc;
	gc->base = -1;
	gc->ngpio = ngpios;
	chip->num_banks = (ngpios + NGPIOS_PER_BANK - 1) / NGPIOS_PER_BANK;
	gc->label = dev_name(dev);
	gc->dev = dev;
	gc->of_node = dev->of_node;
	gc->request = cygnus_gpio_request;
	gc->free = cygnus_gpio_free;
	gc->direction_input = cygnus_gpio_direction_input;
	gc->direction_output = cygnus_gpio_direction_output;
	gc->set = cygnus_gpio_set;
	gc->get = cygnus_gpio_get;

	ret = gpiochip_add(gc);
	if (ret < 0) {
		dev_err(dev, "unable to add GPIO chip\n");
		return ret;
	}

	ret = cygnus_gpio_pinmux_add_range(chip);
	if (ret && ret != -ENODEV) {
		dev_err(dev, "unable to add GPIO pin range\n");
		goto err_rm_gpiochip;
	}

	ret = cygnus_gpio_register_pinconf(chip);
	if (ret) {
		dev_err(dev, "unable to register pinconf\n");
		goto err_rm_gpiochip;
	}

	/* optional GPIO interrupt support */
	irq = platform_get_irq(pdev, 0);
	if (irq) {
		ret = gpiochip_irqchip_add(gc, &cygnus_gpio_irq_chip, 0,
					   handle_simple_irq, IRQ_TYPE_NONE);
		if (ret) {
			dev_err(dev, "no GPIO irqchip\n");
			goto err_unregister_pinconf;
		}

		gpiochip_set_chained_irqchip(gc, &cygnus_gpio_irq_chip, irq,
					     cygnus_gpio_irq_handler);
	}

	return 0;

err_unregister_pinconf:
	cygnus_gpio_unregister_pinconf(chip);

err_rm_gpiochip:
	gpiochip_remove(gc);

	return ret;
}

static struct platform_driver cygnus_gpio_driver = {
	.driver = {
		.name = "cygnus-gpio",
		.of_match_table = cygnus_gpio_of_match,
	},
	.probe = cygnus_gpio_probe,
};

static int __init cygnus_gpio_init(void)
{
	return platform_driver_probe(&cygnus_gpio_driver, cygnus_gpio_probe);
}
arch_initcall_sync(cygnus_gpio_init);
