// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2019 Intel Corporation */

#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>

#include "core.h"
#include "pinconf.h"
#include "pinmux.h"
#include "pinctrl-equilibrium.h"

#define PIN_NAME_FMT	"io-%d"
#define PIN_NAME_LEN	10
#define PAD_REG_OFF	0x100

static void eqbr_gpio_disable_irq(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
	unsigned int offset = irqd_to_hwirq(d);
	unsigned long flags;

	raw_spin_lock_irqsave(&gctrl->lock, flags);
	writel(BIT(offset), gctrl->membase + GPIO_IRNENCLR);
	raw_spin_unlock_irqrestore(&gctrl->lock, flags);
	gpiochip_disable_irq(gc, offset);
}

static void eqbr_gpio_enable_irq(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
	unsigned int offset = irqd_to_hwirq(d);
	unsigned long flags;

	gc->direction_input(gc, offset);
	gpiochip_enable_irq(gc, offset);
	raw_spin_lock_irqsave(&gctrl->lock, flags);
	writel(BIT(offset), gctrl->membase + GPIO_IRNRNSET);
	raw_spin_unlock_irqrestore(&gctrl->lock, flags);
}

static void eqbr_gpio_ack_irq(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
	unsigned int offset = irqd_to_hwirq(d);
	unsigned long flags;

	raw_spin_lock_irqsave(&gctrl->lock, flags);
	writel(BIT(offset), gctrl->membase + GPIO_IRNCR);
	raw_spin_unlock_irqrestore(&gctrl->lock, flags);
}

static void eqbr_gpio_mask_ack_irq(struct irq_data *d)
{
	eqbr_gpio_disable_irq(d);
	eqbr_gpio_ack_irq(d);
}

static inline void eqbr_cfg_bit(void __iomem *addr,
				unsigned int offset, unsigned int set)
{
	if (set)
		writel(readl(addr) | BIT(offset), addr);
	else
		writel(readl(addr) & ~BIT(offset), addr);
}

static int eqbr_irq_type_cfg(struct gpio_irq_type *type,
			     struct eqbr_gpio_ctrl *gctrl,
			     unsigned int offset)
{
	unsigned long flags;

	raw_spin_lock_irqsave(&gctrl->lock, flags);
	eqbr_cfg_bit(gctrl->membase + GPIO_IRNCFG, offset, type->trig_type);
	eqbr_cfg_bit(gctrl->membase + GPIO_EXINTCR1, offset, type->trig_type);
	eqbr_cfg_bit(gctrl->membase + GPIO_EXINTCR0, offset, type->logic_type);
	raw_spin_unlock_irqrestore(&gctrl->lock, flags);

	return 0;
}

static int eqbr_gpio_set_irq_type(struct irq_data *d, unsigned int type)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
	unsigned int offset = irqd_to_hwirq(d);
	struct gpio_irq_type it;

	memset(&it, 0, sizeof(it));

	if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_NONE)
		return 0;

	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
		it.trig_type = GPIO_EDGE_TRIG;
		it.edge_type = GPIO_SINGLE_EDGE;
		it.logic_type = GPIO_POSITIVE_TRIG;
		break;

	case IRQ_TYPE_EDGE_FALLING:
		it.trig_type = GPIO_EDGE_TRIG;
		it.edge_type = GPIO_SINGLE_EDGE;
		it.logic_type = GPIO_NEGATIVE_TRIG;
		break;

	case IRQ_TYPE_EDGE_BOTH:
		it.trig_type = GPIO_EDGE_TRIG;
		it.edge_type = GPIO_BOTH_EDGE;
		it.logic_type = GPIO_POSITIVE_TRIG;
		break;

	case IRQ_TYPE_LEVEL_HIGH:
		it.trig_type = GPIO_LEVEL_TRIG;
		it.edge_type = GPIO_SINGLE_EDGE;
		it.logic_type = GPIO_POSITIVE_TRIG;
		break;

	case IRQ_TYPE_LEVEL_LOW:
		it.trig_type = GPIO_LEVEL_TRIG;
		it.edge_type = GPIO_SINGLE_EDGE;
		it.logic_type = GPIO_NEGATIVE_TRIG;
		break;

	default:
		return -EINVAL;
	}

	eqbr_irq_type_cfg(&it, gctrl, offset);
	if (it.trig_type == GPIO_EDGE_TRIG)
		irq_set_handler_locked(d, handle_edge_irq);
	else
		irq_set_handler_locked(d, handle_level_irq);

	return 0;
}

static void eqbr_irq_handler(struct irq_desc *desc)
{
	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
	struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc);
	struct irq_chip *ic = irq_desc_get_chip(desc);
	unsigned long pins, offset;

	chained_irq_enter(ic, desc);
	pins = readl(gctrl->membase + GPIO_IRNCR);

	for_each_set_bit(offset, &pins, gc->ngpio)
		generic_handle_domain_irq(gc->irq.domain, offset);

	chained_irq_exit(ic, desc);
}

static const struct irq_chip eqbr_irq_chip = {
	.name = "gpio_irq",
	.irq_mask = eqbr_gpio_disable_irq,
	.irq_unmask = eqbr_gpio_enable_irq,
	.irq_ack = eqbr_gpio_ack_irq,
	.irq_mask_ack = eqbr_gpio_mask_ack_irq,
	.irq_set_type = eqbr_gpio_set_irq_type,
	.flags = IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static int gpiochip_setup(struct device *dev, struct eqbr_gpio_ctrl *gctrl)
{
	struct gpio_irq_chip *girq;
	struct gpio_chip *gc;

	gc = &gctrl->chip;
	gc->label = gctrl->name;
	gc->fwnode = gctrl->fwnode;

	if (!fwnode_property_read_bool(gctrl->fwnode, "interrupt-controller")) {
		dev_dbg(dev, "gc %s: doesn't act as interrupt controller!\n",
			gctrl->name);
		return 0;
	}

	girq = &gctrl->chip.irq;
	gpio_irq_chip_set_chip(girq, &eqbr_irq_chip);
	girq->parent_handler = eqbr_irq_handler;
	girq->num_parents = 1;
	girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), GFP_KERNEL);
	if (!girq->parents)
		return -ENOMEM;

	girq->default_type = IRQ_TYPE_NONE;
	girq->handler = handle_bad_irq;
	girq->parents[0] = gctrl->virq;

	return 0;
}

static int gpiolib_reg(struct eqbr_pinctrl_drv_data *drvdata)
{
	struct device *dev = drvdata->dev;
	struct eqbr_gpio_ctrl *gctrl;
	struct device_node *np;
	struct resource res;
	int i, ret;

	for (i = 0; i < drvdata->nr_gpio_ctrls; i++) {
		gctrl = drvdata->gpio_ctrls + i;
		np = to_of_node(gctrl->fwnode);

		gctrl->name = devm_kasprintf(dev, GFP_KERNEL, "gpiochip%d", i);
		if (!gctrl->name)
			return -ENOMEM;

		if (of_address_to_resource(np, 0, &res)) {
			dev_err(dev, "Failed to get GPIO register address\n");
			return -ENXIO;
		}

		gctrl->membase = devm_ioremap_resource(dev, &res);
		if (IS_ERR(gctrl->membase))
			return PTR_ERR(gctrl->membase);

		gctrl->virq = irq_of_parse_and_map(np, 0);
		if (!gctrl->virq) {
			dev_err(dev, "%s: failed to parse and map irq\n",
				gctrl->name);
			return -ENXIO;
		}
		raw_spin_lock_init(&gctrl->lock);

		ret = bgpio_init(&gctrl->chip, dev, gctrl->bank->nr_pins / 8,
				 gctrl->membase + GPIO_IN,
				 gctrl->membase + GPIO_OUTSET,
				 gctrl->membase + GPIO_OUTCLR,
				 gctrl->membase + GPIO_DIR,
				 NULL, 0);
		if (ret) {
			dev_err(dev, "unable to init generic GPIO\n");
			return ret;
		}

		ret = gpiochip_setup(dev, gctrl);
		if (ret)
			return ret;

		ret = devm_gpiochip_add_data(dev, &gctrl->chip, gctrl);
		if (ret)
			return ret;
	}

	return 0;
}

static inline struct eqbr_pin_bank
*find_pinbank_via_pin(struct eqbr_pinctrl_drv_data *pctl, unsigned int pin)
{
	struct eqbr_pin_bank *bank;
	int i;

	for (i = 0; i < pctl->nr_banks; i++) {
		bank = &pctl->pin_banks[i];
		if (pin >= bank->pin_base &&
		    (pin - bank->pin_base) < bank->nr_pins)
			return bank;
	}

	return NULL;
}

