> > + > > +static int sch_gpio_irq_type(struct irq_data *d, unsigned type) > > +{ > > + struct sch_gpio *sch = container_of(d, struct sch_gpio, data); > > + unsigned long flags; > > + u32 gpio_num; > > + > > + if (d == NULL) > > + return -EINVAL; > > + > > + gpio_num = d->irq - sch->irq_base; > > + > > + spin_lock_irqsave(&sch->lock, flags); > > + > > + switch (type) { > > + case IRQ_TYPE_EDGE_RISING: > > + sch_gpio_register_set(sch, gpio_num, GTPE); > > + sch_gpio_register_clear(sch, gpio_num, GTNE); > > You will have the same problem as I pointed out in patch 1/3 that > sch_gpio_register_set/clear() will try to acquire the already-locked > sch->lock. No way this can ever work, or I am under a serious > misapprehension. > > > + break; > > + > > + case IRQ_TYPE_EDGE_FALLING: > > + sch_gpio_register_set(sch, gpio_num, GTNE); > > + sch_gpio_register_clear(sch, gpio_num, GTPE); > > + break; > > + > > + case IRQ_TYPE_EDGE_BOTH: > > + sch_gpio_register_set(sch, gpio_num, GTPE); > > + sch_gpio_register_set(sch, gpio_num, GTNE); > > + break; > > + > > + case IRQ_TYPE_NONE: > > + sch_gpio_register_clear(sch, gpio_num, GTPE); > > + sch_gpio_register_clear(sch, gpio_num, GTNE); > > + break; > > + > > + default: > > + spin_unlock_irqrestore(&sch->lock, flags); > > + return -EINVAL; > > + } > > + > > + spin_unlock_irqrestore(&sch->lock, flags); > > + > > + return 0; > > +} > > + > > +static struct irq_chip sch_irq_chip = { > > + .irq_enable = sch_gpio_irq_enable, > > + .irq_disable = sch_gpio_irq_disable, > > + .irq_ack = sch_gpio_irq_ack, > > + .irq_set_type = sch_gpio_irq_type, > > +}; > > + > > +static void sch_gpio_irqs_init(struct sch_gpio *sch, unsigned int num) > > +{ > > + unsigned int i; > > + > > + for (i = 0; i < num; i++) { > > + irq_set_chip_data(i + sch->irq_base, sch); > > + irq_set_chip_and_handler_name(i + sch->irq_base, > > + &sch_irq_chip, > > + handle_simple_irq, > > + "sch_gpio_irq_chip"); > > + } > > +} > > + > > +static void sch_gpio_irqs_deinit(struct sch_gpio *sch, unsigned int num) > > +{ > > + unsigned int i; > > + > > + for (i = 0; i < num; i++) { > > + irq_set_chip_data(i + sch->irq_base, 0); > > + irq_set_chip_and_handler_name(i + sch->irq_base, 0, 0, 0); > > + } > > +} > > + > > +static void sch_gpio_irq_disable_all(struct sch_gpio *sch, unsigned int num) > > +{ > > + unsigned long flags; > > + unsigned int gpio_num; > > + > > + spin_lock_irqsave(&sch->lock, flags); > > + > > + for (gpio_num = 0; gpio_num < num; gpio_num++) { > > + sch_gpio_register_clear(sch, gpio_num, GTPE); > > + sch_gpio_register_clear(sch, gpio_num, GTNE); > > + sch_gpio_register_clear(sch, gpio_num, GGPE); > > + sch_gpio_register_clear(sch, gpio_num, GSMI); > > Same here. Alright. I should have noticed this double locking issue earlier. Thanks. I think the next version will be much cleaner. Thanks for spending time and effort to review. Rebecca ��.n��������+%������w��{.n�����{�� b���ܨ}���Ơz�j:+v�����w����ޙ��&�)ߡ�a����z�ޗ���ݢj��w�f