/*
 * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
 *
 * 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 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>

#define IOH_EDGE_FALLING	0
#define IOH_EDGE_RISING		BIT(0)
#define IOH_LEVEL_L		BIT(1)
#define IOH_LEVEL_H		(BIT(0) | BIT(1))
#define IOH_EDGE_BOTH		BIT(2)
#define IOH_IM_MASK		(BIT(0) | BIT(1) | BIT(2))

#define IOH_IRQ_BASE		0

#define PCI_VENDOR_ID_ROHM             0x10DB

struct ioh_reg_comn {
	u32	ien;
	u32	istatus;
	u32	idisp;
	u32	iclr;
	u32	imask;
	u32	imaskclr;
	u32	po;
	u32	pi;
	u32	pm;
	u32	im_0;
	u32	im_1;
	u32	reserved;
};

struct ioh_regs {
	struct ioh_reg_comn regs[8];
	u32 reserve1[16];
	u32 ioh_sel_reg[4];
	u32 reserve2[11];
	u32 srst;
};

/**
 * struct ioh_gpio_reg_data - The register store data.
 * @ien_reg	To store contents of interrupt enable register.
 * @imask_reg:	To store contents of interrupt mask regist
 * @po_reg:	To store contents of PO register.
 * @pm_reg:	To store contents of PM register.
 * @im0_reg:	To store contents of interrupt mode regist0
 * @im1_reg:	To store contents of interrupt mode regist1
 * @use_sel_reg: To store contents of GPIO_USE_SEL0~3
 */
struct ioh_gpio_reg_data {
	u32 ien_reg;
	u32 imask_reg;
	u32 po_reg;
	u32 pm_reg;
	u32 im0_reg;
	u32 im1_reg;
	u32 use_sel_reg;
};

/**
 * struct ioh_gpio - GPIO private data structure.
 * @base:			PCI base address of Memory mapped I/O register.
 * @reg:			Memory mapped IOH GPIO register list.
 * @dev:			Pointer to device structure.
 * @gpio:			Data for GPIO infrastructure.
 * @ioh_gpio_reg:		Memory mapped Register data is saved here
 *				when suspend.
 * @gpio_use_sel:		Save GPIO_USE_SEL1~4 register for PM
 * @ch:				Indicate GPIO channel
 * @irq_base:		Save base of IRQ number for interrupt
 * @spinlock:		Used for register access protection
 */
struct ioh_gpio {
	void __iomem *base;
	struct ioh_regs __iomem *reg;
	struct device *dev;
	struct gpio_chip gpio;
	struct ioh_gpio_reg_data ioh_gpio_reg;
	u32 gpio_use_sel;
	int ch;
	int irq_base;
	spinlock_t spinlock;
};

static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12};

static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
{
	u32 reg_val;
	struct ioh_gpio *chip =	container_of(gpio, struct ioh_gpio, gpio);
	unsigned long flags;

	spin_lock_irqsave(&chip->spinlock, flags);
	reg_val = ioread32(&chip->reg->regs[chip->ch].po);
	if (val)
		reg_val |= (1 << nr);
	else
		reg_val &= ~(1 << nr);

	iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
	spin_unlock_irqrestore(&chip->spinlock, flags);
}

static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr)
{
	struct ioh_gpio *chip =	container_of(gpio, struct ioh_gpio, gpio);

	return ioread32(&chip->reg->regs[chip->ch].pi) & (1 << nr);
}

static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
				     int val)
{
	struct ioh_gpio *chip =	container_of(gpio, struct ioh_gpio, gpio);
	u32 pm;
	u32 reg_val;
	unsigned long flags;

	spin_lock_irqsave(&chip->spinlock, flags);
	pm = ioread32(&chip->reg->regs[chip->ch].pm) &
					((1 << num_ports[chip->ch]) - 1);
	pm |= (1 << nr);
	iowrite32(pm, &chip->reg->regs[chip->ch].pm);

	reg_val = ioread32(&chip->reg->regs[chip->ch].po);
	if (val)
		reg_val |= (1 << nr);
	else
		reg_val &= ~(1 << nr);
	iowrite32(reg_val, &chip->reg->regs[chip->ch].po);

	spin_unlock_irqrestore(&chip->spinlock, flags);

	return 0;
}

static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
{
	struct ioh_gpio *chip =	container_of(gpio, struct ioh_gpio, gpio);
	u32 pm;
	unsigned long flags;

	spin_lock_irqsave(&chip->spinlock, flags);
	pm = ioread32(&chip->reg->regs[chip->ch].pm) &
				((1 << num_ports[chip->ch]) - 1);
	pm &= ~(1 << nr);
	iowrite32(pm, &chip->reg->regs[chip->ch].pm);
	spin_unlock_irqrestore(&chip->spinlock, flags);

	return 0;
}

