Commit ef2dc0e6 authored by David Brownell's avatar David Brownell Committed by Kevin Hilman

ARM: DaVinci: update to new generic GPIO layer

Update Davinci GPIO support to match the new cross-platform interfaces.
This removes some old Davinci-only calls, and changes some others.

NOTE:  this presumes the gpio_direction_output() signature change which
was merged shortly after 2.6.21-rc4 was tagged.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
parent 80537c9f
...@@ -386,6 +386,7 @@ config ARCH_OMAP ...@@ -386,6 +386,7 @@ config ARCH_OMAP
config ARCH_DAVINCI config ARCH_DAVINCI
bool "TI DaVinci" bool "TI DaVinci"
select GENERIC_GPIO
endchoice endchoice
......
...@@ -58,13 +58,11 @@ EXPORT_SYMBOL(__gpio_get); ...@@ -58,13 +58,11 @@ EXPORT_SYMBOL(__gpio_get);
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
/* /*
* We expect board setup code to handle all gpio direction setup, * board setup code *MUST* set PINMUX0 and PINMUX1 as
* so there's no need to let driver modules do it.
*
* That same board setup code must also set PINMUX0 and PINMUX1 as
* needed, and enable the GPIO clock. * needed, and enable the GPIO clock.
*/ */
int __init gpio_set_direction(unsigned gpio, int is_in)
int gpio_direction_input(unsigned gpio)
{ {
struct gpio_controller *__iomem g = gpio2controller(gpio); struct gpio_controller *__iomem g = gpio2controller(gpio);
u32 temp; u32 temp;
...@@ -73,17 +71,31 @@ int __init gpio_set_direction(unsigned gpio, int is_in) ...@@ -73,17 +71,31 @@ int __init gpio_set_direction(unsigned gpio, int is_in)
if (!g) if (!g)
return -EINVAL; return -EINVAL;
g = gpio_to_controller(gpio);
mask = gpio_mask(gpio); mask = gpio_mask(gpio);
temp = __raw_readl(&g->dir); temp = __raw_readl(&g->dir);
if (is_in) temp |= mask;
temp |= mask;
else
temp &= ~mask;
__raw_writel(temp, &g->dir); __raw_writel(temp, &g->dir);
return 0; return 0;
} }
EXPORT_SYMBOL(gpio_set_direction); EXPORT_SYMBOL(gpio_direction_input);
int gpio_direction_output(unsigned gpio, int value)
{
struct gpio_controller *__iomem g = gpio2controller(gpio);
u32 temp;
u32 mask;
if (!g)
return -EINVAL;
mask = gpio_mask(gpio);
temp = __raw_readl(&g->dir);
temp &= ~mask;
__raw_writel(mask, value ? &g->set_data : &g->clr_data);
__raw_writel(temp, &g->dir);
return 0;
}
EXPORT_SYMBOL(gpio_direction_output);
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
...@@ -99,12 +111,10 @@ EXPORT_SYMBOL(gpio_set_direction); ...@@ -99,12 +111,10 @@ EXPORT_SYMBOL(gpio_set_direction);
* serve as EDMA event triggers. * serve as EDMA event triggers.
*/ */
#define irq2gpio(irq) ((irq) - DAVINCI_N_AINTC_IRQ)
static void gpio_irq_disable(unsigned irq) static void gpio_irq_disable(unsigned irq)
{ {
struct gpio_controller *__iomem g = get_irq_chip_data(irq); struct gpio_controller *__iomem g = get_irq_chip_data(irq);
u32 mask = gpio_mask(irq2gpio(irq)); u32 mask = gpio_mask(irq_to_gpio(irq));
__raw_writel(mask, &g->clr_falling); __raw_writel(mask, &g->clr_falling);
__raw_writel(mask, &g->clr_rising); __raw_writel(mask, &g->clr_rising);
...@@ -113,7 +123,7 @@ static void gpio_irq_disable(unsigned irq) ...@@ -113,7 +123,7 @@ static void gpio_irq_disable(unsigned irq)
static void gpio_irq_enable(unsigned irq) static void gpio_irq_enable(unsigned irq)
{ {
struct gpio_controller *__iomem g = get_irq_chip_data(irq); struct gpio_controller *__iomem g = get_irq_chip_data(irq);
u32 mask = gpio_mask(irq2gpio(irq)); u32 mask = gpio_mask(irq_to_gpio(irq));
if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING) if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
__raw_writel(mask, &g->set_falling); __raw_writel(mask, &g->set_falling);
...@@ -124,7 +134,7 @@ static void gpio_irq_enable(unsigned irq) ...@@ -124,7 +134,7 @@ static void gpio_irq_enable(unsigned irq)
static int gpio_irq_type(unsigned irq, unsigned trigger) static int gpio_irq_type(unsigned irq, unsigned trigger)
{ {
struct gpio_controller *__iomem g = get_irq_chip_data(irq); struct gpio_controller *__iomem g = get_irq_chip_data(irq);
unsigned mask = gpio_mask(irq2gpio(irq)); unsigned mask = gpio_mask(irq_to_gpio(irq));
if (trigger & ~(IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING)) if (trigger & ~(IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING))
return -EINVAL; return -EINVAL;
...@@ -212,7 +222,7 @@ static int __init davinci_gpio_irq_setup(void) ...@@ -212,7 +222,7 @@ static int __init davinci_gpio_irq_setup(void)
} }
clk_enable(clk); clk_enable(clk);
for (gpio = 0, irq = DAVINCI_GPIO_IRQ(0), bank = IRQ_GPIOBNK0; for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
gpio < DAVINCI_N_GPIO; gpio < DAVINCI_N_GPIO;
bank++) { bank++) {
struct gpio_controller *__iomem g = gpio2controller(gpio); struct gpio_controller *__iomem g = gpio2controller(gpio);
...@@ -242,7 +252,7 @@ static int __init davinci_gpio_irq_setup(void) ...@@ -242,7 +252,7 @@ static int __init davinci_gpio_irq_setup(void)
__raw_writel(0x1f, (void *__iomem) __raw_writel(0x1f, (void *__iomem)
IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08)); IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
printk(info1, irq - DAVINCI_GPIO_IRQ(0)); printk(info1, irq - gpio_to_irq(0));
return 0; return 0;
} }
arch_initcall(davinci_gpio_irq_setup); arch_initcall(davinci_gpio_irq_setup);
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53) * - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53)
* - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70) * - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70)
* *
* GPIO IRQs all use DAVINCI_GPIO_IRQ(N) or DAVINCI_GPIO_IRQ(GPIOV33(N)) etc * For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
* for now, that's != GPIO(N) * for now, that's != GPIO(N)
*/ */
#define GPIO(X) (X) /* 0 <= X <= 71 */ #define GPIO(X) (X) /* 0 <= X <= 71 */
...@@ -47,6 +47,8 @@ struct gpio_controller { ...@@ -47,6 +47,8 @@ struct gpio_controller {
* You'd access the controller directly when reading or writing more than * You'd access the controller directly when reading or writing more than
* one gpio value at a time, and to support wired logic where the value * one gpio value at a time, and to support wired logic where the value
* being driven by the cpu need not match the value read back. * being driven by the cpu need not match the value read back.
*
* These are NOT part of the cross-platform GPIO interface
*/ */
static inline struct gpio_controller *__iomem static inline struct gpio_controller *__iomem
gpio_to_controller(unsigned gpio) gpio_to_controller(unsigned gpio)
...@@ -81,48 +83,25 @@ extern int __error_inval_gpio(void); ...@@ -81,48 +83,25 @@ extern int __error_inval_gpio(void);
extern int __gpio_set(unsigned gpio, int value); extern int __gpio_set(unsigned gpio, int value);
extern int __gpio_get(unsigned gpio); extern int __gpio_get(unsigned gpio);
static inline int gpio_set(unsigned gpio) static inline void gpio_set_value(unsigned gpio, int value)
{
struct gpio_controller *__iomem g;
if (!__builtin_constant_p(gpio))
return __gpio_set(gpio, 1);
if (gpio >= DAVINCI_N_GPIO)
return __error_inval_gpio();
g = gpio_to_controller(gpio);
__raw_writel(gpio_mask(gpio), &g->set_data);
return 0;
}
static inline int gpio_clear(unsigned gpio)
{ {
struct gpio_controller *__iomem g; if (__builtin_constant_p(value)) {
struct gpio_controller *__iomem g;
if (!__builtin_constant_p(gpio)) u32 mask;
return __gpio_set(gpio, 0);
if (gpio >= DAVINCI_N_GPIO)
return __error_inval_gpio();
g = gpio_to_controller(gpio); if (gpio >= DAVINCI_N_GPIO)
__raw_writel(gpio_mask(gpio), &g->clr_data); __error_inval_gpio();
return 0;
}
static inline int gpio_set_value(unsigned gpio, int value) g = gpio_to_controller(gpio);
{ mask = gpio_mask(gpio);
if (__builtin_constant_p(value)) {
if (value) if (value)
return gpio_set(gpio); __raw_writel(mask, &g->set_data);
else else
return gpio_clear(gpio); __raw_writel(mask, &g->clr_data);
return;
} }
if (__builtin_constant_p(gpio) && gpio >= DAVINCI_N_GPIO)
return __error_inval_gpio();
return __gpio_set(gpio, value); __gpio_set(gpio, value);
} }
/* Returns zero or nonzero, or negative on error; works for gpios /* Returns zero or nonzero, or negative on error; works for gpios
...@@ -147,11 +126,32 @@ static inline int gpio_get_value(unsigned gpio) ...@@ -147,11 +126,32 @@ static inline int gpio_get_value(unsigned gpio)
} }
/* powerup default direction is IN */ /* powerup default direction is IN */
extern int __init gpio_set_direction(unsigned gpio, int is_in);
extern int gpio_direction_input(unsigned gpio);
extern int gpio_direction_output(unsigned gpio, int value);
/* NOTE: currently there's no "claim/release" mechanism for GPIOs, /* NOTE: currently there's no request/free implementation for GPIOs,
* so drivers arguing over them will get errors much like they will * so drivers arguing over them will get errors much like they will
* when the pin isn't muxed properly as gpio ... * when the pin isn't muxed properly as gpio ...
*/ */
static inline int gpio_request(unsigned gpio, const char *tag)
{
return 0;
}
static inline void gpio_free(unsigned gpio)
{
}
static inline int gpio_to_irq(unsigned gpio)
{
return DAVINCI_N_AINTC_IRQ + gpio;
}
static inline int irq_to_gpio(unsigned irq)
{
return irq - DAVINCI_N_AINTC_IRQ;
}
#endif /* __DAVINCI_GPIO_H */ #endif /* __DAVINCI_GPIO_H */
...@@ -106,8 +106,6 @@ ...@@ -106,8 +106,6 @@
#define NR_IRQS (DAVINCI_N_AINTC_IRQ + DAVINCI_N_GPIO) #define NR_IRQS (DAVINCI_N_AINTC_IRQ + DAVINCI_N_GPIO)
#define DAVINCI_GPIO_IRQ(n) (DAVINCI_N_AINTC_IRQ + (n))
#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34 #define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment