irq; support irq revert trigger type and get gpio level
Change-Id: Ib897bb37c518429c595903bb8f2cfd9fcea9aa78 Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
parent
bb9827924e
commit
c234b81e6a
|
|
@ -162,6 +162,28 @@ int irq_set_irq_type(int irq, unsigned int type)
|
|||
return gpio_irq_chip->irq_set_type(irq, type);
|
||||
}
|
||||
|
||||
int irq_revert_irq_type(int irq)
|
||||
{
|
||||
if (irq_bad(irq))
|
||||
return -EINVAL;
|
||||
|
||||
if (irq < PLATFORM_GIC_IRQS_NR)
|
||||
return 0;
|
||||
else
|
||||
return gpio_irq_chip->irq_revert_type(irq);
|
||||
}
|
||||
|
||||
int irq_get_gpio_level(int irq)
|
||||
{
|
||||
if (irq_bad(irq))
|
||||
return -EINVAL;
|
||||
|
||||
if (irq < PLATFORM_GIC_IRQS_NR)
|
||||
return 0;
|
||||
else
|
||||
return gpio_irq_chip->irq_get_gpio_level(irq);
|
||||
}
|
||||
|
||||
void irq_install_handler(int irq, interrupt_handler_t *handler, void *data)
|
||||
{
|
||||
if (irq_bad(irq))
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ static void gpio_bit_op(void __iomem *regbase, unsigned int offset,
|
|||
writel(val, regbase + offset);
|
||||
}
|
||||
|
||||
static int gpio_bit_rd(void __iomem *regbase, unsigned int offset, u32 bit)
|
||||
{
|
||||
return readl(regbase + offset) & bit ? 1 : 0;
|
||||
}
|
||||
|
||||
static void gpio_irq_unmask(void __iomem *regbase, unsigned int bit)
|
||||
{
|
||||
gpio_bit_op(regbase, GPIO_INTEN, bit, 1);
|
||||
|
|
@ -137,6 +142,34 @@ static void gpio_set_intr_type(void __iomem *regbase,
|
|||
}
|
||||
}
|
||||
|
||||
static int gpio_get_intr_type(void __iomem *regbase,
|
||||
unsigned int bit)
|
||||
{
|
||||
u32 polarity, level, magic = 0;
|
||||
int type;
|
||||
|
||||
polarity = gpio_bit_rd(regbase, GPIO_INT_POLARITY, bit);
|
||||
level = gpio_bit_rd(regbase, GPIO_INTTYPE_LEVEL, bit);
|
||||
magic = (polarity << 1) | (level << 0);
|
||||
|
||||
switch (magic) {
|
||||
case 0x00:
|
||||
type = GPIOLevelLow;
|
||||
break;
|
||||
case 0x02:
|
||||
type = GPIOLevelHigh;
|
||||
break;
|
||||
case 0x01:
|
||||
type = GPIOEdgelFalling;
|
||||
break;
|
||||
case 0x03:
|
||||
type = GPIOEdgelRising;
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static int gpio_irq_set_type(int gpio_irq, unsigned int type)
|
||||
{
|
||||
int gpio = irq_to_gpio(gpio_irq);
|
||||
|
|
@ -175,6 +208,58 @@ static int gpio_irq_set_type(int gpio_irq, unsigned int type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_irq_revert_type(int gpio_irq)
|
||||
{
|
||||
int gpio = irq_to_gpio(gpio_irq);
|
||||
struct gpio_bank *bank = gpio_to_bank(gpio);
|
||||
eGPIOIntType_t int_type = 0;
|
||||
int type;
|
||||
|
||||
if (!bank)
|
||||
return -EINVAL;
|
||||
|
||||
gpio &= GPIO_PIN_MASK;
|
||||
if (gpio >= bank->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
type = gpio_get_intr_type(bank->regbase, offset_to_bit(gpio));
|
||||
switch (type) {
|
||||
case GPIOEdgelFalling:
|
||||
int_type = GPIOEdgelRising;
|
||||
break;
|
||||
case GPIOEdgelRising:
|
||||
int_type = GPIOEdgelFalling;
|
||||
break;
|
||||
case GPIOLevelHigh:
|
||||
int_type = GPIOLevelLow;
|
||||
break;
|
||||
case GPIOLevelLow:
|
||||
int_type = GPIOLevelHigh;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpio_set_intr_type(bank->regbase, offset_to_bit(gpio), int_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_irq_get_gpio_level(int gpio_irq)
|
||||
{
|
||||
int gpio = irq_to_gpio(gpio_irq);
|
||||
struct gpio_bank *bank = gpio_to_bank(gpio);
|
||||
|
||||
if (!bank)
|
||||
return -EINVAL;
|
||||
|
||||
gpio &= GPIO_PIN_MASK;
|
||||
if (gpio >= bank->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
return gpio_bit_rd(bank->regbase, GPIO_EXT_PORT, offset_to_bit(gpio));
|
||||
}
|
||||
|
||||
static int gpio_irq_enable(int gpio_irq)
|
||||
{
|
||||
int gpio = irq_to_gpio(gpio_irq);
|
||||
|
|
@ -238,6 +323,8 @@ static struct irq_chip gpio_irq_chip = {
|
|||
.irq_enable = gpio_irq_enable,
|
||||
.irq_disable = gpio_irq_disable,
|
||||
.irq_set_type = gpio_irq_set_type,
|
||||
.irq_revert_type = gpio_irq_revert_type,
|
||||
.irq_get_gpio_level = gpio_irq_get_gpio_level,
|
||||
};
|
||||
|
||||
struct irq_chip *arch_gpio_irq_init(void)
|
||||
|
|
|
|||
|
|
@ -55,14 +55,18 @@ struct irq_chip {
|
|||
void (*irq_ack)(int irq);
|
||||
void (*irq_eoi)(int irq);
|
||||
int (*irq_set_type)(int irq, unsigned int flow_type);
|
||||
int (*irq_revert_type)(int irq);
|
||||
int (*irq_get_gpio_level)(int irq);
|
||||
};
|
||||
|
||||
/* APIs for irqs */
|
||||
void irq_install_handler(int irq, interrupt_handler_t *handler, void *data);
|
||||
void irq_free_handler(int irq);
|
||||
int irq_set_irq_type(int irq, unsigned int type);
|
||||
int irq_revert_irq_type(int irq);
|
||||
int irq_handler_enable(int irq);
|
||||
int irq_handler_disable(int irq);
|
||||
int irq_get_gpio_level(int irq);
|
||||
int irqs_suspend(void);
|
||||
int irqs_resume(void);
|
||||
int gpio_to_irq(struct gpio_desc *gpio);
|
||||
|
|
|
|||
Loading…
Reference in New Issue