[ARM] 2836/1: Cleanup IXP4xx GPIO code
Patch from Deepak Saxena This patch implements the set_irq_type() hooks for configuring GPIO IRQ type and updates all the platforms to use it instead of the gpio_line_config() function which is now used to configure input vs. output on the pins. Signed-off-by: Deepak Saxena <dsaxena@plexity.net> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:

committed by
Russell King

parent
e605ecd7c8
commit
bdf82b59c5
@@ -38,90 +38,6 @@
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
enum ixp4xx_irq_type {
|
||||
IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
|
||||
};
|
||||
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
|
||||
|
||||
/*************************************************************************
|
||||
* GPIO acces functions
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
* Configure GPIO line for input, interrupt, or output operation
|
||||
*
|
||||
* TODO: Enable/disable the irq_desc based on interrupt or output mode.
|
||||
* TODO: Should these be named ixp4xx_gpio_?
|
||||
*/
|
||||
void gpio_line_config(u8 line, u32 style)
|
||||
{
|
||||
static const int gpio2irq[] = {
|
||||
6, 7, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
|
||||
};
|
||||
u32 enable;
|
||||
volatile u32 *int_reg;
|
||||
u32 int_style;
|
||||
enum ixp4xx_irq_type irq_type;
|
||||
|
||||
enable = *IXP4XX_GPIO_GPOER;
|
||||
|
||||
if (style & IXP4XX_GPIO_OUT) {
|
||||
enable &= ~((1) << line);
|
||||
} else if (style & IXP4XX_GPIO_IN) {
|
||||
enable |= ((1) << line);
|
||||
|
||||
switch (style & IXP4XX_GPIO_INTSTYLE_MASK)
|
||||
{
|
||||
case (IXP4XX_GPIO_ACTIVE_HIGH):
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
break;
|
||||
case (IXP4XX_GPIO_ACTIVE_LOW):
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
break;
|
||||
case (IXP4XX_GPIO_RISING_EDGE):
|
||||
int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
case (IXP4XX_GPIO_FALLING_EDGE):
|
||||
int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
case (IXP4XX_GPIO_TRANSITIONAL):
|
||||
int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
break;
|
||||
default:
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (style & IXP4XX_GPIO_INTSTYLE_MASK)
|
||||
ixp4xx_config_irq(gpio2irq[line], irq_type);
|
||||
|
||||
if (line >= 8) { /* pins 8-15 */
|
||||
line -= 8;
|
||||
int_reg = IXP4XX_GPIO_GPIT2R;
|
||||
}
|
||||
else { /* pins 0-7 */
|
||||
int_reg = IXP4XX_GPIO_GPIT1R;
|
||||
}
|
||||
|
||||
/* Clear the style for the appropriate pin */
|
||||
*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
|
||||
(line * IXP4XX_GPIO_STYLE_SIZE));
|
||||
|
||||
/* Set the new style */
|
||||
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
|
||||
}
|
||||
|
||||
*IXP4XX_GPIO_GPOER = enable;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(gpio_line_config);
|
||||
|
||||
/*************************************************************************
|
||||
* IXP4xx chipset I/O mapping
|
||||
*************************************************************************/
|
||||
@@ -165,6 +81,69 @@ void __init ixp4xx_map_io(void)
|
||||
* (be it PCI or something else) configures that GPIO line
|
||||
* as an IRQ.
|
||||
**************************************************************************/
|
||||
enum ixp4xx_irq_type {
|
||||
IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
|
||||
};
|
||||
|
||||
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
|
||||
|
||||
/*
|
||||
* IRQ -> GPIO mapping table
|
||||
*/
|
||||
static int irq2gpio[32] = {
|
||||
-1, -1, -1, -1, -1, -1, 0, 1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, -1, -1,
|
||||
};
|
||||
|
||||
static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
|
||||
{
|
||||
int line = irq2gpio[irq];
|
||||
u32 int_style;
|
||||
enum ixp4xx_irq_type irq_type;
|
||||
volatile u32 *int_reg;
|
||||
|
||||
/*
|
||||
* Only for GPIO IRQs
|
||||
*/
|
||||
if (line < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (type & IRQT_BOTHEDGE) {
|
||||
int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
} else if (type & IRQT_RISING) {
|
||||
int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
} else if (type & IRQT_FALLING) {
|
||||
int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
|
||||
irq_type = IXP4XX_IRQ_EDGE;
|
||||
} else if (type & IRQT_HIGH) {
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
} else if (type & IRQT_LOW) {
|
||||
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
|
||||
irq_type = IXP4XX_IRQ_LEVEL;
|
||||
}
|
||||
|
||||
ixp4xx_config_irq(irq, irq_type);
|
||||
|
||||
if (line >= 8) { /* pins 8-15 */
|
||||
line -= 8;
|
||||
int_reg = IXP4XX_GPIO_GPIT2R;
|
||||
} else { /* pins 0-7 */
|
||||
int_reg = IXP4XX_GPIO_GPIT1R;
|
||||
}
|
||||
|
||||
/* Clear the style for the appropriate pin */
|
||||
*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
|
||||
(line * IXP4XX_GPIO_STYLE_SIZE));
|
||||
|
||||
/* Set the new style */
|
||||
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
|
||||
}
|
||||
|
||||
static void ixp4xx_irq_mask(unsigned int irq)
|
||||
{
|
||||
if (cpu_is_ixp46x() && irq >= 32)
|
||||
@@ -183,12 +162,6 @@ static void ixp4xx_irq_unmask(unsigned int irq)
|
||||
|
||||
static void ixp4xx_irq_ack(unsigned int irq)
|
||||
{
|
||||
static int irq2gpio[32] = {
|
||||
-1, -1, -1, -1, -1, -1, 0, 1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, -1, -1,
|
||||
};
|
||||
int line = (irq < 32) ? irq2gpio[irq] : -1;
|
||||
|
||||
if (line >= 0)
|
||||
@@ -209,12 +182,14 @@ static struct irqchip ixp4xx_irq_level_chip = {
|
||||
.ack = ixp4xx_irq_mask,
|
||||
.mask = ixp4xx_irq_mask,
|
||||
.unmask = ixp4xx_irq_level_unmask,
|
||||
.type = ixp4xx_set_irq_type
|
||||
};
|
||||
|
||||
static struct irqchip ixp4xx_irq_edge_chip = {
|
||||
.ack = ixp4xx_irq_ack,
|
||||
.mask = ixp4xx_irq_mask,
|
||||
.unmask = ixp4xx_irq_unmask,
|
||||
.type = ixp4xx_set_irq_type
|
||||
};
|
||||
|
||||
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type)
|
||||
|
Reference in New Issue
Block a user