static const struct pinctrl_ops eqbr_pctl_ops = {
	.get_groups_count	= pinctrl_generic_get_group_count,
	.get_group_name		= pinctrl_generic_get_group_name,
	.get_group_pins		= pinctrl_generic_get_group_pins,
	.dt_node_to_map		= pinconf_generic_dt_node_to_map_all,
	.dt_free_map		= pinconf_generic_dt_free_map,
};

static int eqbr_set_pin_mux(struct eqbr_pinctrl_drv_data *pctl,
			    unsigned int pmx, unsigned int pin)
{
	struct eqbr_pin_bank *bank;
	unsigned long flags;
	unsigned int offset;
	void __iomem *mem;

	bank = find_pinbank_via_pin(pctl, pin);
	if (!bank) {
		dev_err(pctl->dev, "Couldn't find pin bank for pin %u\n", pin);
		return -ENODEV;
	}
	mem = bank->membase;
	offset = pin - bank->pin_base;

	if (!(bank->aval_pinmap & BIT(offset))) {
		dev_err(pctl->dev,
			"PIN: %u is not valid, pinbase: %u, bitmap: %u\n",
			pin, bank->pin_base, bank->aval_pinmap);
		return -ENODEV;
	}

	raw_spin_lock_irqsave(&pctl->lock, flags);
	writel(pmx, mem + (offset * 4));
	raw_spin_unlock_irqrestore(&pctl->lock, flags);
	return 0;
}

static int eqbr_pinmux_set_mux(struct pinctrl_dev *pctldev,
			       unsigned int selector, unsigned int group)
{
	struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);
	struct function_desc *func;
	struct group_desc *grp;
	unsigned int *pinmux;
	int i;

	func = pinmux_generic_get_function(pctldev, selector);
	if (!func)
		return -EINVAL;

	grp = pinctrl_generic_get_group(pctldev, group);
	if (!grp)
		return -EINVAL;

	pinmux = grp->data;
	for (i = 0; i < grp->grp.npins; i++)
		eqbr_set_pin_mux(pctl, pinmux[i], grp->grp.pins[i]);

	return 0;
}

static int eqbr_pinmux_gpio_request(struct pinctrl_dev *pctldev,
				    struct pinctrl_gpio_range *range,
				    unsigned int pin)
{
	struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);

	return eqbr_set_pin_mux(pctl, EQBR_GPIO_MODE, pin);
}

static const struct pinmux_ops eqbr_pinmux_ops = {
	.get_functions_count	= pinmux_generic_get_function_count,
	.get_function_name	= pinmux_generic_get_function_name,
	.get_function_groups	= pinmux_generic_get_function_groups,
	.set_mux		= eqbr_pinmux_set_mux,
	.gpio_request_enable	= eqbr_pinmux_gpio_request,
	.strict			= true,
};

static int get_drv_cur(void __iomem *mem, unsigned int offset)
{
	unsigned int idx = offset / DRV_CUR_PINS; /* 0-15, 16-31 per register*/
	unsigned int pin_offset = offset % DRV_CUR_PINS;

	return PARSE_DRV_CURRENT(readl(mem + REG_DRCC(idx)), pin_offset);
}

static struct eqbr_gpio_ctrl
*get_gpio_ctrls_via_bank(struct eqbr_pinctrl_drv_data *pctl,
			struct eqbr_pin_bank *bank)
{
	int i;

	for (i = 0; i < pctl->nr_gpio_ctrls; i++) {
		if (pctl->gpio_ctrls[i].bank == bank)
			return &pctl->gpio_ctrls[i];
	}

	return NULL;
}

