// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-sa1100/gpio.c
 *
 * Generic SA-1100 GPIO handling
 */
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/syscore_ops.h>
#include <soc/sa1100/pwer.h>
#include <mach/hardware.h>
#include <mach/irqs.h>

struct sa1100_gpio_chip {
	struct gpio_chip chip;
	void __iomem *membase;
	int irqbase;
	u32 irqmask;
	u32 irqrising;
	u32 irqfalling;
	u32 irqwake;
};

#define sa1100_gpio_chip(x) container_of(x, struct sa1100_gpio_chip, chip)

enum {
	R_GPLR = 0x00,
	R_GPDR = 0x04,
	R_GPSR = 0x08,
	R_GPCR = 0x0c,
	R_GRER = 0x10,
	R_GFER = 0x14,
	R_GEDR = 0x18,
	R_GAFR = 0x1c,
};

static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	return readl_relaxed(sa1100_gpio_chip(chip)->membase + R_GPLR) &
		BIT(offset);
}

static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	int reg = value ? R_GPSR : R_GPCR;

	writel_relaxed(BIT(offset), sa1100_gpio_chip(chip)->membase + reg);
}

static int sa1100_get_direction(struct gpio_chip *chip, unsigned offset)
{
	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;

	if (readl_relaxed(gpdr) & BIT(offset))
		return GPIO_LINE_DIRECTION_OUT;

	return GPIO_LINE_DIRECTION_IN;
}

static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset)
{
	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
	unsigned long flags;

	local_irq_save(flags);
	writel_relaxed(readl_relaxed(gpdr) & ~BIT(offset), gpdr);
	local_irq_restore(flags);

	return 0;
}

static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value)
{
	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
	unsigned long flags;

	local_irq_save(flags);
	sa1100_gpio_set(chip, offset, value);
	writel_relaxed(readl_relaxed(gpdr) | BIT(offset), gpdr);
	local_irq_restore(flags);

	return 0;
}

static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset)
{
	return sa1100_gpio_chip(chip)->irqbase + offset;
}

static struct sa1100_gpio_chip sa1100_gpio_chip = {
	.chip = {
		.label			= "gpio",
		.get_direction		= sa1100_get_direction,
		.direction_input	= sa1100_direction_input,
		.direction_output	= sa1100_direction_output,
		.set			= sa1100_gpio_set,
		.get			= sa1100_gpio_get,
		.to_irq			= sa1100_to_irq,
		.base			= 0,
		.ngpio			= GPIO_MAX + 1,
	},
	.membase = (void *)&GPLR,
	.irqbase = IRQ_GPIO0,
};

/*
 * SA1100 GPIO edge detection for IRQs:
 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
 * Use this instead of directly setting GRER/GFER.
 */
static void sa1100_update_edge_regs(struct sa1100_gpio_chip *sgc)
{
	void *base = sgc->membase;
	u32 grer, gfer;

	grer = sgc->irqrising & sgc->irqmask;
	gfer = sgc->irqfalling & sgc->irqmask;

	writel_relaxed(grer, base + R_GRER);
	writel_relaxed(gfer, base + R_GFER);
}

static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
{
	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
	unsigned int mask = BIT(d->hwirq);

	if (type == IRQ_TYPE_PROBE) {
		if ((sgc->irqrising | sgc->irqfalling) & mask)
			return 0;
		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
	}

	if (type & IRQ_TYPE_EDGE_RISING)
		sgc->irqrising |= mask;
	else
		sgc->irqrising &= ~mask;
	if (type & IRQ_TYPE_EDGE_FALLING)
		sgc->irqfalling |= mask;
	else
		sgc->irqfalling &= ~mask;

	sa1100_update_edge_regs(sgc);

	return 0;
}

/*
 * GPIO IRQs must be acknowledged.
 */
static void sa1100_gpio_ack(struct irq_data *d)
{
	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);

	writel_relaxed(BIT(d->hwirq), sgc->membase + R_GEDR);
}

static void sa1100_gpio_mask(struct irq_data *d)
{
	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
	unsigned int mask = BIT(d->hwirq);

	sgc->irqmask &= ~mask;

	sa1100_update_edge_regs(sgc);
}

static void sa1100_gpio_unmask(struct irq_data *d)
{
	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
	unsigned int mask = BIT(d->hwirq);

	sgc->irqmask |= mask;

	sa1100_update_edge_regs(sgc);
}

static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
{
	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
	int ret = sa11x0_gpio_set_wake(d->hwirq, on);
	if (!ret) {
		if (on)
			sgc->irqwake |= BIT(d->hwirq);
		else
			sgc->irqwake &= ~BIT(d->hwirq);
	}
	return ret;
}

/*
 * This is for GPIO IRQs
 */
static struct irq_chip sa1100_gpio_irq_chip = {
	.name		= "GPIO",
	.irq_ack	= sa1100_gpio_ack,
	.irq_mask	= sa1100_gpio_mask,
	.irq_unmask	= sa1100_gpio_unmask,
	.irq_set_type	= sa1100_gpio_type,
	.irq_set_wake	= sa1100_gpio_wake,
};

static int sa1100_gpio_irqdomain_map(struct irq_domain *d,
		unsigned int irq, irq_hw_number_t hwirq)
{
	struct sa1100_gpio_chip *sgc = d->host_data;

	irq_set_chip_data(irq, sgc);
	irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip, handle_edge_irq);
	irq_set_probe(irq);

	return 0;
}

static const struct irq_domain_ops sa1100_gpio_irqdomain_ops = {
	.map = sa1100_gpio_irqdomain_map,
	.xlate = irq_domain_xlate_onetwocell,
};

static struct irq_domain *sa1100_gpio_irqdomain;

/*
 * IRQ 0-11 (GPIO) handler.  We enter here with the
 * irq_controller_lock held, and IRQs disabled.  Decode the IRQ
 * and call the handler.
 */
static void sa1100_gpio_handler(struct irq_desc *desc)
{
	struct sa1100_gpio_chip *sgc = irq_desc_get_handler_data(desc);
	unsigned int irq, mask;
	void __iomem *gedr = sgc->membase + R_GEDR;

	mask = readl_relaxed(gedr);
	do {
		/*
		 * clear down all currently active IRQ sources.
		 * We will be processing them all.
		 */
		writel_relaxed(mask, gedr);

		irq = sgc->irqbase;
		do {
			if (mask & 1)
				generic_handle_irq(irq);
			mask >>= 1;
			irq++;
		} while (mask);

		mask = readl_relaxed(gedr);
	} while (mask);
}

static int sa1100_gpio_suspend(void)
{
	struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip;

	/*
	 * Set the appropriate edges for wakeup.
	 */
	writel_relaxed(sgc->irqwake & sgc->irqrising, sgc->membase + R_GRER);
	writel_relaxed(sgc->irqwake & sgc->irqfalling, sgc->membase + R_GFER);

	/*
	 * Clear any pending GPIO interrupts.
	 */
	writel_relaxed(readl_relaxed(sgc->membase + R_GEDR),
		       sgc->membase + R_GEDR);

	return 0;
}

static void sa1100_gpio_resume(void)
{
	sa1100_update_edge_regs(&sa1100_gpio_chip);
}

static struct syscore_ops sa1100_gpio_syscore_ops = {
	.suspend	= sa1100_gpio_suspend,
	.resume		= sa1100_gpio_resume,
};

static int __init sa1100_gpio_init_devicefs(void)
{
	register_syscore_ops(&sa1100_gpio_syscore_ops);
	return 0;
}

device_initcall(sa1100_gpio_init_devicefs);

static const int sa1100_gpio_irqs[] __initconst = {
	/* Install handlers for GPIO 0-10 edge detect interrupts */
	IRQ_GPIO0_SC,
	IRQ_GPIO1_SC,
	IRQ_GPIO2_SC,
	IRQ_GPIO3_SC,
	IRQ_GPIO4_SC,
	IRQ_GPIO5_SC,
	IRQ_GPIO6_SC,
	IRQ_GPIO7_SC,
	IRQ_GPIO8_SC,
	IRQ_GPIO9_SC,
	IRQ_GPIO10_SC,
	/* Install handler for GPIO 11-27 edge detect interrupts */
	IRQ_GPIO11_27,
};

void __init sa1100_init_gpio(void)
{
	struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip;
	int i;

	/* clear all GPIO edge detects */
	writel_relaxed(0, sgc->membase + R_GFER);
	writel_relaxed(0, sgc->membase + R_GRER);
	writel_relaxed(-1, sgc->membase + R_GEDR);

	gpiochip_add_data(&sa1100_gpio_chip.chip, NULL);

	sa1100_gpio_irqdomain = irq_domain_add_simple(NULL,
			28, IRQ_GPIO0,
			&sa1100_gpio_irqdomain_ops, sgc);

	for (i = 0; i < ARRAY_SIZE(sa1100_gpio_irqs); i++)
		irq_set_chained_handler_and_data(sa1100_gpio_irqs[i],
						 sa1100_gpio_handler, sgc);
}
