/*
 * pinmux driver for CSR SiRFprimaII
 *
 * Copyright (c) 2011 - 2014 Cambridge Silicon Radio Limited, a CSR plc group
 * company.
 *
 * Licensed under GPLv2 or later.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/machine.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/bitops.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>

#include "pinctrl-sirf.h"

#define DRIVER_NAME "pinmux-sirf"

struct sirfsoc_gpio_bank {
	int id;
	int parent_irq;
	spinlock_t lock;
};

struct sirfsoc_gpio_chip {
	struct of_mm_gpio_chip chip;
	struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS];
	spinlock_t lock;
};

static struct sirfsoc_pin_group *sirfsoc_pin_groups;
static int sirfsoc_pingrp_cnt;

static int sirfsoc_get_groups_count(struct pinctrl_dev *pctldev)
{
	return sirfsoc_pingrp_cnt;
}

static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev,
				       unsigned selector)
{
	return sirfsoc_pin_groups[selector].name;
}

static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev,
				unsigned selector,
				const unsigned **pins,
				unsigned *num_pins)
{
	*pins = sirfsoc_pin_groups[selector].pins;
	*num_pins = sirfsoc_pin_groups[selector].num_pins;
	return 0;
}

static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev,
				struct seq_file *s, unsigned offset)
{
	seq_printf(s, " " DRIVER_NAME);
}

static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev,
				 struct device_node *np_config,
				 struct pinctrl_map **map, unsigned *num_maps)
{
	struct sirfsoc_pmx *spmx = pinctrl_dev_get_drvdata(pctldev);
	struct device_node *np;
	struct property *prop;
	const char *function, *group;
	int ret, index = 0, count = 0;

	/* calculate number of maps required */
	for_each_child_of_node(np_config, np) {
		ret = of_property_read_string(np, "sirf,function", &function);
		if (ret < 0) {
			of_node_put(np);
			return ret;
		}

		ret = of_property_count_strings(np, "sirf,pins");
		if (ret < 0) {
			of_node_put(np);
			return ret;
		}

		count += ret;
	}

	if (!count) {
		dev_err(spmx->dev, "No child nodes passed via DT\n");
		return -ENODEV;
	}

	*map = kzalloc(sizeof(**map) * count, GFP_KERNEL);
	if (!*map)
		return -ENOMEM;

	for_each_child_of_node(np_config, np) {
		of_property_read_string(np, "sirf,function", &function);
		of_property_for_each_string(np, "sirf,pins", prop, group) {
			(*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
			(*map)[index].data.mux.group = group;
			(*map)[index].data.mux.function = function;
			index++;
		}
	}

	*num_maps = count;

	return 0;
}

static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev,
		struct pinctrl_map *map, unsigned num_maps)
{
	kfree(map);
}

static struct pinctrl_ops sirfsoc_pctrl_ops = {
	.get_groups_count = sirfsoc_get_groups_count,
	.get_group_name = sirfsoc_get_group_name,
	.get_group_pins = sirfsoc_get_group_pins,
	.pin_dbg_show = sirfsoc_pin_dbg_show,
	.dt_node_to_map = sirfsoc_dt_node_to_map,
	.dt_free_map = sirfsoc_dt_free_map,
};

static struct sirfsoc_pmx_func *sirfsoc_pmx_functions;
static int sirfsoc_pmxfunc_cnt;

static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx,
					unsigned selector, bool enable)
{
	int i;
	const struct sirfsoc_padmux *mux =
		sirfsoc_pmx_functions[selector].padmux;
	const struct sirfsoc_muxmask *mask = mux->muxmask;

	for (i = 0; i < mux->muxmask_counts; i++) {
		u32 muxval;
		muxval = readl(spmx->gpio_virtbase +
			SIRFSOC_GPIO_PAD_EN(mask[i].group));
		if (enable)
			muxval = muxval & ~mask[i].mask;
		else
			muxval = muxval | mask[i].mask;
		writel(muxval, spmx->gpio_virtbase +
			SIRFSOC_GPIO_PAD_EN(mask[i].group));
	}

	if (mux->funcmask && enable) {
		u32 func_en_val;

		func_en_val =
			readl(spmx->rsc_virtbase + mux->ctrlreg);
		func_en_val =
			(func_en_val & ~mux->funcmask) | (mux->funcval);
		writel(func_en_val, spmx->rsc_virtbase + mux->ctrlreg);
	}
}