static int eqbr_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
			    unsigned long *config)
{
	struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param = pinconf_to_config_param(*config);
	struct eqbr_gpio_ctrl *gctrl;
	struct eqbr_pin_bank *bank;
	unsigned long flags;
	unsigned int offset;
	void __iomem *mem;
	u32 val;

	bank = find_pinbank_via_pin(pctl, pin);
	if (!bank) {
		dev_err(pctl->dev, "Couldn't find pin bank for pin %u\n", pin);
		return -ENODEV;
	}
	mem = bank->membase;
	offset = pin - bank->pin_base;

	if (!(bank->aval_pinmap & BIT(offset))) {
		dev_err(pctl->dev,
			"PIN: %u is not valid, pinbase: %u, bitmap: %u\n",
			pin, bank->pin_base, bank->aval_pinmap);
		return -ENODEV;
	}

	raw_spin_lock_irqsave(&pctl->lock, flags);
	switch (param) {
	case PIN_CONFIG_BIAS_PULL_UP:
		val = !!(readl(mem + REG_PUEN) & BIT(offset));
		break;
	case PIN_CONFIG_BIAS_PULL_DOWN:
		val = !!(readl(mem + REG_PDEN) & BIT(offset));
		break;
	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		val = !!(readl(mem + REG_OD) & BIT(offset));
		break;
	case PIN_CONFIG_DRIVE_STRENGTH:
		val = get_drv_cur(mem, offset);
		break;
	case PIN_CONFIG_SLEW_RATE:
		val = !!(readl(mem + REG_SRC) & BIT(offset));
		break;
	case PIN_CONFIG_OUTPUT_ENABLE:
		gctrl = get_gpio_ctrls_via_bank(pctl, bank);
		if (!gctrl) {
			dev_err(pctl->dev, "Failed to find gpio via bank pinbase: %u, pin: %u\n",
				bank->pin_base, pin);
			raw_spin_unlock_irqrestore(&pctl->lock, flags);
			return -ENODEV;
		}
		val = !!(readl(gctrl->membase + GPIO_DIR) & BIT(offset));
		break;
	default:
		raw_spin_unlock_irqrestore(&pctl->lock, flags);
		return -ENOTSUPP;
	}
	raw_spin_unlock_irqrestore(&pctl->lock, flags);
	*config = pinconf_to_config_packed(param, val);
;
	return 0;
}

static int eqbr_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
			    unsigned long *configs, unsigned int num_configs)
{
	struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);
	struct eqbr_gpio_ctrl *gctrl;
	enum pin_config_param param;
	struct eqbr_pin_bank *bank;
	unsigned int val, offset;
	struct gpio_chip *gc;
	unsigned long flags;
	void __iomem *mem;
	u32 regval, mask;
	int i;

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

		bank = find_pinbank_via_pin(pctl, pin);
		if (!bank) {
			dev_err(pctl->dev,
				"Couldn't find pin bank for pin %u\n", pin);
			return -ENODEV;
		}
		mem = bank->membase;
		offset = pin - bank->pin_base;

		switch (param) {
		case PIN_CONFIG_BIAS_PULL_UP:
			mem += REG_PUEN;
			mask = BIT(offset);
			break;
		case PIN_CONFIG_BIAS_PULL_DOWN:
			mem += REG_PDEN;
			mask = BIT(offset);
			break;
		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
			mem += REG_OD;
			mask = BIT(offset);
			break;
		case PIN_CONFIG_DRIVE_STRENGTH:
			mem += REG_DRCC(offset / DRV_CUR_PINS);
			offset = (offset % DRV_CUR_PINS) * 2;
			mask = GENMASK(1, 0) << offset;
			break;
		case PIN_CONFIG_SLEW_RATE:
			mem += REG_SRC;
			mask = BIT(offset);
			break;
		case PIN_CONFIG_OUTPUT_ENABLE:
			gctrl = get_gpio_ctrls_via_bank(pctl, bank);
			if (!gctrl) {
				dev_err(pctl->dev, "Failed to find gpio via bank pinbase: %u, pin: %u\n",
					bank->pin_base, pin);
				return -ENODEV;
			}
			gc = &gctrl->chip;
			gc->direction_output(gc, offset, 0);
			continue;
		default:
			return -ENOTSUPP;
		}

		raw_spin_lock_irqsave(&pctl->lock, flags);
		regval = readl(mem);
		regval = (regval & ~mask) | ((val << offset) & mask);
		writel(regval, mem);
		raw_spin_unlock_irqrestore(&pctl->lock, flags);
	}

	return 0;
}

static int eqbr_pinconf_group_get(struct pinctrl_dev *pctldev,
				  unsigned int group, unsigned long *config)
{
	unsigned int i, npins, old = 0;
	const unsigned int *pins;
	int ret;

	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
	if (ret)
		return ret;

	for (i = 0; i < npins; i++) {
		if (eqbr_pinconf_get(pctldev, pins[i], config))
			return -ENOTSUPP;

		if (i && old != *config)
			return -ENOTSUPP;

		old = *config;
	}
	return 0;
}