#ifdef CONFIG_PM
/*
 * Save register configuration and disable interrupts.
 */
static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip)
{
	int i;

	for (i = 0; i < 8; i ++, chip++) {
		chip->ioh_gpio_reg.po_reg =
					ioread32(&chip->reg->regs[chip->ch].po);
		chip->ioh_gpio_reg.pm_reg =
					ioread32(&chip->reg->regs[chip->ch].pm);
		chip->ioh_gpio_reg.ien_reg =
				       ioread32(&chip->reg->regs[chip->ch].ien);
		chip->ioh_gpio_reg.imask_reg =
				     ioread32(&chip->reg->regs[chip->ch].imask);
		chip->ioh_gpio_reg.im0_reg =
				      ioread32(&chip->reg->regs[chip->ch].im_0);
		chip->ioh_gpio_reg.im1_reg =
				      ioread32(&chip->reg->regs[chip->ch].im_1);
		if (i < 4)
			chip->ioh_gpio_reg.use_sel_reg =
					   ioread32(&chip->reg->ioh_sel_reg[i]);
	}
}

/*
 * This function restores the register configuration of the GPIO device.
 */
static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip)
{
	int i;

	for (i = 0; i < 8; i ++, chip++) {
		iowrite32(chip->ioh_gpio_reg.po_reg,
			  &chip->reg->regs[chip->ch].po);
		iowrite32(chip->ioh_gpio_reg.pm_reg,
			  &chip->reg->regs[chip->ch].pm);
		iowrite32(chip->ioh_gpio_reg.ien_reg,
			  &chip->reg->regs[chip->ch].ien);
		iowrite32(chip->ioh_gpio_reg.imask_reg,
			  &chip->reg->regs[chip->ch].imask);
		iowrite32(chip->ioh_gpio_reg.im0_reg,
			  &chip->reg->regs[chip->ch].im_0);
		iowrite32(chip->ioh_gpio_reg.im1_reg,
			  &chip->reg->regs[chip->ch].im_1);
		if (i < 4)
			iowrite32(chip->ioh_gpio_reg.use_sel_reg,
				  &chip->reg->ioh_sel_reg[i]);
	}
}
#endif

static int ioh_gpio_to_irq(struct gpio_chip *gpio, unsigned offset)
{
	struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio);
	return chip->irq_base + offset;
}

static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port)
{
	struct gpio_chip *gpio = &chip->gpio;

	gpio->label = dev_name(chip->dev);
	gpio->owner = THIS_MODULE;
	gpio->direction_input = ioh_gpio_direction_input;
	gpio->get = ioh_gpio_get;
	gpio->direction_output = ioh_gpio_direction_output;
	gpio->set = ioh_gpio_set;
	gpio->dbg_show = NULL;
	gpio->base = -1;
	gpio->ngpio = num_port;
	gpio->can_sleep = 0;
	gpio->to_irq = ioh_gpio_to_irq;
}

static int ioh_irq_type(struct irq_data *d, unsigned int type)
{
	u32 im;
	void __iomem *im_reg;
	u32 ien;
	u32 im_pos;
	int ch;
	unsigned long flags;
	u32 val;
	int irq = d->irq;
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct ioh_gpio *chip = gc->private;

	ch = irq - chip->irq_base;
	if (irq <= chip->irq_base + 7) {
		im_reg = &chip->reg->regs[chip->ch].im_0;
		im_pos = ch;
	} else {
		im_reg = &chip->reg->regs[chip->ch].im_1;
		im_pos = ch - 8;
	}
	dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d type=%d\n",
		__func__, irq, type, ch, im_pos, type);

	spin_lock_irqsave(&chip->spinlock, flags);

	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
		val = IOH_EDGE_RISING;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		val = IOH_EDGE_FALLING;
		break;
	case IRQ_TYPE_EDGE_BOTH:
		val = IOH_EDGE_BOTH;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		val = IOH_LEVEL_H;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		val = IOH_LEVEL_L;
		break;
	case IRQ_TYPE_PROBE:
		goto end;
	default:
		dev_warn(chip->dev, "%s: unknown type(%dd)",
			__func__, type);
		goto end;
	}

	/* Set interrupt mode */
	im = ioread32(im_reg) & ~(IOH_IM_MASK << (im_pos * 4));
	iowrite32(im | (val << (im_pos * 4)), im_reg);

	/* iclr */
	iowrite32(BIT(ch), &chip->reg->regs[chip->ch].iclr);

	/* IMASKCLR */
	iowrite32(BIT(ch), &chip->reg->regs[chip->ch].imaskclr);

	/* Enable interrupt */
	ien = ioread32(&chip->reg->regs[chip->ch].ien);
	iowrite32(ien | BIT(ch), &chip->reg->regs[chip->ch].ien);
end:
	spin_unlock_irqrestore(&chip->spinlock, flags);

	return 0;
}

static void ioh_irq_unmask(struct irq_data *d)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct ioh_gpio *chip = gc->private;

	iowrite32(1 << (d->irq - chip->irq_base),
		  &chip->reg->regs[chip->ch].imaskclr);
}

static void ioh_irq_mask(struct irq_data *d)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct ioh_gpio *chip = gc->private;

	iowrite32(1 << (d->irq - chip->irq_base),
		  &chip->reg->regs[chip->ch].imask);
}

static void ioh_irq_disable(struct irq_data *d)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct ioh_gpio *chip = gc->private;
	unsigned long flags;
	u32 ien;

	spin_lock_irqsave(&chip->spinlock, flags);
	ien = ioread32(&chip->reg->regs[chip->ch].ien);
	ien &= ~(1 << (d->irq - chip->irq_base));
	iowrite32(ien, &chip->reg->regs[chip->ch].ien);
	spin_unlock_irqrestore(&chip->spinlock, flags);
}

static void ioh_irq_enable(struct irq_data *d)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct ioh_gpio *chip = gc->private;
	unsigned long flags;
	u32 ien;

	spin_lock_irqsave(&chip->spinlock, flags);
	ien = ioread32(&chip->reg->regs[chip->ch].ien);
	ien |= 1 << (d->irq - chip->irq_base);
	iowrite32(ien, &chip->reg->regs[chip->ch].ien);
	spin_unlock_irqrestore(&chip->spinlock, flags);
}

static irqreturn_t ioh_gpio_handler(int irq, void *dev_id)
{
	struct ioh_gpio *chip = dev_id;
	u32 reg_val;
	int i, j;
	int ret = IRQ_NONE;

	for (i = 0; i < 8; i++, chip++) {
		reg_val = ioread32(&chip->reg->regs[i].istatus);
		for (j = 0; j < num_ports[i]; j++) {
			if (reg_val & BIT(j)) {
				dev_dbg(chip->dev,
					"%s:[%d]:irq=%d status=0x%x\n",
					__func__, j, irq, reg_val);
				iowrite32(BIT(j),
					  &chip->reg->regs[chip->ch].iclr);
				generic_handle_irq(chip->irq_base + j);
				ret = IRQ_HANDLED;
			}
		}
	}
	return ret;
}

static void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip,
				unsigned int irq_start, unsigned int num)
{
	struct irq_chip_generic *gc;
	struct irq_chip_type *ct;

	gc = irq_alloc_generic_chip("ioh_gpio", 1, irq_start, chip->base,
				    handle_simple_irq);
	gc->private = chip;
	ct = gc->chip_types;

	ct->chip.irq_mask = ioh_irq_mask;
	ct->chip.irq_unmask = ioh_irq_unmask;
	ct->chip.irq_set_type = ioh_irq_type;
	ct->chip.irq_disable = ioh_irq_disable;
	ct->chip.irq_enable = ioh_irq_enable;

	irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
}