static int sirfsoc_pinmux_set_mux(struct pinctrl_dev *pmxdev,
				unsigned selector,
				unsigned group)
{
	struct sirfsoc_pmx *spmx;

	spmx = pinctrl_dev_get_drvdata(pmxdev);
	sirfsoc_pinmux_endisable(spmx, selector, true);

	return 0;
}

static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
{
	return sirfsoc_pmxfunc_cnt;
}

static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev,
					  unsigned selector)
{
	return sirfsoc_pmx_functions[selector].name;
}

static int sirfsoc_pinmux_get_groups(struct pinctrl_dev *pctldev,
				unsigned selector,
				const char * const **groups,
				unsigned * const num_groups)
{
	*groups = sirfsoc_pmx_functions[selector].groups;
	*num_groups = sirfsoc_pmx_functions[selector].num_groups;
	return 0;
}

static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
	struct pinctrl_gpio_range *range, unsigned offset)
{
	struct sirfsoc_pmx *spmx;

	int group = range->id;

	u32 muxval;

	spmx = pinctrl_dev_get_drvdata(pmxdev);

	muxval = readl(spmx->gpio_virtbase +
		SIRFSOC_GPIO_PAD_EN(group));
	muxval = muxval | (1 << (offset - range->pin_base));
	writel(muxval, spmx->gpio_virtbase +
		SIRFSOC_GPIO_PAD_EN(group));

	return 0;
}

static struct pinmux_ops sirfsoc_pinmux_ops = {
	.set_mux = sirfsoc_pinmux_set_mux,
	.get_functions_count = sirfsoc_pinmux_get_funcs_count,
	.get_function_name = sirfsoc_pinmux_get_func_name,
	.get_function_groups = sirfsoc_pinmux_get_groups,
	.gpio_request_enable = sirfsoc_pinmux_request_gpio,
};

static struct pinctrl_desc sirfsoc_pinmux_desc = {
	.name = DRIVER_NAME,
	.pctlops = &sirfsoc_pctrl_ops,
	.pmxops = &sirfsoc_pinmux_ops,
	.owner = THIS_MODULE,
};

static void __iomem *sirfsoc_rsc_of_iomap(void)
{
	const struct of_device_id rsc_ids[]  = {
		{ .compatible = "sirf,prima2-rsc" },
		{}
	};
	struct device_node *np;

	np = of_find_matching_node(NULL, rsc_ids);
	if (!np)
		panic("unable to find compatible rsc node in dtb\n");

	return of_iomap(np, 0);
}

static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc,
	const struct of_phandle_args *gpiospec,
	u32 *flags)
{
	if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE)
		return -EINVAL;

	if (flags)
		*flags = gpiospec->args[1];

	return gpiospec->args[0];
}

static const struct of_device_id pinmux_ids[] = {
	{ .compatible = "sirf,prima2-pinctrl", .data = &prima2_pinctrl_data, },
	{ .compatible = "sirf,atlas6-pinctrl", .data = &atlas6_pinctrl_data, },
	{}
};

static int sirfsoc_pinmux_probe(struct platform_device *pdev)
{
	int ret;
	struct sirfsoc_pmx *spmx;
	struct device_node *np = pdev->dev.of_node;
	const struct sirfsoc_pinctrl_data *pdata;

	/* Create state holders etc for this driver */
	spmx = devm_kzalloc(&pdev->dev, sizeof(*spmx), GFP_KERNEL);
	if (!spmx)
		return -ENOMEM;

	spmx->dev = &pdev->dev;

	platform_set_drvdata(pdev, spmx);

	spmx->gpio_virtbase = of_iomap(np, 0);
	if (!spmx->gpio_virtbase) {
		dev_err(&pdev->dev, "can't map gpio registers\n");
		return -ENOMEM;
	}

	spmx->rsc_virtbase = sirfsoc_rsc_of_iomap();
	if (!spmx->rsc_virtbase) {
		ret = -ENOMEM;
		dev_err(&pdev->dev, "can't map rsc registers\n");
		goto out_no_rsc_remap;
	}

	pdata = of_match_node(pinmux_ids, np)->data;
	sirfsoc_pin_groups = pdata->grps;
	sirfsoc_pingrp_cnt = pdata->grps_cnt;
	sirfsoc_pmx_functions = pdata->funcs;
	sirfsoc_pmxfunc_cnt = pdata->funcs_cnt;
	sirfsoc_pinmux_desc.pins = pdata->pads;
	sirfsoc_pinmux_desc.npins = pdata->pads_cnt;


	/* Now register the pin controller and all pins it handles */
	spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx);
	if (IS_ERR(spmx->pmx)) {
		dev_err(&pdev->dev, "could not register SIRFSOC pinmux driver\n");
		ret = PTR_ERR(spmx->pmx);
		goto out_no_pmx;
	}

	dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n");

	return 0;

