/*
 * 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 in
 *				interrupt context ioh_irq_type and PM;
 */
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;
	struct mutex lock;
	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);

	mutex_lock(&chip->lock);
	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);
	mutex_unlock(&chip->lock);
}

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;

	mutex_lock(&chip->lock);
	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);

	mutex_unlock(&chip->lock);

	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;

	mutex_lock(&chip->lock);
	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);
	mutex_unlock(&chip->lock);

	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;
	u32 *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 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++) {
		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 __devinit 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;

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

static int __devinit 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 __iomem *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 == 0) {
		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;
		mutex_init(&chip->lock);
		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;
			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--;
		ret = gpiochip_remove(&chip->gpio);
		if (ret)
			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 __devexit ioh_gpio_remove(struct pci_dev *pdev)
{
	int err;
	int i;
	struct ioh_gpio *chip = pci_get_drvdata(pdev);
	void __iomem *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 = __devexit_p(ioh_gpio_remove),
	.suspend = ioh_gpio_suspend,
	.resume = ioh_gpio_resume
};

static int __init ioh_gpio_pci_init(void)
{
	return pci_register_driver(&ioh_gpio_driver);
}
module_init(ioh_gpio_pci_init);

static void __exit ioh_gpio_pci_exit(void)
{
	pci_unregister_driver(&ioh_gpio_driver);
}
module_exit(ioh_gpio_pci_exit);

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