[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <50B33AC5ED75F74F991980326F1C438D0FC00922@PGSMSX108.gar.corp.intel.com>
Date: Thu, 23 Oct 2014 07:29:38 +0000
From: "Chang, Rebecca Swee Fun" <rebecca.swee.fun.chang@...el.com>
To: 'Alexandre Courbot' <gnurou@...il.com>
CC: Linus Walleij <linus.walleij@...aro.org>,
"Westerberg, Mika" <mika.westerberg@...el.com>,
GPIO Subsystem Mailing List <linux-gpio@...r.kernel.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Denis Turischev <denis.turischev@...pulab.co.il>
Subject: RE: [PATCHv3 3/3] gpio: sch: Enable IRQ support for Quark X1000
> > +
> > +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
Powered by blists - more mailing lists