out_no_pmx:
	iounmap(spmx->rsc_virtbase);
out_no_rsc_remap:
	iounmap(spmx->gpio_virtbase);
	return ret;
}

#ifdef CONFIG_PM_SLEEP
static int sirfsoc_pinmux_suspend_noirq(struct device *dev)
{
	int i, j;
	struct sirfsoc_pmx *spmx = dev_get_drvdata(dev);

	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
		for (j = 0; j < SIRFSOC_GPIO_BANK_SIZE; j++) {
			spmx->gpio_regs[i][j] = readl(spmx->gpio_virtbase +
				SIRFSOC_GPIO_CTRL(i, j));
		}
		spmx->ints_regs[i] = readl(spmx->gpio_virtbase +
			SIRFSOC_GPIO_INT_STATUS(i));
		spmx->paden_regs[i] = readl(spmx->gpio_virtbase +
			SIRFSOC_GPIO_PAD_EN(i));
	}
	spmx->dspen_regs = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_DSP_EN0);

	for (i = 0; i < 3; i++)
		spmx->rsc_regs[i] = readl(spmx->rsc_virtbase + 4 * i);

	return 0;
}

static int sirfsoc_pinmux_resume_noirq(struct device *dev)
{
	int i, j;
	struct sirfsoc_pmx *spmx = dev_get_drvdata(dev);

	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
		for (j = 0; j < SIRFSOC_GPIO_BANK_SIZE; j++) {
			writel(spmx->gpio_regs[i][j], spmx->gpio_virtbase +
				SIRFSOC_GPIO_CTRL(i, j));
		}
		writel(spmx->ints_regs[i], spmx->gpio_virtbase +
			SIRFSOC_GPIO_INT_STATUS(i));
		writel(spmx->paden_regs[i], spmx->gpio_virtbase +
			SIRFSOC_GPIO_PAD_EN(i));
	}
	writel(spmx->dspen_regs, spmx->gpio_virtbase + SIRFSOC_GPIO_DSP_EN0);

	for (i = 0; i < 3; i++)
		writel(spmx->rsc_regs[i], spmx->rsc_virtbase + 4 * i);

	return 0;
}

static const struct dev_pm_ops sirfsoc_pinmux_pm_ops = {
	.suspend_noirq = sirfsoc_pinmux_suspend_noirq,
	.resume_noirq = sirfsoc_pinmux_resume_noirq,
	.freeze_noirq = sirfsoc_pinmux_suspend_noirq,
	.restore_noirq = sirfsoc_pinmux_resume_noirq,
};
#endif

static struct platform_driver sirfsoc_pinmux_driver = {
	.driver = {
		.name = DRIVER_NAME,
		.of_match_table = pinmux_ids,
#ifdef CONFIG_PM_SLEEP
		.pm = &sirfsoc_pinmux_pm_ops,
#endif
	},
	.probe = sirfsoc_pinmux_probe,
};

static int __init sirfsoc_pinmux_init(void)
{
	return platform_driver_register(&sirfsoc_pinmux_driver);
}
arch_initcall(sirfsoc_pinmux_init);

static inline struct sirfsoc_gpio_chip *to_sirfsoc_gpio(struct gpio_chip *gc)
{
	return container_of(gc, struct sirfsoc_gpio_chip, chip.gc);
}

static inline struct sirfsoc_gpio_bank *
sirfsoc_gpio_to_bank(struct sirfsoc_gpio_chip *sgpio, unsigned int offset)
{
	return &sgpio->sgpio_bank[offset / SIRFSOC_GPIO_BANK_SIZE];
}

static inline int sirfsoc_gpio_to_bankoff(unsigned int offset)
{
	return offset % SIRFSOC_GPIO_BANK_SIZE;
}

