/* langwell_gpio.c Moorestown platform Langwell chip GPIO driver
 * Copyright (c) 2008 - 2009,  Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Supports:
 * Moorestown platform Langwell chip.
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/stddef.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/slab.h>

struct lnw_gpio_register {
	u32	GPLR[2];
	u32	GPDR[2];
	u32	GPSR[2];
	u32	GPCR[2];
	u32	GRER[2];
	u32	GFER[2];
	u32	GEDR[2];
};

struct lnw_gpio {
	struct gpio_chip		chip;
	struct lnw_gpio_register 	*reg_base;
	spinlock_t			lock;
	unsigned			irq_base;
};

static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
	u8 reg = offset / 32;
	void __iomem *gplr;

	gplr = (void __iomem *)(&lnw->reg_base->GPLR[reg]);
	return readl(gplr) & BIT(offset % 32);
}

static void lnw_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
	u8 reg = offset / 32;
	void __iomem *gpsr, *gpcr;

	if (value) {
		gpsr = (void __iomem *)(&lnw->reg_base->GPSR[reg]);
		writel(BIT(offset % 32), gpsr);
	} else {
		gpcr = (void __iomem *)(&lnw->reg_base->GPCR[reg]);
		writel(BIT(offset % 32), gpcr);
	}
}

static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
	struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
	u8 reg = offset / 32;
	u32 value;
	unsigned long flags;
	void __iomem *gpdr;

	gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]);
	spin_lock_irqsave(&lnw->lock, flags);
	value = readl(gpdr);
	value &= ~BIT(offset % 32);
	writel(value, gpdr);
	spin_unlock_irqrestore(&lnw->lock, flags);
	return 0;
}

static int lnw_gpio_direction_output(struct gpio_chip *chip,
			unsigned offset, int value)
{
	struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
	u8 reg = offset / 32;
	unsigned long flags;
	void __iomem *gpdr;

	lnw_gpio_set(chip, offset, value);
	gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]);
	spin_lock_irqsave(&lnw->lock, flags);
	value = readl(gpdr);
	value |= BIT(offset % 32);;
	writel(value, gpdr);
	spin_unlock_irqrestore(&lnw->lock, flags);
	return 0;
}

static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
	struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
	return lnw->irq_base + offset;
}

static int lnw_irq_type(unsigned irq, unsigned type)
{
	struct lnw_gpio *lnw = get_irq_chip_data(irq);
	u32 gpio = irq - lnw->irq_base;
	u8 reg = gpio / 32;
	unsigned long flags;
	u32 value;
	void __iomem *grer = (void __iomem *)(&lnw->reg_base->GRER[reg]);
	void __iomem *gfer = (void __iomem *)(&lnw->reg_base->GFER[reg]);

	if (gpio >= lnw->chip.ngpio)
		return -EINVAL;
	spin_lock_irqsave(&lnw->lock, flags);
	if (type & IRQ_TYPE_EDGE_RISING)
		value = readl(grer) | BIT(gpio % 32);
	else
		value = readl(grer) & (~BIT(gpio % 32));
	writel(value, grer);

	if (type & IRQ_TYPE_EDGE_FALLING)
		value = readl(gfer) | BIT(gpio % 32);
	else
		value = readl(gfer) & (~BIT(gpio % 32));
	writel(value, gfer);
	spin_unlock_irqrestore(&lnw->lock, flags);

	return 0;
};

static void lnw_irq_unmask(unsigned irq)
{
};

static void lnw_irq_mask(unsigned irq)
{
};

static struct irq_chip lnw_irqchip = {
	.name		= "LNW-GPIO",
	.mask		= lnw_irq_mask,
	.unmask		= lnw_irq_unmask,
	.set_type	= lnw_irq_type,
};

static struct pci_device_id lnw_gpio_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f) },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);

static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
{
	struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq);
	u32 reg, gpio;
	void __iomem *gedr;
	u32 gedr_v;

	/* check GPIO controller to check which pin triggered the interrupt */
	for (reg = 0; reg < lnw->chip.ngpio / 32; reg++) {
		gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
		gedr_v = readl(gedr);
		if (!gedr_v)
			continue;
		for (gpio = reg*32; gpio < reg*32+32; gpio++)
			if (gedr_v & BIT(gpio % 32)) {
				pr_debug("pin %d triggered\n", gpio);
				generic_handle_irq(lnw->irq_base + gpio);
			}
		/* clear the edge detect status bit */
		writel(gedr_v, gedr);
	}
	desc->chip->eoi(irq);
}

static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
			const struct pci_device_id *id)
{
	void *base;
	int i;
	resource_size_t start, len;
	struct lnw_gpio *lnw;
	u32 irq_base;
	u32 gpio_base;
	int retval = 0;

	retval = pci_enable_device(pdev);
	if (retval)
		goto done;

	retval = pci_request_regions(pdev, "langwell_gpio");
	if (retval) {
		dev_err(&pdev->dev, "error requesting resources\n");
		goto err2;
	}
	/* get the irq_base from bar1 */
	start = pci_resource_start(pdev, 1);
	len = pci_resource_len(pdev, 1);
	base = ioremap_nocache(start, len);
	if (!base) {
		dev_err(&pdev->dev, "error mapping bar1\n");
		goto err3;
	}
	irq_base = *(u32 *)base;
	gpio_base = *((u32 *)base + 1);
	/* release the IO mapping, since we already get the info from bar1 */
	iounmap(base);
	/* get the register base from bar0 */
	start = pci_resource_start(pdev, 0);
	len = pci_resource_len(pdev, 0);
	base = ioremap_nocache(start, len);
	if (!base) {
		dev_err(&pdev->dev, "error mapping bar0\n");
		retval = -EFAULT;
		goto err3;
	}

	lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL);
	if (!lnw) {
		dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n");
		retval = -ENOMEM;
		goto err4;
	}
	lnw->reg_base = base;
	lnw->irq_base = irq_base;
	lnw->chip.label = dev_name(&pdev->dev);
	lnw->chip.direction_input = lnw_gpio_direction_input;
	lnw->chip.direction_output = lnw_gpio_direction_output;
	lnw->chip.get = lnw_gpio_get;
	lnw->chip.set = lnw_gpio_set;
	lnw->chip.to_irq = lnw_gpio_to_irq;
	lnw->chip.base = gpio_base;
	lnw->chip.ngpio = 64;
	lnw->chip.can_sleep = 0;
	pci_set_drvdata(pdev, lnw);
	retval = gpiochip_add(&lnw->chip);
	if (retval) {
		dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
		goto err5;
	}
	set_irq_data(pdev->irq, lnw);
	set_irq_chained_handler(pdev->irq, lnw_irq_handler);
	for (i = 0; i < lnw->chip.ngpio; i++) {
		set_irq_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip,
					handle_simple_irq, "demux");
		set_irq_chip_data(i + lnw->irq_base, lnw);
	}

	spin_lock_init(&lnw->lock);
	goto done;
err5:
	kfree(lnw);
err4:
	iounmap(base);
err3:
	pci_release_regions(pdev);
err2:
	pci_disable_device(pdev);
done:
	return retval;
}

static struct pci_driver lnw_gpio_driver = {
	.name		= "langwell_gpio",
	.id_table	= lnw_gpio_ids,
	.probe		= lnw_gpio_probe,
};

static int __init lnw_gpio_init(void)
{
	return pci_register_driver(&lnw_gpio_driver);
}

device_initcall(lnw_gpio_init);
