irq: virq: add parent irq enable/disable management

- disable virq chip by default;
- fix bank->use_count little than 0;

Change-Id: I69aa07cc2924dab40eea6524588869361ad8cf66
Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
Joseph Chen 2019-10-22 18:09:11 +08:00
parent e6c4e3fbd5
commit 25c13168fe
4 changed files with 44 additions and 8 deletions

View File

@ -414,7 +414,7 @@ static int do_dump_irqs(cmd_tbl_t *cmdtp, int flag,
char *drv_name;
int pirq;
printf(" IRQ En Handler Driver Name Count\n");
printf(" IRQ En Handler Driver Name Trig\n");
printf("----------------------------------------------------------------------\n");
for (pirq = 0; pirq < PLATFORM_MAX_IRQ; pirq++) {

View File

@ -290,6 +290,9 @@ static int gpio_irq_disable(int irq)
if (!bank)
return -EINVAL;
if (bank->use_count <= 0)
return 0;
gpio &= GPIO_PIN_MASK;
if (gpio >= bank->ngpio)
return -EINVAL;

View File

@ -38,6 +38,7 @@ struct virq_desc {
struct virq_data *virqs; /* child irq data list */
struct udevice *parent; /* parent device */
int pirq; /* parent irq */
int use_count; /* enable count */
int irq_base; /* child irq base */
int irq_end; /* child irq end */
uint reg_stride;
@ -238,12 +239,12 @@ void virq_chip_generic_handler(int pirq, void *pdata)
}
}
int virq_add_chip(struct udevice *dev, struct virq_chip *chip,
int irq, int enable)
int virq_add_chip(struct udevice *dev, struct virq_chip *chip, int irq)
{
struct virq_data *vdata;
struct virq_desc *desc;
uint *status_buf;
uint status_reg;
uint mask_reg;
int ret;
int i;
@ -274,6 +275,7 @@ int virq_add_chip(struct udevice *dev, struct virq_chip *chip,
desc->pirq = irq;
desc->chip = chip;
desc->virqs = vdata;
desc->use_count = 0;
desc->irq_base = vdata[0].irq;
desc->irq_end = vdata[chip->num_irqs - 1].irq;
desc->status_buf = status_buf;
@ -292,10 +294,19 @@ int virq_add_chip(struct udevice *dev, struct virq_chip *chip,
__func__, mask_reg, ret);
}
/* Clear all status */
for (i = 0; i < chip->num_regs; i++) {
status_reg = reg_base_get(desc, chip->status_base, i);
ret = chip->i2c_write(dev, status_reg, ~0U);
if (ret)
printf("%s: Clear status register 0x%x failed, ret=%d\n",
__func__, status_reg, ret);
}
/* Add parent irq into interrupt framework with generic virq handler */
irq_install_handler(irq, virq_chip_generic_handler, dev);
return enable ? irq_handler_enable(irq) : irq_handler_disable(irq);
return irq_handler_disable(irq);
free1:
free(desc);
@ -358,18 +369,41 @@ static int __virq_enable(int irq, int enable)
static int virq_enable(int irq)
{
struct virq_desc *desc = find_virq_desc(irq);
int ret;
if (bad_virq(irq))
return -EINVAL;
return __virq_enable(irq, 1);
ret = __virq_enable(irq, 1);
if (!ret) {
if (desc->use_count == 0)
irq_handler_enable(desc->pirq);
desc->use_count++;
}
return ret;
}
static int virq_disable(int irq)
{
struct virq_desc *desc = find_virq_desc(irq);
int ret;
if (bad_virq(irq))
return -EINVAL;
return __virq_enable(irq, 0);
ret = __virq_enable(irq, 0);
if (!ret) {
if (desc->use_count <= 0)
return ret;
if (desc->use_count == 1)
irq_handler_disable(desc->pirq);
desc->use_count--;
}
return ret;
}
struct irq_chip virq_generic_chip = {

View File

@ -120,7 +120,6 @@ int phandle_gpio_to_irq(u32 gpio_phandle, u32 pin);
/* Virtual irq */
int virq_to_irq(struct virq_chip *chip, int virq);
int virq_add_chip(struct udevice *dev, struct virq_chip *chip,
int irq, int enable);
int virq_add_chip(struct udevice *dev, struct virq_chip *chip, int irq);
#endif /* _IRQ_GENERIC_H */