static int ioh_gpio_probe(struct pci_dev *pdev,
				    const struct pci_device_id *id)
{
	int ret;
	int i, j;
	struct ioh_gpio *chip;
	void __iomem *base;
	void *chip_save;
	int irq_base;

	ret = pci_enable_device(pdev);
	if (ret) {
		dev_err(&pdev->dev, "%s : pci_enable_device failed", __func__);
		goto err_pci_enable;
	}

	ret = pci_request_regions(pdev, KBUILD_MODNAME);
	if (ret) {
		dev_err(&pdev->dev, "pci_request_regions failed-%d", ret);
		goto err_request_regions;
	}

	base = pci_iomap(pdev, 1, 0);
	if (!base) {
		dev_err(&pdev->dev, "%s : pci_iomap failed", __func__);
		ret = -ENOMEM;
		goto err_iomap;
	}

	chip_save = kzalloc(sizeof(*chip) * 8, GFP_KERNEL);
	if (chip_save == NULL) {
		dev_err(&pdev->dev, "%s : kzalloc failed", __func__);
		ret = -ENOMEM;
		goto err_kzalloc;
	}

	chip = chip_save;
	for (i = 0; i < 8; i++, chip++) {
		chip->dev = &pdev->dev;
		chip->base = base;
		chip->reg = chip->base;
		chip->ch = i;
		spin_lock_init(&chip->spinlock);
		ioh_gpio_setup(chip, num_ports[i]);
		ret = gpiochip_add(&chip->gpio);
		if (ret) {
			dev_err(&pdev->dev, "IOH gpio: Failed to register GPIO\n");
			goto err_gpiochip_add;
		}
	}

	chip = chip_save;
	for (j = 0; j < 8; j++, chip++) {
		irq_base = irq_alloc_descs(-1, IOH_IRQ_BASE, num_ports[j],
					   NUMA_NO_NODE);
		if (irq_base < 0) {
			dev_warn(&pdev->dev,
				"ml_ioh_gpio: Failed to get IRQ base num\n");
			chip->irq_base = -1;
			ret = irq_base;
			goto err_irq_alloc_descs;
		}
		chip->irq_base = irq_base;
		ioh_gpio_alloc_generic_chip(chip, irq_base, num_ports[j]);
	}

	chip = chip_save;
	ret = request_irq(pdev->irq, ioh_gpio_handler,
			     IRQF_SHARED, KBUILD_MODNAME, chip);
	if (ret != 0) {
		dev_err(&pdev->dev,
			"%s request_irq failed\n", __func__);
		goto err_request_irq;
	}

	pci_set_drvdata(pdev, chip);

	return 0;

err_request_irq:
	chip = chip_save;
err_irq_alloc_descs:
	while (--j >= 0) {
		chip--;
		irq_free_descs(chip->irq_base, num_ports[j]);
	}

	chip = chip_save;
err_gpiochip_add:
	while (--i >= 0) {
		chip--;
		if (gpiochip_remove(&chip->gpio))
			dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i);
	}
	kfree(chip_save);

err_kzalloc:
	pci_iounmap(pdev, base);

err_iomap:
	pci_release_regions(pdev);

err_request_regions:
	pci_disable_device(pdev);

err_pci_enable:

	dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret);
	return ret;
}

static void ioh_gpio_remove(struct pci_dev *pdev)
{
	int err;
	int i;
	struct ioh_gpio *chip = pci_get_drvdata(pdev);
	void *chip_save;

	chip_save = chip;

	free_irq(pdev->irq, chip);

	for (i = 0; i < 8; i++, chip++) {
		irq_free_descs(chip->irq_base, num_ports[i]);
		err = gpiochip_remove(&chip->gpio);
		if (err)
			dev_err(&pdev->dev, "Failed gpiochip_remove\n");
	}

	chip = chip_save;
	pci_iounmap(pdev, chip->base);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
	kfree(chip);
}

#ifdef CONFIG_PM
static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state)
{
	s32 ret;
	struct ioh_gpio *chip = pci_get_drvdata(pdev);
	unsigned long flags;

	spin_lock_irqsave(&chip->spinlock, flags);
	ioh_gpio_save_reg_conf(chip);
	spin_unlock_irqrestore(&chip->spinlock, flags);

	ret = pci_save_state(pdev);
	if (ret) {
		dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret);
		return ret;
	}
	pci_disable_device(pdev);
	pci_set_power_state(pdev, PCI_D0);
	ret = pci_enable_wake(pdev, PCI_D0, 1);
	if (ret)
		dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret);

	return 0;
}

static int ioh_gpio_resume(struct pci_dev *pdev)
{
	s32 ret;
	struct ioh_gpio *chip = pci_get_drvdata(pdev);
	unsigned long flags;

	ret = pci_enable_wake(pdev, PCI_D0, 0);

	pci_set_power_state(pdev, PCI_D0);
	ret = pci_enable_device(pdev);
	if (ret) {
		dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret);
		return ret;
	}
	pci_restore_state(pdev);

	spin_lock_irqsave(&chip->spinlock, flags);
	iowrite32(0x01, &chip->reg->srst);
	iowrite32(0x00, &chip->reg->srst);
	ioh_gpio_restore_reg_conf(chip);
	spin_unlock_irqrestore(&chip->spinlock, flags);

	return 0;
}
#else
#define ioh_gpio_suspend NULL
#define ioh_gpio_resume NULL
#endif

static DEFINE_PCI_DEVICE_TABLE(ioh_gpio_pcidev_id) = {
	{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, ioh_gpio_pcidev_id);

static struct pci_driver ioh_gpio_driver = {
	.name = "ml_ioh_gpio",
	.id_table = ioh_gpio_pcidev_id,
	.probe = ioh_gpio_probe,
	.remove = ioh_gpio_remove,
	.suspend = ioh_gpio_suspend,
	.resume = ioh_gpio_resume
};

module_pci_driver(ioh_gpio_driver);

MODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver");
MODULE_LICENSE("GPL");
