mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-13 14:04:05 +08:00
40ca061b1b
The SA1100 was implementing its own variants of gpio_get_value() and gpio_set_value() and only selectively falling back to gpiolib for extended (EGPIO) handling. However the driver in gpio/gpio-sa1100.c already handles the same functionality for these lines, yet remain unused. The only upside would be things like a timing-critical hotpath on bit-banged GPIO, but that kind of things does not seem to happen on these GPIOs, so it is not worth having the extra complexity. Tested with some buttons on the Compaq iPAQ H3630. Cc: Kristoffer Ericson <kristoffer.ericson@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
71 lines
1.6 KiB
C
71 lines
1.6 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
#include <linux/gpio.h>
|
|
#include <linux/init.h>
|
|
#include <linux/module.h>
|
|
#include <linux/io.h>
|
|
#include <mach/hardware.h>
|
|
#include <mach/irqs.h>
|
|
|
|
static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|
{
|
|
return GPLR & GPIO_GPIO(offset);
|
|
}
|
|
|
|
static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|
{
|
|
if (value)
|
|
GPSR = GPIO_GPIO(offset);
|
|
else
|
|
GPCR = GPIO_GPIO(offset);
|
|
}
|
|
|
|
static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset)
|
|
{
|
|
unsigned long flags;
|
|
|
|
local_irq_save(flags);
|
|
GPDR &= ~GPIO_GPIO(offset);
|
|
local_irq_restore(flags);
|
|
return 0;
|
|
}
|
|
|
|
static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value)
|
|
{
|
|
unsigned long flags;
|
|
|
|
local_irq_save(flags);
|
|
sa1100_gpio_set(chip, offset, value);
|
|
GPDR |= GPIO_GPIO(offset);
|
|
local_irq_restore(flags);
|
|
return 0;
|
|
}
|
|
|
|
static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset)
|
|
{
|
|
return offset < 11 ? (IRQ_GPIO0 + offset) : (IRQ_GPIO11 - 11 + offset);
|
|
}
|
|
|
|
static struct gpio_chip sa1100_gpio_chip = {
|
|
.label = "gpio",
|
|
.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,
|
|
};
|
|
|
|
void __init sa1100_init_gpio(void)
|
|
{
|
|
gpiochip_add(&sa1100_gpio_chip);
|
|
}
|