[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CACRpkdbVnpdPUaMZRr-Lh27MZjM-CUwzgsy1QfzDR7tbHFPZWw@mail.gmail.com>
Date: Tue, 22 Dec 2015 09:44:29 +0100
From: Linus Walleij <linus.walleij@...aro.org>
To: Peter Rosin <peda@...ntia.se>
Cc: Jonathan Cameron <jic23@...nel.org>,
Peter Rosin <peda@...ator.liu.se>,
"linux-iio@...r.kernel.org" <linux-iio@...r.kernel.org>,
"linux-gpio@...r.kernel.org" <linux-gpio@...r.kernel.org>,
Alexandre Courbot <gnurou@...il.com>,
Jean-Christophe Plagniol-Villard <plagnioj@...osoft.com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"linux-arm-kernel@...ts.infradead.org"
<linux-arm-kernel@...ts.infradead.org>,
Lars-Peter Clausen <lars@...afoo.de>,
Matt Porter <mporter@...sulko.com>,
Marc Zyngier <marc.zyngier@....com>
Subject: Re: [RESEND RFC PATCH 0/2] Expose the PIO_ISR register on SAMA5D3
On Fri, Dec 18, 2015 at 12:19 AM, Peter Rosin <peda@...ntia.se> wrote:
> This all makes sense. The reason is that I'm not familiar with
> the kernel APIs. I have to wrap my head around how to set up
> work to be performed later, etc etc.
FWIW a random work to be performed later is a delayed work.
It can be queued on a global workqueue or you can create your
own workqueue. This is the latter way, it's even simpler if you
just use NULL as workqueue, it will then end up on the big
system workqueue. The workqueue in turn uses deferrable timers,
and these can also be used directly.
#include <linux/workqueue.h>
struct foo {
struct workqueue_struct *foo_wq;
struct delayed_work delayed_foo_work;
....
};
static void foo_work_cb(struct work_struct *work)
{
struct foo *foo = container_of(work, struct foo, delayed_foo_work.work);
... do the work ...
};
main {
INIT_DEFERRABLE_WORK(&foo->delayed_foo_work, foo_work_cb);
queue_delayed_work(foo->foo_wq, &foo->delayed_foo_work, 6*HZ);
}
6*HZ means wait for 6 seconds as the delay is given in ticks (jiffies)
and the system does HZ ticks per second.
>> > I have realized that I could work with one-shot-interrupts. Then the
>> > urgency to disable interrupts go away, as only one interrupt would
>> > be served. That was not my immediate solution though, as I have been
>> > using isr type registers in this way several times before.
>>
>> That sounds like the right solution. With ONESHOT a threaded IRQ
>> will have its line masked until you return from the ISR thread. Would this
>> work for your usecase?
>
> The ISR thread would need to be able to disable further interrupts
> before it returned, is that possible without deadlock? If so, it's
> a good fit.
Yes that is what the ONESHOT flag means. So like this:
ret = request_threaded_irq(irqnum, NULL, foo_irq_handler,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"foo", foo);
To register a threaded oneshot IRQ that will run on a falling edge,
as a thread, until completed, masking its own interrupt line, but
no others.
The threaded handler can msleep(), mdelay()/udelay() etc since it
is a thread. usleep_range(a, b) is the best as the system can idle
while that happens, and can plan for a good wakeup point.
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists