add support for GPIO IRQs
SVN-Revision: 9700
This commit is contained in:
parent
cf1c2554e7
commit
9b9b83976c
5 changed files with 95 additions and 43 deletions
|
@ -83,6 +83,8 @@ static int __init adm5120_board_setup(void)
|
||||||
|
|
||||||
memcpy(&adm5120_board_name, board->name, ADM5120_BOARD_NAMELEN);
|
memcpy(&adm5120_board_name, board->name, ADM5120_BOARD_NAMELEN);
|
||||||
|
|
||||||
|
adm5120_gpio_init();
|
||||||
|
|
||||||
adm5120_board_reset = board->board_reset;
|
adm5120_board_reset = board->board_reset;
|
||||||
if (board->eth_num_ports > 0)
|
if (board->eth_num_ports > 0)
|
||||||
adm5120_eth_num_ports = board->eth_num_ports;
|
adm5120_eth_num_ports = board->eth_num_ports;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include <adm5120_defs.h>
|
#include <adm5120_defs.h>
|
||||||
#include <adm5120_info.h>
|
#include <adm5120_info.h>
|
||||||
#include <adm5120_switch.h>
|
#include <adm5120_switch.h>
|
||||||
|
#include <adm5120_irq.h>
|
||||||
|
|
||||||
#define GPIO_READ(r) readl((r))
|
#define GPIO_READ(r) readl((r))
|
||||||
#define GPIO_WRITE(v, r) writel((v), (r))
|
#define GPIO_WRITE(v, r) writel((v), (r))
|
||||||
|
@ -46,6 +46,7 @@
|
||||||
struct adm5120_gpio_line {
|
struct adm5120_gpio_line {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
const char *label;
|
const char *label;
|
||||||
|
int irq;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GPIO_FLAG_VALID 0x01
|
#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)
|
LED_DESC(4, 0), LED_DESC(4, 1), LED_DESC(4, 2)
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct adm5120_gpio_line adm5120_gpio_map[ADM5120_GPIO_COUNT] = {
|
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}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define gpio_is_invalid(g) ((g) > ADM5120_GPIO_MAX || \
|
/*-------------------------------------------------------------------------*/
|
||||||
((adm5120_gpio_map[(g)].flags & GPIO_FLAG_VALID) == 0))
|
|
||||||
|
|
||||||
#define gpio_is_used(g) ((adm5120_gpio_map[(g)].flags & GPIO_FLAG_USED) != 0)
|
static inline int gpio_is_invalid(unsigned gpio)
|
||||||
|
{
|
||||||
|
if ((gpio > ADM5120_GPIO_MAX) ||
|
||||||
|
(adm5120_gpio_map[gpio].flags & GPIO_FLAG_VALID) == 0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int gpio_is_used(unsigned gpio)
|
||||||
|
{
|
||||||
|
return ((adm5120_gpio_map[gpio].flags & GPIO_FLAG_USED) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helpers for GPIO lines in GPIO_CONF0 register
|
* Helpers for GPIO lines in GPIO_CONF0 register
|
||||||
|
@ -247,6 +237,8 @@ static inline int leds_get_value(unsigned led)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main GPIO support routines
|
* Main GPIO support routines
|
||||||
*/
|
*/
|
||||||
|
@ -325,29 +317,74 @@ EXPORT_SYMBOL(adm5120_gpio_free);
|
||||||
|
|
||||||
int adm5120_gpio_to_irq(unsigned gpio)
|
int adm5120_gpio_to_irq(unsigned gpio)
|
||||||
{
|
{
|
||||||
/* FIXME: not yet implemented */
|
if (gpio > ADM5120_GPIO_MAX)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
return adm5120_gpio_map[gpio].irq;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(adm5120_gpio_to_irq);
|
EXPORT_SYMBOL(adm5120_gpio_to_irq);
|
||||||
|
|
||||||
int adm5120_irq_to_gpio(unsigned 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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(adm5120_irq_to_gpio);
|
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;
|
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()) {
|
if (adm5120_package_pqfp()) {
|
||||||
/* GPIO pins 4-7 are unavailable in ADM5120P */
|
adm5120_gpio_map[ADM5120_GPIO_PIN4].flags &= ~GPIO_FLAG_VALID;
|
||||||
for (i = ADM5120_GPIO_PIN4; i <= ADM5120_GPIO_PIN7; i++)
|
adm5120_gpio_map[ADM5120_GPIO_PIN5].flags &= ~GPIO_FLAG_VALID;
|
||||||
adm5120_gpio_map[i].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);
|
|
||||||
|
|
|
@ -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)
|
static int adm5120_intc_irq_set_type(unsigned int irq, unsigned int flow_type)
|
||||||
{
|
{
|
||||||
/* TODO: not yet tested */
|
/* TODO: not yet tested */
|
||||||
#if 1
|
|
||||||
unsigned int sense;
|
unsigned int sense;
|
||||||
unsigned long mode;
|
unsigned long mode;
|
||||||
int err = 0;
|
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));
|
mode &= (1 << (irq-ADM5120_INTC_IRQ_BASE));
|
||||||
|
|
||||||
INTC_WRITE(INTC_REG_INT_MODE, mode);
|
INTC_WRITE(INTC_REG_INT_MODE, mode);
|
||||||
/* fallthrogh */
|
/* fallthrough */
|
||||||
default:
|
default:
|
||||||
irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
|
irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
|
||||||
irq_desc[irq].status |= sense;
|
irq_desc[irq].status |= sense;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,10 +161,13 @@ static void __init adm5120_intc_irq_init(int base)
|
||||||
|
|
||||||
/* disable all interrupts */
|
/* disable all interrupts */
|
||||||
INTC_WRITE(INTC_REG_IRQ_DISABLE, INTC_INT_ALL);
|
INTC_WRITE(INTC_REG_IRQ_DISABLE, INTC_INT_ALL);
|
||||||
|
|
||||||
/* setup all interrupts to generate IRQ instead of FIQ */
|
/* setup all interrupts to generate IRQ instead of FIQ */
|
||||||
INTC_WRITE(INTC_REG_INT_MODE, 0);
|
INTC_WRITE(INTC_REG_INT_MODE, 0);
|
||||||
|
|
||||||
/* set active level for all external interrupts to HIGH */
|
/* set active level for all external interrupts to HIGH */
|
||||||
INTC_WRITE(INTC_REG_INT_LEVEL, 0);
|
INTC_WRITE(INTC_REG_INT_LEVEL, 0);
|
||||||
|
|
||||||
/* disable usage of the TEST_SOURCE register */
|
/* disable usage of the TEST_SOURCE register */
|
||||||
INTC_WRITE(INTC_REG_IRQ_SOURCE_SELECT, 0);
|
INTC_WRITE(INTC_REG_IRQ_SOURCE_SELECT, 0);
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,11 @@ extern void adm5120_halt(void);
|
||||||
|
|
||||||
extern void (*adm5120_board_reset)(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)
|
static inline int adm5120_package_pqfp(void)
|
||||||
{
|
{
|
||||||
return (adm5120_package == ADM5120_PACKAGE_PQFP);
|
return (adm5120_package == ADM5120_PACKAGE_PQFP);
|
||||||
|
|
|
@ -247,6 +247,11 @@
|
||||||
#define GPIO_CONF0_OE_MASK (0xFF << GPIO_CONF0_OE_SHIFT)
|
#define GPIO_CONF0_OE_MASK (0xFF << GPIO_CONF0_OE_SHIFT)
|
||||||
#define GPIO_CONF0_OV_MASK (0xFF << GPIO_CONF0_OV_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 */
|
/* INT_STATUS/INT_MASK register bits */
|
||||||
#define SWITCH_INT_SHD BIT(0) /* Send High Done */
|
#define SWITCH_INT_SHD BIT(0) /* Send High Done */
|
||||||
#define SWITCH_INT_SLD BIT(1) /* Send Low Done */
|
#define SWITCH_INT_SLD BIT(1) /* Send Low Done */
|
||||||
|
|
Loading…
Reference in a new issue