static int eqbr_pinconf_group_set(struct pinctrl_dev *pctldev,
				  unsigned int group, unsigned long *configs,
				  unsigned int num_configs)
{
	const unsigned int *pins;
	unsigned int i, npins;
	int ret;

	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
	if (ret)
		return ret;

	for (i = 0; i < npins; i++) {
		ret = eqbr_pinconf_set(pctldev, pins[i], configs, num_configs);
		if (ret)
			return ret;
	}
	return 0;
}

static const struct pinconf_ops eqbr_pinconf_ops = {
	.is_generic			= true,
	.pin_config_get			= eqbr_pinconf_get,
	.pin_config_set			= eqbr_pinconf_set,
	.pin_config_group_get		= eqbr_pinconf_group_get,
	.pin_config_group_set		= eqbr_pinconf_group_set,
	.pin_config_config_dbg_show	= pinconf_generic_dump_config,
};

static bool is_func_exist(struct pinfunction *funcs, const char *name,
			  unsigned int nr_funcs, unsigned int *idx)
{
	int i;

	if (!funcs)
		return false;

	for (i = 0; i < nr_funcs; i++) {
		if (funcs[i].name && !strcmp(funcs[i].name, name)) {
			*idx = i;
			return true;
		}
	}

	return false;
}

static int funcs_utils(struct device *dev, struct pinfunction *funcs,
		       unsigned int *nr_funcs, funcs_util_ops op)
{
	struct device_node *node = dev->of_node;
	struct property *prop;
	const char *fn_name;
	const char **groups;
	unsigned int fid;
	int i, j;

	i = 0;
	for_each_child_of_node_scoped(node, np) {
		prop = of_find_property(np, "groups", NULL);
		if (!prop)
			continue;

		if (of_property_read_string(np, "function", &fn_name)) {
			/* some groups may not have function, it's OK */
			dev_dbg(dev, "Group %s: not function binded!\n",
				(char *)prop->value);
			continue;
		}

		switch (op) {
		case OP_COUNT_NR_FUNCS:
			if (!is_func_exist(funcs, fn_name, *nr_funcs, &fid))
				*nr_funcs = *nr_funcs + 1;
			break;

		case OP_ADD_FUNCS:
			if (!is_func_exist(funcs, fn_name, *nr_funcs, &fid))
				funcs[i].name = fn_name;
			break;

		case OP_COUNT_NR_FUNC_GRPS:
			if (is_func_exist(funcs, fn_name, *nr_funcs, &fid))
				funcs[fid].ngroups++;
			break;

		case OP_ADD_FUNC_GRPS:
			if (is_func_exist(funcs, fn_name, *nr_funcs, &fid)) {
				groups = (const char **)funcs[fid].groups;
				for (j = 0; j < funcs[fid].ngroups; j++)
					if (!groups[j])
						break;
				groups[j] = prop->value;
			}
			break;

		default:
			return -EINVAL;
		}
		i++;
	}

	return 0;
}

static int eqbr_build_functions(struct eqbr_pinctrl_drv_data *drvdata)
{
	struct device *dev = drvdata->dev;
	struct pinfunction *funcs = NULL;
	unsigned int nr_funcs = 0;
	int i, ret;

	ret = funcs_utils(dev, funcs, &nr_funcs, OP_COUNT_NR_FUNCS);
	if (ret)
		return ret;

	funcs = devm_kcalloc(dev, nr_funcs, sizeof(*funcs), GFP_KERNEL);
	if (!funcs)
		return -ENOMEM;

	ret = funcs_utils(dev, funcs, &nr_funcs, OP_ADD_FUNCS);
	if (ret)
		return ret;

	ret = funcs_utils(dev, funcs, &nr_funcs, OP_COUNT_NR_FUNC_GRPS);
	if (ret)
		return ret;

	for (i = 0; i < nr_funcs; i++) {
		if (!funcs[i].ngroups)
			continue;
		funcs[i].groups = devm_kcalloc(dev, funcs[i].ngroups,
					       sizeof(*(funcs[i].groups)),
					       GFP_KERNEL);
		if (!funcs[i].groups)
			return -ENOMEM;
	}

	ret = funcs_utils(dev, funcs, &nr_funcs, OP_ADD_FUNC_GRPS);
	if (ret)
		return ret;

	for (i = 0; i < nr_funcs; i++) {

		/* Ignore the same function with multiple groups */
		if (funcs[i].name == NULL)
			continue;

		ret = pinmux_generic_add_function(drvdata->pctl_dev,
						  funcs[i].name,
						  funcs[i].groups,
						  funcs[i].ngroups,
						  drvdata);
		if (ret < 0) {
			dev_err(dev, "Failed to register function %s\n",
				funcs[i].name);
			return ret;
		}
	}

	return 0;
}

