Skip to content

Commit

Permalink
[ARM] pxa: make pxa_gpio_irq_type() processor generic
Browse files Browse the repository at this point in the history
The main issue here is that pxa3xx does not have GAFRx registers,
access directly to these registers should be avoided for pxa3xx:

1. introduce __gpio_is_occupied() to indicate the GAFRx and GPDRx
   registers are already configured on pxa{25x,27x} while returns
   0 always on pxa3xx

2. pxa_gpio_mode(gpio | GPIO_IN) is replaced directly with assign-
   ment of GPDRx, the side effect of this change is that the pin
   _must_ be configured before use, pxa_gpio_irq_type() will not
   change the pin to GPIO, as this restriction is sane, esp. with
   the new MFP framework

Signed-off-by: eric miao <eric.miao@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
eric miao authored and Russell King committed Apr 19, 2008
1 parent 663707c commit 689c04a
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions arch/arm/mach-pxa/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,20 @@ static long GPIO_IRQ_rising_edge[4];
static long GPIO_IRQ_falling_edge[4];
static long GPIO_IRQ_mask[4];

/*
* On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
* function of a GPIO, and GPDRx cannot be altered once configured. It
* is attributed as "occupied" here (I know this terminology isn't
* accurate, you are welcome to propose a better one :-)
*/
static int __gpio_is_occupied(unsigned gpio)
{
if (cpu_is_pxa25x() || cpu_is_pxa27x())
return GAFR(gpio) & (0x3 << (((gpio) & 0xf) * 2));
else
return 0;
}

static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
{
int gpio, idx;
Expand All @@ -179,12 +193,14 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
GPIO_IRQ_falling_edge[idx] |
GPDR(gpio)) & GPIO_bit(gpio))
return 0;
if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))

if (__gpio_is_occupied(gpio))
return 0;

type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
}

pxa_gpio_mode(gpio | GPIO_IN);
GPDR(gpio) &= ~GPIO_bit(gpio);

if (type & IRQ_TYPE_EDGE_RISING)
__set_bit(gpio, GPIO_IRQ_rising_edge);
Expand Down

0 comments on commit 689c04a

Please sign in to comment.