Source
x
/*
* linux/arch/arm/mach-sa1100/gpio.c
*
* Generic SA-1100 GPIO handling
*
* 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.
*/
struct sa1100_gpio_chip {
struct gpio_chip chip;
void __iomem *membase;
int irqbase;
u32 irqmask;
u32 irqrising;
u32 irqfalling;
u32 irqwake;
};
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;
return !(readl_relaxed(gpdr) & BIT(offset));
}
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 = {