aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/adm5120
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2007-12-10 14:05:01 +0000
committerGabor Juhos <juhosg@openwrt.org>2007-12-10 14:05:01 +0000
commit4aa4b0e4638b121041496f50d5a99bb2e33b97f4 (patch)
tree476f5ee3120fad865cc3fad86139097022103d7d /target/linux/adm5120
parentd249fa0b426e170a9951fdace388ee33f4ec8f02 (diff)
downloadupstream-4aa4b0e4638b121041496f50d5a99bb2e33b97f4.tar.gz
upstream-4aa4b0e4638b121041496f50d5a99bb2e33b97f4.tar.bz2
upstream-4aa4b0e4638b121041496f50d5a99bb2e33b97f4.zip
[adm5120] add support for GPIO IRQs
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@9700 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/adm5120')
-rw-r--r--target/linux/adm5120/files/arch/mips/adm5120/board.c2
-rw-r--r--target/linux/adm5120/files/arch/mips/adm5120/gpio.c117
-rw-r--r--target/linux/adm5120/files/arch/mips/adm5120/irq.c9
-rw-r--r--target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_info.h5
-rw-r--r--target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_switch.h5
5 files changed, 95 insertions, 43 deletions
diff --git a/target/linux/adm5120/files/arch/mips/adm5120/board.c b/target/linux/adm5120/files/arch/mips/adm5120/board.c
index c5ee4e3e72..0ac85f529f 100644
--- a/target/linux/adm5120/files/arch/mips/adm5120/board.c
+++ b/target/linux/adm5120/files/arch/mips/adm5120/board.c
@@ -83,6 +83,8 @@ static int __init adm5120_board_setup(void)
memcpy(&adm5120_board_name, board->name, ADM5120_BOARD_NAMELEN);
+ adm5120_gpio_init();
+
adm5120_board_reset = board->board_reset;
if (board->eth_num_ports > 0)
adm5120_eth_num_ports = board->eth_num_ports;
diff --git a/target/linux/adm5120/files/arch/mips/adm5120/gpio.c b/target/linux/adm5120/files/arch/mips/adm5120/gpio.c
index 075ea87416..a6cfdcbe09 100644
--- a/target/linux/adm5120/files/arch/mips/adm5120/gpio.c
+++ b/target/linux/adm5120/files/arch/mips/adm5120/gpio.c
@@ -37,7 +37,7 @@
#include <adm5120_defs.h>
#include <adm5120_info.h>
#include <adm5120_switch.h>
-
+#include <adm5120_irq.h>
#define GPIO_READ(r) readl((r))
#define GPIO_WRITE(v, r) writel((v), (r))
@@ -46,6 +46,7 @@
struct adm5120_gpio_line {
u32 flags;
const char *label;
+ int irq;
};
#define GPIO_FLAG_VALID 0x01
@@ -71,36 +72,25 @@ static struct led_desc led_table[15] = {
LED_DESC(4, 0), LED_DESC(4, 1), LED_DESC(4, 2)
};
-static struct adm5120_gpio_line adm5120_gpio_map[ADM5120_GPIO_COUNT] = {
- [ADM5120_GPIO_PIN0] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_PIN1] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_PIN2] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_PIN3] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_PIN4] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_PIN5] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_PIN6] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_PIN7] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P0L0] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P0L1] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P0L2] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P1L0] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P1L1] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P1L2] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P2L0] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P2L1] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P2L2] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P3L0] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P3L1] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P3L2] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P4L0] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P4L1] = {.flags = GPIO_FLAG_VALID},
- [ADM5120_GPIO_P4L2] = {.flags = GPIO_FLAG_VALID}
-};
+static struct adm5120_gpio_line adm5120_gpio_map[ADM5120_GPIO_COUNT];
+
+/*-------------------------------------------------------------------------*/
+
+static inline int gpio_is_invalid(unsigned gpio)
+{
+ if ((gpio > ADM5120_GPIO_MAX) ||
+ (adm5120_gpio_map[gpio].flags & GPIO_FLAG_VALID) == 0);
+ return 0;
-#define gpio_is_invalid(g) ((g) > ADM5120_GPIO_MAX || \
- ((adm5120_gpio_map[(g)].flags & GPIO_FLAG_VALID) == 0))
+ return 1;
+}
+
+static inline int gpio_is_used(unsigned gpio)
+{
+ return ((adm5120_gpio_map[gpio].flags & GPIO_FLAG_USED) != 0);
+}
-#define gpio_is_used(g) ((adm5120_gpio_map[(g)].flags & GPIO_FLAG_USED) != 0)
+/*-------------------------------------------------------------------------*/
/*
* Helpers for GPIO lines in GPIO_CONF0 register
@@ -247,6 +237,8 @@ static inline int leds_get_value(unsigned led)
return 1;
}
+/*-------------------------------------------------------------------------*/
+
/*
* Main GPIO support routines
*/
@@ -325,29 +317,74 @@ EXPORT_SYMBOL(adm5120_gpio_free);
int adm5120_gpio_to_irq(unsigned gpio)
{
- /* FIXME: not yet implemented */
- return -EINVAL;
+ if (gpio > ADM5120_GPIO_MAX)
+ return -EINVAL;
+
+ return adm5120_gpio_map[gpio].irq;
}
EXPORT_SYMBOL(adm5120_gpio_to_irq);
int adm5120_irq_to_gpio(unsigned irq)
{
- /* FIXME: not yet implemented */
+ int i;
+
+ for (i = 0; i < ADM5120_GPIO_COUNT; i++)
+ if (adm5120_gpio_map[i].irq == irq)
+ return i;
+
return -EINVAL;
}
EXPORT_SYMBOL(adm5120_irq_to_gpio);
-static int __init adm5120_gpio_init(void)
+/*-------------------------------------------------------------------------*/
+
+void __init adm5120_gpio_csx0_enable(void)
+{
+ u32 t;
+
+ t = SW_READ_REG(GPIO_CONF2);
+ t |= GPIO_CONF2_CSX0;
+ SW_WRITE_REG(GPIO_CONF2, t);
+
+ adm5120_gpio_map[ADM5120_GPIO_PIN1].flags &= ~GPIO_FLAG_VALID;
+ adm5120_gpio_map[ADM5120_GPIO_PIN2].irq = ADM5120_IRQ_GPIO2;
+}
+
+void __init adm5120_gpio_csx1_enable(void)
+{
+ u32 t;
+
+ t = SW_READ_REG(GPIO_CONF2);
+ t |= GPIO_CONF2_CSX1;
+ SW_WRITE_REG(GPIO_CONF2, t);
+
+ adm5120_gpio_map[ADM5120_GPIO_PIN3].flags &= ~GPIO_FLAG_VALID;
+ if (adm5120_package_bga())
+ adm5120_gpio_map[ADM5120_GPIO_PIN4].irq = ADM5120_IRQ_GPIO4;
+}
+
+void __init adm5120_gpio_ew_enable(void)
+{
+ u32 t;
+
+ t = SW_READ_REG(GPIO_CONF2);
+ t |= GPIO_CONF2_EW;
+ SW_WRITE_REG(GPIO_CONF2, t);
+}
+
+void __init adm5120_gpio_init(void)
{
int i;
+ SW_WRITE_REG(GPIO_CONF2, 0);
+
+ for (i = 0; i < ADM5120_GPIO_COUNT; i++)
+ adm5120_gpio_map[i].flags = GPIO_FLAG_VALID;
+
if (adm5120_package_pqfp()) {
- /* GPIO pins 4-7 are unavailable in ADM5120P */
- for (i = ADM5120_GPIO_PIN4; i <= ADM5120_GPIO_PIN7; i++)
- adm5120_gpio_map[i].flags &= ~GPIO_FLAG_VALID;
+ adm5120_gpio_map[ADM5120_GPIO_PIN4].flags &= ~GPIO_FLAG_VALID;
+ adm5120_gpio_map[ADM5120_GPIO_PIN5].flags &= ~GPIO_FLAG_VALID;
+ adm5120_gpio_map[ADM5120_GPIO_PIN6].flags &= ~GPIO_FLAG_VALID;
+ adm5120_gpio_map[ADM5120_GPIO_PIN7].flags &= ~GPIO_FLAG_VALID;
}
-
- return 0;
}
-
-pure_initcall(adm5120_gpio_init);
diff --git a/target/linux/adm5120/files/arch/mips/adm5120/irq.c b/target/linux/adm5120/files/arch/mips/adm5120/irq.c
index 6e3fc62220..361dcb8628 100644
--- a/target/linux/adm5120/files/arch/mips/adm5120/irq.c
+++ b/target/linux/adm5120/files/arch/mips/adm5120/irq.c
@@ -76,7 +76,7 @@ static void adm5120_intc_irq_mask(unsigned int irq)
static int adm5120_intc_irq_set_type(unsigned int irq, unsigned int flow_type)
{
/* TODO: not yet tested */
-#if 1
+
unsigned int sense;
unsigned long mode;
int err = 0;
@@ -114,13 +114,13 @@ static int adm5120_intc_irq_set_type(unsigned int irq, unsigned int flow_type)
mode &= (1 << (irq-ADM5120_INTC_IRQ_BASE));
INTC_WRITE(INTC_REG_INT_MODE, mode);
- /* fallthrogh */
+ /* fallthrough */
default:
irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
irq_desc[irq].status |= sense;
break;
}
-#endif
+
return 0;
}
@@ -161,10 +161,13 @@ static void __init adm5120_intc_irq_init(int base)
/* disable all interrupts */
INTC_WRITE(INTC_REG_IRQ_DISABLE, INTC_INT_ALL);
+
/* setup all interrupts to generate IRQ instead of FIQ */
INTC_WRITE(INTC_REG_INT_MODE, 0);
+
/* set active level for all external interrupts to HIGH */
INTC_WRITE(INTC_REG_INT_LEVEL, 0);
+
/* disable usage of the TEST_SOURCE register */
INTC_WRITE(INTC_REG_IRQ_SOURCE_SELECT, 0);
diff --git a/target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_info.h b/target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_info.h
index ac452ef30f..7d92a510bd 100644
--- a/target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_info.h
+++ b/target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_info.h
@@ -68,6 +68,11 @@ extern void adm5120_halt(void);
extern void (*adm5120_board_reset)(void);
+extern void adm5120_gpio_init(void) __init;
+extern void adm5120_gpio_csx0_enable(void) __init;
+extern void adm5120_gpio_csx1_enable(void) __init;
+extern void adm5120_gpio_ew_enable(void) __init;
+
static inline int adm5120_package_pqfp(void)
{
return (adm5120_package == ADM5120_PACKAGE_PQFP);
diff --git a/target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_switch.h b/target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_switch.h
index a40175b03b..f96c7d50c7 100644
--- a/target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_switch.h
+++ b/target/linux/adm5120/files/include/asm-mips/mach-adm5120/adm5120_switch.h
@@ -247,6 +247,11 @@
#define GPIO_CONF0_OE_MASK (0xFF << GPIO_CONF0_OE_SHIFT)
#define GPIO_CONF0_OV_MASK (0xFF << GPIO_CONF0_OV_SHIFT)
+/* GPIO_CONF2 register bits */
+#define GPIO_CONF2_CSX0 BIT(4) /* enable CSX0:INTX0 on GPIO 1:2 */
+#define GPIO_CONF2_CSX1 BIT(5) /* enable CSX1:INTX1 on GPIO 3:4 */
+#define GPIO_CONF2_EW BIT(6) /* enable wait state pin for CSX0/1 */
+
/* INT_STATUS/INT_MASK register bits */
#define SWITCH_INT_SHD BIT(0) /* Send High Done */
#define SWITCH_INT_SLD BIT(1) /* Send Low Done */