static void sirfsoc_gpio_irq_ack(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq);
	int idx = sirfsoc_gpio_to_bankoff(d->hwirq);
	u32 val, offset;
	unsigned long flags;

	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);

	spin_lock_irqsave(&sgpio->lock, flags);

	val = readl(sgpio->chip.regs + offset);

	writel(val, sgpio->chip.regs + offset);

	spin_unlock_irqrestore(&sgpio->lock, flags);
}

static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio,
				    struct sirfsoc_gpio_bank *bank,
				    int idx)
{
	u32 val, offset;
	unsigned long flags;

	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);

	spin_lock_irqsave(&sgpio->lock, flags);

	val = readl(sgpio->chip.regs + offset);
	val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
	writel(val, sgpio->chip.regs + offset);

	spin_unlock_irqrestore(&sgpio->lock, flags);
}

static void sirfsoc_gpio_irq_mask(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq);

	__sirfsoc_gpio_irq_mask(sgpio, bank, d->hwirq % SIRFSOC_GPIO_BANK_SIZE);
}

static void sirfsoc_gpio_irq_unmask(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq);
	int idx = sirfsoc_gpio_to_bankoff(d->hwirq);
	u32 val, offset;
	unsigned long flags;

	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);

	spin_lock_irqsave(&sgpio->lock, flags);

	val = readl(sgpio->chip.regs + offset);
	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
	val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK;
	writel(val, sgpio->chip.regs + offset);

	spin_unlock_irqrestore(&sgpio->lock, flags);
}

static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, d->hwirq);
	int idx = sirfsoc_gpio_to_bankoff(d->hwirq);
	u32 val, offset;
	unsigned long flags;

	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);

	spin_lock_irqsave(&sgpio->lock, flags);

	val = readl(sgpio->chip.regs + offset);
	val &= ~(SIRFSOC_GPIO_CTL_INTR_STS_MASK | SIRFSOC_GPIO_CTL_OUT_EN_MASK);

	switch (type) {
	case IRQ_TYPE_NONE:
		break;
	case IRQ_TYPE_EDGE_RISING:
		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK |
			SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
		val &= ~SIRFSOC_GPIO_CTL_INTR_LOW_MASK;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		val &= ~SIRFSOC_GPIO_CTL_INTR_HIGH_MASK;
		val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK |
			SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
		break;
	case IRQ_TYPE_EDGE_BOTH:
		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK |
			SIRFSOC_GPIO_CTL_INTR_LOW_MASK |
			SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		val &= ~(SIRFSOC_GPIO_CTL_INTR_HIGH_MASK |
			SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
		val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK;
		val &= ~(SIRFSOC_GPIO_CTL_INTR_LOW_MASK |
			SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
		break;
	}

	writel(val, sgpio->chip.regs + offset);

	spin_unlock_irqrestore(&sgpio->lock, flags);

	return 0;
}

static struct irq_chip sirfsoc_irq_chip = {
	.name = "sirf-gpio-irq",
	.irq_ack = sirfsoc_gpio_irq_ack,
	.irq_mask = sirfsoc_gpio_irq_mask,
	.irq_unmask = sirfsoc_gpio_irq_unmask,
	.irq_set_type = sirfsoc_gpio_irq_type,
};

static void sirfsoc_gpio_handle_irq(struct irq_desc *desc)
{
	unsigned int irq = irq_desc_get_irq(desc);
	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(gc);
	struct sirfsoc_gpio_bank *bank;
	u32 status, ctrl;
	int idx = 0;
	struct irq_chip *chip = irq_desc_get_chip(desc);
	int i;

	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
		bank = &sgpio->sgpio_bank[i];
		if (bank->parent_irq == irq)
			break;
	}
	BUG_ON(i == SIRFSOC_GPIO_NO_OF_BANKS);

	chained_irq_enter(chip, desc);

	status = readl(sgpio->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id));
	if (!status) {
		printk(KERN_WARNING
			"%s: gpio id %d status %#x no interrupt is flagged\n",
			__func__, bank->id, status);
		handle_bad_irq(desc);
		return;
	}

	while (status) {
		ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, idx));

		/*
		 * Here we must check whether the corresponding GPIO's interrupt
		 * has been enabled, otherwise just skip it
		 */
		if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) {
			pr_debug("%s: gpio id %d idx %d happens\n",
				__func__, bank->id, idx);
			generic_handle_irq(irq_find_mapping(gc->irqdomain, idx +
					bank->id * SIRFSOC_GPIO_BANK_SIZE));
		}

		idx++;
		status = status >> 1;
	}

	chained_irq_exit(chip, desc);
}

static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_chip *sgpio,
					  unsigned ctrl_offset)
{
	u32 val;

	val = readl(sgpio->chip.regs + ctrl_offset);
	val &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK;
	writel(val, sgpio->chip.regs + ctrl_offset);
}

static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset)
{
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset);
	unsigned long flags;

	if (pinctrl_request_gpio(chip->base + offset))
		return -ENODEV;

	spin_lock_irqsave(&bank->lock, flags);

	/*
	 * default status:
	 * set direction as input and mask irq
	 */
	sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset));
	__sirfsoc_gpio_irq_mask(sgpio, bank, offset);

	spin_unlock_irqrestore(&bank->lock, flags);

	return 0;
}

static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset)
{
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset);
	unsigned long flags;

	spin_lock_irqsave(&bank->lock, flags);

	__sirfsoc_gpio_irq_mask(sgpio, bank, offset);
	sirfsoc_gpio_set_input(sgpio, SIRFSOC_GPIO_CTRL(bank->id, offset));

	spin_unlock_irqrestore(&bank->lock, flags);

	pinctrl_free_gpio(chip->base + offset);
}

static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio);
	int idx = sirfsoc_gpio_to_bankoff(gpio);
	unsigned long flags;
	unsigned offset;

	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);

	spin_lock_irqsave(&bank->lock, flags);

	sirfsoc_gpio_set_input(sgpio, offset);

	spin_unlock_irqrestore(&bank->lock, flags);

	return 0;
}

static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_chip *sgpio,
					   struct sirfsoc_gpio_bank *bank,
					   unsigned offset,
					   int value)
{
	u32 out_ctrl;
	unsigned long flags;

	spin_lock_irqsave(&bank->lock, flags);

	out_ctrl = readl(sgpio->chip.regs + offset);
	if (value)
		out_ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK;
	else
		out_ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK;

	out_ctrl &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
	out_ctrl |= SIRFSOC_GPIO_CTL_OUT_EN_MASK;
	writel(out_ctrl, sgpio->chip.regs + offset);

	spin_unlock_irqrestore(&bank->lock, flags);
}

static int sirfsoc_gpio_direction_output(struct gpio_chip *chip,
	unsigned gpio, int value)
{
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, gpio);
	int idx = sirfsoc_gpio_to_bankoff(gpio);
	u32 offset;
	unsigned long flags;

	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);

	spin_lock_irqsave(&sgpio->lock, flags);

	sirfsoc_gpio_set_output(sgpio, bank, offset, value);

	spin_unlock_irqrestore(&sgpio->lock, flags);

	return 0;
}

static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset)
{
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset);
	u32 val;
	unsigned long flags;

	spin_lock_irqsave(&bank->lock, flags);

	val = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));

	spin_unlock_irqrestore(&bank->lock, flags);

	return !!(val & SIRFSOC_GPIO_CTL_DATAIN_MASK);
}

static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset,
	int value)
{
	struct sirfsoc_gpio_chip *sgpio = to_sirfsoc_gpio(chip);
	struct sirfsoc_gpio_bank *bank = sirfsoc_gpio_to_bank(sgpio, offset);
	u32 ctrl;
	unsigned long flags;

	spin_lock_irqsave(&bank->lock, flags);

	ctrl = readl(sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));
	if (value)
		ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK;
	else
		ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK;
	writel(ctrl, sgpio->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));

	spin_unlock_irqrestore(&bank->lock, flags);
}

static void sirfsoc_gpio_set_pullup(struct sirfsoc_gpio_chip *sgpio,
				    const u32 *pullups)
{
	int i, n;
	const unsigned long *p = (const unsigned long *)pullups;

	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
		for_each_set_bit(n, p + i, BITS_PER_LONG) {
			u32 offset = SIRFSOC_GPIO_CTRL(i, n);
			u32 val = readl(sgpio->chip.regs + offset);
			val |= SIRFSOC_GPIO_CTL_PULL_MASK;
			val |= SIRFSOC_GPIO_CTL_PULL_HIGH;
			writel(val, sgpio->chip.regs + offset);
		}
	}
}

