static struct irqaction ep93xx_timer_irq = {
.name = "ep93xx timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ep93xx_timer_interrupt,
};
/*************************************************************************
* GPIO handling for EP93xx
*************************************************************************/
-static unsigned char gpio_int_enable[3];
+static unsigned char gpio_int_unmasked[3];
+static unsigned char gpio_int_enabled[3];
static unsigned char gpio_int_type1[3];
static unsigned char gpio_int_type2[3];
__raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
__raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2);
__raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1);
- __raw_writeb(gpio_int_enable[0], EP93XX_GPIO_A_INT_ENABLE);
+ __raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], EP93XX_GPIO_A_INT_ENABLE);
} else if (abf == 1) {
__raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
__raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2);
__raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1);
- __raw_writeb(gpio_int_enable[1], EP93XX_GPIO_B_INT_ENABLE);
+ __raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], EP93XX_GPIO_B_INT_ENABLE);
} else if (abf == 2) {
__raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE);
__raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2);
__raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1);
- __raw_writeb(gpio_int_enable[2], EP93XX_GPIO_F_INT_ENABLE);
+ __raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], EP93XX_GPIO_F_INT_ENABLE);
} else {
BUG();
}
0x10, 0x14, 0x18, 0x1c, 0x24, 0x34, 0x3c, 0x44,
};
-void gpio_line_config(int line, int direction)
+static void ep93xx_gpio_set_direction(unsigned line, int direction)
{
unsigned int data_direction_register;
unsigned long flags;
if (direction == GPIO_OUT) {
if (line >= 0 && line < 16) {
/* Port A/B. */
- gpio_int_enable[line >> 3] &= ~(1 << (line & 7));
+ gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
update_gpio_int_params(line >> 3);
} else if (line >= 40 && line < 48) {
/* Port F. */
- gpio_int_enable[2] &= ~(1 << (line & 7));
+ gpio_int_unmasked[2] &= ~(1 << (line & 7));
update_gpio_int_params(2);
}
}
local_irq_restore(flags);
}
+
+void __deprecated gpio_line_config(int line, int direction)
+{
+ ep93xx_gpio_set_direction(line, direction);
+}
EXPORT_SYMBOL(gpio_line_config);
-int gpio_line_get(int line)
+int gpio_direction_input(unsigned gpio)
+{
+ if (gpio > EP93XX_GPIO_LINE_H(7))
+ return -EINVAL;
+
+ ep93xx_gpio_set_direction(gpio, GPIO_IN);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ if (gpio > EP93XX_GPIO_LINE_H(7))
+ return -EINVAL;
+
+ gpio_set_value(gpio, value);
+ ep93xx_gpio_set_direction(gpio, GPIO_OUT);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+int gpio_get_value(unsigned gpio)
{
unsigned int data_register;
- data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]);
+ data_register = EP93XX_GPIO_REG(data_register_offset[gpio >> 3]);
- return !!(__raw_readb(data_register) & (1 << (line & 7)));
+ return !!(__raw_readb(data_register) & (1 << (gpio & 7)));
}
-EXPORT_SYMBOL(gpio_line_get);
+EXPORT_SYMBOL(gpio_get_value);
-void gpio_line_set(int line, int value)
+void gpio_set_value(unsigned gpio, int value)
{
unsigned int data_register;
unsigned long flags;
unsigned char v;
- data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]);
+ data_register = EP93XX_GPIO_REG(data_register_offset[gpio >> 3]);
local_irq_save(flags);
- if (value == EP93XX_GPIO_HIGH) {
- v = __raw_readb(data_register);
- v |= 1 << (line & 7);
- __raw_writeb(v, data_register);
- } else if (value == EP93XX_GPIO_LOW) {
- v = __raw_readb(data_register);
- v &= ~(1 << (line & 7));
- __raw_writeb(v, data_register);
- }
+ v = __raw_readb(data_register);
+ if (value)
+ v |= 1 << (gpio & 7);
+ else
+ v &= ~(1 << (gpio & 7));
+ __raw_writeb(v, data_register);
local_irq_restore(flags);
}
-EXPORT_SYMBOL(gpio_line_set);
+EXPORT_SYMBOL(gpio_set_value);
/*************************************************************************
int line = irq - IRQ_EP93XX_GPIO(0);
int port = line >> 3;
- gpio_int_enable[port] &= ~(1 << (line & 7));
+ gpio_int_unmasked[port] &= ~(1 << (line & 7));
update_gpio_int_params(port);
if (port == 0) {
int line = irq - IRQ_EP93XX_GPIO(0);
int port = line >> 3;
- gpio_int_enable[port] &= ~(1 << (line & 7));
+ gpio_int_unmasked[port] &= ~(1 << (line & 7));
update_gpio_int_params(port);
}
int line = irq - IRQ_EP93XX_GPIO(0);
int port = line >> 3;
- gpio_int_enable[port] |= 1 << (line & 7);
+ gpio_int_unmasked[port] |= 1 << (line & 7);
update_gpio_int_params(port);
}
line = irq - IRQ_EP93XX_GPIO(0);
if (line >= 0 && line < 16) {
- gpio_line_config(line, GPIO_IN);
+ ep93xx_gpio_set_direction(line, GPIO_IN);
} else {
- gpio_line_config(EP93XX_GPIO_LINE_F(line), GPIO_IN);
+ ep93xx_gpio_set_direction(EP93XX_GPIO_LINE_F(line-16), GPIO_IN);
}
port = line >> 3;
line &= 7;
if (type & IRQT_RISING) {
+ gpio_int_enabled[port] |= 1 << line;
gpio_int_type1[port] |= 1 << line;
gpio_int_type2[port] |= 1 << line;
} else if (type & IRQT_FALLING) {
+ gpio_int_enabled[port] |= 1 << line;
gpio_int_type1[port] |= 1 << line;
gpio_int_type2[port] &= ~(1 << line);
} else if (type & IRQT_HIGH) {
+ gpio_int_enabled[port] |= 1 << line;
gpio_int_type1[port] &= ~(1 << line);
gpio_int_type2[port] |= 1 << line;
} else if (type & IRQT_LOW) {
+ gpio_int_enabled[port] |= 1 << line;
gpio_int_type1[port] &= ~(1 << line);
gpio_int_type2[port] &= ~(1 << line);
+ } else {
+ gpio_int_enabled[port] &= ~(1 << line);
}
update_gpio_int_params(port);