/*
 * A gpio chip driver for TXx9 SoCs
 *
 * Copyright (C) 2008 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
 *
 * 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.
 */

#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/gpio.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <asm/txx9pio.h>

static DEFINE_SPINLOCK(txx9_gpio_lock);

static struct txx9_pio_reg __iomem *txx9_pioptr;

static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	return __raw_readl(&txx9_pioptr->din) & (1 << offset);
}

static void txx9_gpio_set_raw(unsigned int offset, int value)
{
	u32 val;
	val = __raw_readl(&txx9_pioptr->dout);
	if (value)
		val |= 1 << offset;
	else
		val &= ~(1 << offset);
	__raw_writel(val, &txx9_pioptr->dout);
}

static void txx9_gpio_set(struct gpio_chip *chip, unsigned int offset,
			  int value)
{
	unsigned long flags;
	spin_lock_irqsave(&txx9_gpio_lock, flags);
	txx9_gpio_set_raw(offset, value);
	mmiowb();
	spin_unlock_irqrestore(&txx9_gpio_lock, flags);
}

static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset)
{
	unsigned long flags;
	spin_lock_irqsave(&txx9_gpio_lock, flags);
	__raw_writel(__raw_readl(&txx9_pioptr->dir) & ~(1 << offset),
		     &txx9_pioptr->dir);
	mmiowb();
	spin_unlock_irqrestore(&txx9_gpio_lock, flags);
	return 0;
}

static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset,
			     int value)
{
	unsigned long flags;
	spin_lock_irqsave(&txx9_gpio_lock, flags);
	txx9_gpio_set_raw(offset, value);
	__raw_writel(__raw_readl(&txx9_pioptr->dir) | (1 << offset),
		     &txx9_pioptr->dir);
	mmiowb();
	spin_unlock_irqrestore(&txx9_gpio_lock, flags);
	return 0;
}

static struct gpio_chip txx9_gpio_chip = {
	.get = txx9_gpio_get,
	.set = txx9_gpio_set,
	.direction_input = txx9_gpio_dir_in,
	.direction_output = txx9_gpio_dir_out,
	.label = "TXx9",
};

int __init txx9_gpio_init(unsigned long baseaddr,
			  unsigned int base, unsigned int num)
{
	txx9_pioptr = ioremap(baseaddr, sizeof(struct txx9_pio_reg));
	if (!txx9_pioptr)
		return -ENODEV;
	txx9_gpio_chip.base = base;
	txx9_gpio_chip.ngpio = num;
	return gpiochip_add(&txx9_gpio_chip);
}