static int eqbr_build_groups(struct eqbr_pinctrl_drv_data *drvdata)
{
	struct device *dev = drvdata->dev;
	struct device_node *node = dev->of_node;
	unsigned int *pins, *pinmux, pin_id, pinmux_id;
	struct pingroup group, *grp = &group;
	struct property *prop;
	int j, err;

	for_each_child_of_node_scoped(node, np) {
		prop = of_find_property(np, "groups", NULL);
		if (!prop)
			continue;

		err = of_property_count_u32_elems(np, "pins");
		if (err < 0) {
			dev_err(dev, "No pins in the group: %s\n", prop->name);
			return err;
		}
		grp->npins = err;
		grp->name = prop->value;
		pins = devm_kcalloc(dev, grp->npins, sizeof(*pins), GFP_KERNEL);
		if (!pins)
			return -ENOMEM;

		grp->pins = pins;

		pinmux = devm_kcalloc(dev, grp->npins, sizeof(*pinmux), GFP_KERNEL);
		if (!pinmux)
			return -ENOMEM;

		for (j = 0; j < grp->npins; j++) {
			if (of_property_read_u32_index(np, "pins", j, &pin_id)) {
				dev_err(dev, "Group %s: Read intel pins id failed\n",
					grp->name);
				return -EINVAL;
			}
			if (pin_id >= drvdata->pctl_desc.npins) {
				dev_err(dev, "Group %s: Invalid pin ID, idx: %d, pin %u\n",
					grp->name, j, pin_id);
				return -EINVAL;
			}
			pins[j] = pin_id;
			if (of_property_read_u32_index(np, "pinmux", j, &pinmux_id)) {
				dev_err(dev, "Group %s: Read intel pinmux id failed\n",
					grp->name);
				return -EINVAL;
			}
			pinmux[j] = pinmux_id;
		}

		err = pinctrl_generic_add_group(drvdata->pctl_dev,
						grp->name, grp->pins, grp->npins,
						pinmux);
		if (err < 0) {
			dev_err(dev, "Failed to register group %s\n", grp->name);
			return err;
		}
		memset(&group, 0, sizeof(group));
		pinmux = NULL;
	}

	return 0;
}

static int pinctrl_reg(struct eqbr_pinctrl_drv_data *drvdata)
{
	struct pinctrl_desc *pctl_desc;
	struct pinctrl_pin_desc *pdesc;
	struct device *dev;
	unsigned int nr_pins;
	char *pin_names;
	int i, ret;

	dev = drvdata->dev;
	pctl_desc = &drvdata->pctl_desc;
	pctl_desc->name = "eqbr-pinctrl";
	pctl_desc->owner = THIS_MODULE;
	pctl_desc->pctlops = &eqbr_pctl_ops;
	pctl_desc->pmxops = &eqbr_pinmux_ops;
	pctl_desc->confops = &eqbr_pinconf_ops;
	raw_spin_lock_init(&drvdata->lock);

	for (i = 0, nr_pins = 0; i < drvdata->nr_banks; i++)
		nr_pins += drvdata->pin_banks[i].nr_pins;

	pdesc = devm_kcalloc(dev, nr_pins, sizeof(*pdesc), GFP_KERNEL);
	if (!pdesc)
		return -ENOMEM;
	pin_names = devm_kcalloc(dev, nr_pins, PIN_NAME_LEN, GFP_KERNEL);
	if (!pin_names)
		return -ENOMEM;

	for (i = 0; i < nr_pins; i++) {
		sprintf(pin_names, PIN_NAME_FMT, i);
		pdesc[i].number = i;
		pdesc[i].name = pin_names;
		pin_names += PIN_NAME_LEN;
	}
	pctl_desc->pins = pdesc;
	pctl_desc->npins = nr_pins;
	dev_dbg(dev, "pinctrl total pin number: %u\n", nr_pins);

	ret = devm_pinctrl_register_and_init(dev, pctl_desc, drvdata,
					     &drvdata->pctl_dev);
	if (ret)
		return ret;

	ret = eqbr_build_groups(drvdata);
	if (ret) {
		dev_err(dev, "Failed to build groups\n");
		return ret;
	}

	ret = eqbr_build_functions(drvdata);
	if (ret) {
		dev_err(dev, "Failed to build functions\n");
		return ret;
	}

	return pinctrl_enable(drvdata->pctl_dev);
}