static void sirfsoc_gpio_set_pulldown(struct sirfsoc_gpio_chip *sgpio,
				      const u32 *pulldowns)
{
	int i, n;
	const unsigned long *p = (const unsigned long *)pulldowns;

	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
		for_each_set_bit(n, p + i, BITS_PER_LONG) {
			u32 offset = SIRFSOC_GPIO_CTRL(i, n);
			u32 val = readl(sgpio->chip.regs + offset);
			val |= SIRFSOC_GPIO_CTL_PULL_MASK;
			val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH;
			writel(val, sgpio->chip.regs + offset);
		}
	}
}

static int sirfsoc_gpio_probe(struct device_node *np)
{
	int i, err = 0;
	static struct sirfsoc_gpio_chip *sgpio;
	struct sirfsoc_gpio_bank *bank;
	void __iomem *regs;
	struct platform_device *pdev;

	u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS];

	pdev = of_find_device_by_node(np);
	if (!pdev)
		return -ENODEV;

	sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL);
	if (!sgpio)
		return -ENOMEM;
	spin_lock_init(&sgpio->lock);

	regs = of_iomap(np, 0);
	if (!regs)
		return -ENOMEM;

	sgpio->chip.gc.request = sirfsoc_gpio_request;
	sgpio->chip.gc.free = sirfsoc_gpio_free;
	sgpio->chip.gc.direction_input = sirfsoc_gpio_direction_input;
	sgpio->chip.gc.get = sirfsoc_gpio_get_value;
	sgpio->chip.gc.direction_output = sirfsoc_gpio_direction_output;
	sgpio->chip.gc.set = sirfsoc_gpio_set_value;
	sgpio->chip.gc.base = 0;
	sgpio->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS;
	sgpio->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL);
	sgpio->chip.gc.of_node = np;
	sgpio->chip.gc.of_xlate = sirfsoc_gpio_of_xlate;
	sgpio->chip.gc.of_gpio_n_cells = 2;
	sgpio->chip.gc.dev = &pdev->dev;
	sgpio->chip.regs = regs;

	err = gpiochip_add(&sgpio->chip.gc);
	if (err) {
		dev_err(&pdev->dev, "%s: error in probe function with status %d\n",
			np->full_name, err);
		goto out;
	}

	err =  gpiochip_irqchip_add(&sgpio->chip.gc,
		&sirfsoc_irq_chip,
		0, handle_level_irq,
		IRQ_TYPE_NONE);
	if (err) {
		dev_err(&pdev->dev,
			"could not connect irqchip to gpiochip\n");
		goto out_banks;
	}

	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
		bank = &sgpio->sgpio_bank[i];
		spin_lock_init(&bank->lock);
		bank->parent_irq = platform_get_irq(pdev, i);
		if (bank->parent_irq < 0) {
			err = bank->parent_irq;
			goto out_banks;
		}

		gpiochip_set_chained_irqchip(&sgpio->chip.gc,
			&sirfsoc_irq_chip,
			bank->parent_irq,
			sirfsoc_gpio_handle_irq);
	}

	err = gpiochip_add_pin_range(&sgpio->chip.gc, dev_name(&pdev->dev),
		0, 0, SIRFSOC_GPIO_BANK_SIZE * SIRFSOC_GPIO_NO_OF_BANKS);
	if (err) {
		dev_err(&pdev->dev,
			"could not add gpiochip pin range\n");
		goto out_no_range;
	}

	if (!of_property_read_u32_array(np, "sirf,pullups", pullups,
		SIRFSOC_GPIO_NO_OF_BANKS))
		sirfsoc_gpio_set_pullup(sgpio, pullups);

	if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns,
		SIRFSOC_GPIO_NO_OF_BANKS))
		sirfsoc_gpio_set_pulldown(sgpio, pulldowns);

	return 0;

out_no_range:
out_banks:
	gpiochip_remove(&sgpio->chip.gc);
out:
	iounmap(regs);
	return err;
}

static int __init sirfsoc_gpio_init(void)
{

	struct device_node *np;

	np = of_find_matching_node(NULL, pinmux_ids);

	if (!np)
		return -ENODEV;

	return sirfsoc_gpio_probe(np);
}
subsys_initcall(sirfsoc_gpio_init);

MODULE_AUTHOR("Rongjun Ying <rongjun.ying@csr.com>");
MODULE_AUTHOR("Yuping Luo <yuping.luo@csr.com>");
MODULE_AUTHOR("Barry Song <baohua.song@csr.com>");
MODULE_DESCRIPTION("SIRFSOC pin control driver");
MODULE_LICENSE("GPL");
