mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-03-01 09:56:16 +07:00
[ARM] 4122/1: ep93xx: add support for GPIO port F interrupts
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
fac105d05e
commit
4932e397be
@ -152,22 +152,29 @@ struct sys_timer ep93xx_timer = {
|
|||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* GPIO handling for EP93xx
|
* GPIO handling for EP93xx
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
static unsigned char gpio_int_enable[2];
|
static unsigned char gpio_int_enable[3];
|
||||||
static unsigned char gpio_int_type1[2];
|
static unsigned char gpio_int_type1[3];
|
||||||
static unsigned char gpio_int_type2[2];
|
static unsigned char gpio_int_type2[3];
|
||||||
|
|
||||||
static void update_gpio_ab_int_params(int port)
|
static void update_gpio_int_params(int abf)
|
||||||
{
|
{
|
||||||
if (port == 0) {
|
if (abf == 0) {
|
||||||
__raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
|
__raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
|
||||||
__raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2);
|
__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_type1[0], EP93XX_GPIO_A_INT_TYPE1);
|
||||||
__raw_writeb(gpio_int_enable[0], EP93XX_GPIO_A_INT_ENABLE);
|
__raw_writeb(gpio_int_enable[0], EP93XX_GPIO_A_INT_ENABLE);
|
||||||
} else if (port == 1) {
|
} else if (abf == 1) {
|
||||||
__raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
|
__raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
|
||||||
__raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2);
|
__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_type1[1], EP93XX_GPIO_B_INT_TYPE1);
|
||||||
__raw_writeb(gpio_int_enable[1], EP93XX_GPIO_B_INT_ENABLE);
|
__raw_writeb(gpio_int_enable[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);
|
||||||
|
} else {
|
||||||
|
BUG();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,8 +199,13 @@ void gpio_line_config(int line, int direction)
|
|||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
if (direction == GPIO_OUT) {
|
if (direction == GPIO_OUT) {
|
||||||
if (line >= 0 && line < 16) {
|
if (line >= 0 && line < 16) {
|
||||||
|
/* Port A/B. */
|
||||||
gpio_int_enable[line >> 3] &= ~(1 << (line & 7));
|
gpio_int_enable[line >> 3] &= ~(1 << (line & 7));
|
||||||
update_gpio_ab_int_params(line >> 3);
|
update_gpio_int_params(line >> 3);
|
||||||
|
} else if (line >= 40 && line < 48) {
|
||||||
|
/* Port F. */
|
||||||
|
gpio_int_enable[2] &= ~(1 << (line & 7));
|
||||||
|
update_gpio_int_params(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
v = __raw_readb(data_direction_register);
|
v = __raw_readb(data_direction_register);
|
||||||
@ -244,8 +256,7 @@ EXPORT_SYMBOL(gpio_line_set);
|
|||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* EP93xx IRQ handling
|
* EP93xx IRQ handling
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
|
static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||||
struct irq_desc *desc)
|
|
||||||
{
|
{
|
||||||
unsigned char status;
|
unsigned char status;
|
||||||
int i;
|
int i;
|
||||||
@ -267,37 +278,46 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ep93xx_gpio_ab_irq_mask_ack(unsigned int irq)
|
static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
int gpio_irq = IRQ_EP93XX_GPIO(16) + (((irq + 1) & 7) ^ 4);
|
||||||
|
|
||||||
|
desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
|
||||||
{
|
{
|
||||||
int line = irq - IRQ_EP93XX_GPIO(0);
|
int line = irq - IRQ_EP93XX_GPIO(0);
|
||||||
int port = line >> 3;
|
int port = line >> 3;
|
||||||
|
|
||||||
gpio_int_enable[port] &= ~(1 << (line & 7));
|
gpio_int_enable[port] &= ~(1 << (line & 7));
|
||||||
update_gpio_ab_int_params(port);
|
update_gpio_int_params(port);
|
||||||
|
|
||||||
if (line >> 3) {
|
if (port == 0) {
|
||||||
__raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
|
|
||||||
} else {
|
|
||||||
__raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK);
|
__raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK);
|
||||||
|
} else if (port == 1) {
|
||||||
|
__raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
|
||||||
|
} else if (port == 2) {
|
||||||
|
__raw_writel(1 << (line & 7), EP93XX_GPIO_F_INT_ACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ep93xx_gpio_ab_irq_mask(unsigned int irq)
|
static void ep93xx_gpio_irq_mask(unsigned int irq)
|
||||||
{
|
{
|
||||||
int line = irq - IRQ_EP93XX_GPIO(0);
|
int line = irq - IRQ_EP93XX_GPIO(0);
|
||||||
int port = line >> 3;
|
int port = line >> 3;
|
||||||
|
|
||||||
gpio_int_enable[port] &= ~(1 << (line & 7));
|
gpio_int_enable[port] &= ~(1 << (line & 7));
|
||||||
update_gpio_ab_int_params(port);
|
update_gpio_int_params(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ep93xx_gpio_ab_irq_unmask(unsigned int irq)
|
static void ep93xx_gpio_irq_unmask(unsigned int irq)
|
||||||
{
|
{
|
||||||
int line = irq - IRQ_EP93XX_GPIO(0);
|
int line = irq - IRQ_EP93XX_GPIO(0);
|
||||||
int port = line >> 3;
|
int port = line >> 3;
|
||||||
|
|
||||||
gpio_int_enable[port] |= 1 << (line & 7);
|
gpio_int_enable[port] |= 1 << (line & 7);
|
||||||
update_gpio_ab_int_params(port);
|
update_gpio_int_params(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -306,13 +326,17 @@ static void ep93xx_gpio_ab_irq_unmask(unsigned int irq)
|
|||||||
* edge (1) triggered, while gpio_int_type2 controls whether it
|
* edge (1) triggered, while gpio_int_type2 controls whether it
|
||||||
* triggers on low/falling (0) or high/rising (1).
|
* triggers on low/falling (0) or high/rising (1).
|
||||||
*/
|
*/
|
||||||
static int ep93xx_gpio_ab_irq_type(unsigned int irq, unsigned int type)
|
static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
|
||||||
{
|
{
|
||||||
int port;
|
int port;
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
line = irq - IRQ_EP93XX_GPIO(0);
|
line = irq - IRQ_EP93XX_GPIO(0);
|
||||||
gpio_line_config(line, GPIO_IN);
|
if (line >= 0 && line < 16) {
|
||||||
|
gpio_line_config(line, GPIO_IN);
|
||||||
|
} else {
|
||||||
|
gpio_line_config(EP93XX_GPIO_LINE_F(line), GPIO_IN);
|
||||||
|
}
|
||||||
|
|
||||||
port = line >> 3;
|
port = line >> 3;
|
||||||
line &= 7;
|
line &= 7;
|
||||||
@ -330,16 +354,17 @@ static int ep93xx_gpio_ab_irq_type(unsigned int irq, unsigned int type)
|
|||||||
gpio_int_type1[port] &= ~(1 << line);
|
gpio_int_type1[port] &= ~(1 << line);
|
||||||
gpio_int_type2[port] &= ~(1 << line);
|
gpio_int_type2[port] &= ~(1 << line);
|
||||||
}
|
}
|
||||||
update_gpio_ab_int_params(port);
|
update_gpio_int_params(port);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irq_chip ep93xx_gpio_ab_irq_chip = {
|
static struct irq_chip ep93xx_gpio_irq_chip = {
|
||||||
.ack = ep93xx_gpio_ab_irq_mask_ack,
|
.name = "GPIO",
|
||||||
.mask = ep93xx_gpio_ab_irq_mask,
|
.ack = ep93xx_gpio_irq_mask_ack,
|
||||||
.unmask = ep93xx_gpio_ab_irq_unmask,
|
.mask = ep93xx_gpio_irq_mask,
|
||||||
.set_type = ep93xx_gpio_ab_irq_type,
|
.unmask = ep93xx_gpio_irq_unmask,
|
||||||
|
.set_type = ep93xx_gpio_irq_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -350,12 +375,21 @@ void __init ep93xx_init_irq(void)
|
|||||||
vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
|
vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
|
||||||
vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
|
vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
|
||||||
|
|
||||||
for (irq = IRQ_EP93XX_GPIO(0) ; irq <= IRQ_EP93XX_GPIO(15); irq++) {
|
for (irq = IRQ_EP93XX_GPIO(0); irq <= IRQ_EP93XX_GPIO(23); irq++) {
|
||||||
set_irq_chip(irq, &ep93xx_gpio_ab_irq_chip);
|
set_irq_chip(irq, &ep93xx_gpio_irq_chip);
|
||||||
set_irq_handler(irq, handle_level_irq);
|
set_irq_handler(irq, handle_level_irq);
|
||||||
set_irq_flags(irq, IRQF_VALID);
|
set_irq_flags(irq, IRQF_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
|
set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +73,11 @@
|
|||||||
|
|
||||||
#define EP93XX_GPIO_BASE (EP93XX_APB_VIRT_BASE + 0x00040000)
|
#define EP93XX_GPIO_BASE (EP93XX_APB_VIRT_BASE + 0x00040000)
|
||||||
#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
|
#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
|
||||||
|
#define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c)
|
||||||
|
#define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50)
|
||||||
|
#define EP93XX_GPIO_F_INT_ACK EP93XX_GPIO_REG(0x54)
|
||||||
|
#define EP93XX_GPIO_F_INT_ENABLE EP93XX_GPIO_REG(0x58)
|
||||||
|
#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
|
||||||
#define EP93XX_GPIO_A_INT_TYPE1 EP93XX_GPIO_REG(0x90)
|
#define EP93XX_GPIO_A_INT_TYPE1 EP93XX_GPIO_REG(0x90)
|
||||||
#define EP93XX_GPIO_A_INT_TYPE2 EP93XX_GPIO_REG(0x94)
|
#define EP93XX_GPIO_A_INT_TYPE2 EP93XX_GPIO_REG(0x94)
|
||||||
#define EP93XX_GPIO_A_INT_ACK EP93XX_GPIO_REG(0x98)
|
#define EP93XX_GPIO_A_INT_ACK EP93XX_GPIO_REG(0x98)
|
||||||
|
@ -67,9 +67,13 @@
|
|||||||
#define IRQ_EP93XX_SAI 60
|
#define IRQ_EP93XX_SAI 60
|
||||||
#define EP93XX_VIC2_VALID_IRQ_MASK 0x1fffffff
|
#define EP93XX_VIC2_VALID_IRQ_MASK 0x1fffffff
|
||||||
|
|
||||||
#define IRQ_EP93XX_GPIO(x) (64 + (x))
|
/*
|
||||||
|
* Map GPIO A0..A7 to irq 64..71, B0..B7 to 72..79, and
|
||||||
|
* F0..F7 to 80..87.
|
||||||
|
*/
|
||||||
|
#define IRQ_EP93XX_GPIO(x) (64 + (((x) + (((x) >> 2) & 8)) & 0x1f))
|
||||||
|
|
||||||
#define NR_EP93XX_IRQS IRQ_EP93XX_GPIO(16)
|
#define NR_EP93XX_IRQS (64 + 24)
|
||||||
|
|
||||||
#define EP93XX_BOARD_IRQ(x) (NR_EP93XX_IRQS + (x))
|
#define EP93XX_BOARD_IRQ(x) (NR_EP93XX_IRQS + (x))
|
||||||
#define EP93XX_BOARD_IRQS 32
|
#define EP93XX_BOARD_IRQS 32
|
||||||
|
Loading…
Reference in New Issue
Block a user