static int pinbank_init(struct device_node *np,
			struct eqbr_pinctrl_drv_data *drvdata,
			struct eqbr_pin_bank *bank, unsigned int id)
{
	struct device *dev = drvdata->dev;
	struct of_phandle_args spec;
	int ret;

	bank->membase = drvdata->membase + id * PAD_REG_OFF;

	ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &spec);
	if (ret) {
		dev_err(dev, "gpio-range not available!\n");
		return ret;
	}

	bank->pin_base = spec.args[1];
	bank->nr_pins = spec.args[2];

	bank->aval_pinmap = readl(bank->membase + REG_AVAIL);
	bank->id = id;

	dev_dbg(dev, "pinbank id: %d, reg: %px, pinbase: %u, pin number: %u, pinmap: 0x%x\n",
		id, bank->membase, bank->pin_base,
		bank->nr_pins, bank->aval_pinmap);

	return ret;
}

static int pinbank_probe(struct eqbr_pinctrl_drv_data *drvdata)
{
	struct device *dev = drvdata->dev;
	struct device_node *np_gpio;
	struct eqbr_gpio_ctrl *gctrls;
	struct eqbr_pin_bank *banks;
	int i, nr_gpio;

	/* Count gpio bank number */
	nr_gpio = 0;
	for_each_node_by_name(np_gpio, "gpio") {
		if (of_device_is_available(np_gpio))
			nr_gpio++;
	}

	if (!nr_gpio) {
		dev_err(dev, "NO pin bank available!\n");
		return -ENODEV;
	}

	/* Count pin bank number and gpio controller number */
	banks = devm_kcalloc(dev, nr_gpio, sizeof(*banks), GFP_KERNEL);
	if (!banks)
		return -ENOMEM;

	gctrls = devm_kcalloc(dev, nr_gpio, sizeof(*gctrls), GFP_KERNEL);
	if (!gctrls)
		return -ENOMEM;

	dev_dbg(dev, "found %d gpio controller!\n", nr_gpio);

	/* Initialize Pin bank */
	i = 0;
	for_each_node_by_name(np_gpio, "gpio") {
		if (!of_device_is_available(np_gpio))
			continue;

		pinbank_init(np_gpio, drvdata, banks + i, i);

		gctrls[i].fwnode = of_fwnode_handle(np_gpio);
		gctrls[i].bank = banks + i;
		i++;
	}

	drvdata->pin_banks = banks;
	drvdata->nr_banks = nr_gpio;
	drvdata->gpio_ctrls = gctrls;
	drvdata->nr_gpio_ctrls = nr_gpio;

	return 0;
}

static int eqbr_pinctrl_probe(struct platform_device *pdev)
{
	struct eqbr_pinctrl_drv_data *drvdata;
	struct device *dev = &pdev->dev;
	int ret;

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

	drvdata->dev = dev;

	drvdata->membase = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(drvdata->membase))
		return PTR_ERR(drvdata->membase);

	ret = pinbank_probe(drvdata);
	if (ret)
		return ret;

	ret = pinctrl_reg(drvdata);
	if (ret)
		return ret;

	ret = gpiolib_reg(drvdata);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, drvdata);
	return 0;
}

static const struct of_device_id eqbr_pinctrl_dt_match[] = {
	{ .compatible = "intel,lgm-io" },
	{}
};
MODULE_DEVICE_TABLE(of, eqbr_pinctrl_dt_match);

static struct platform_driver eqbr_pinctrl_driver = {
	.probe	= eqbr_pinctrl_probe,
	.driver = {
		.name = "eqbr-pinctrl",
		.of_match_table = eqbr_pinctrl_dt_match,
	},
};

module_platform_driver(eqbr_pinctrl_driver);

MODULE_AUTHOR("Zhu Yixin <yixin.zhu@intel.com>, Rahul Tanwar <rahul.tanwar@intel.com>");
MODULE_DESCRIPTION("Pinctrl Driver for LGM SoC (Equilibrium)");
MODULE_LICENSE("GPL v2");
