

Writing a Linux Kernel Module — Part 3: Buttons and LEDs - OrangeTux
http://derekmolloy.ie/kernel-gpio-programming-buttons-and-leds/

======
buserror
Nice article; however, in 'real life' I always try to do without having to use
all of these APIs if I can get away with it. The overhead is quite massive,
even with something as simple as the GPIO library.

Also, I'd rather use a tasklet than a kthread to offload 'work' from interrupt
contexts.

~~~
simias
I strongly disagree with that. Especially with the GPIO library which is as
thin as it gets (you can even redefine gpio_get_value, gpio_set_value etc...
in the BSP if you want an extra-fast board-specific version). In my experience
the overhead is really small actually and it gives you some nice debugging
tools (the sysfs interface and debugfs entry in particular).

If you implement a GPIO controller driver using the gpiolib means that all
other drivers and userland tools will be able to interface with you at no
cost. If you write a device driver that uses a GPIO using the gpiolib means
that you'll be able to use your driver even if the GPIO gets wired on an
external I2C "expander" or something like that.

Pushing your logic to the extreme one might as well get rid of the kernel and
write on bare metal to make sure not to waste any CPU cycle or memory byte on
a abstraction layer. What is a kernel in the end if not a set of standardized
APIs?

It's true that there's some bloat in a few of the kernel's APIs (the video
comes to mind, although I won't pretend I would be able to do it better) but
that shouldn't be a reason to "always try to do without having to use all of
these APIs". Unless you only write code that's only intended to be used on a
particular software configuration on a single board without any possible
evolution or reuse it's really asking for trouble in the long term.

If I have to integrate a third party driver and I see that they use some
custom made GPIO interface instead of the standard kernel API I'm going to be
very annoyed.

~~~
buserror
I don't disagree with the fact gpiolib is a good idea etc, however more often
than not, if I'm hired to make a firmware for a particular device, the work
required to tailor a driver for best efficiency is worth it, and will be
minimal compared to the rest. You can always #ifdef the changes too...

If you use GPIOs for a couple LED, pin configuration and stuff like that it's
perfectly adequate, and won't require a driver anyway. If your GPIO expander
is on i2c then you clearly are not worrying about latency anyway, so gpiolib
is just fine.

If you make a driver to use the gpios for more critical time sensitive things
(overcurrent/thermal protections and that sort of things, or bitbanging), and
then realize that actually, it's pretty crap and you'd be better off mmaping
/dev/mem and poke at the registers directly from userland to get the
performance/latency that is needed, your driver was a waste of time if you
went that way first...

~~~
simias
Can you point out exactly why it's pretty crap?

Again, gpiolib lets you redefine gpio_get_value, gpio_set_value, gpio_cansleep
and gpio_to_irq in the BSP to be specialized inline macros if you want to, it
means that for a specific board you can just straight to the hardware if you
want to avoid any kind of indirection. I don't see what you could possibly do
to make it even faster, gpiolib or not.

But even if you don't do that the only cost will mostly be an indirect
function pointer call to the GPIO controller's driver, we're talking
nanoseconds here (assuming it's in cache). Might be worth it for bitbanging
applications.

At any rate, while I totally believe there are situations where the gpiolib
doesn't quite cut it I don't think it's good advice to tell kernel beginners
(the audience of TFA) to avoid it on principle alone. In my experience 99% of
the time I use GPIOs to de-reset a chip, read a switch/button or, when I feel
fancy, light up a LED.

------
sgt
Many people will ask "why not do this in user space?" The article answers
this:

Unlike Linux user space, the Linux kernel space has support for interrupts.
The first example in this article demonstrates how you can write an LKM that
uses GPIOs and interrupts to achieve a faster response time than is possible
in user space.

~~~
OrangeTux
But what if you've a complex app which interacts with GPIOs? You don't want to
write the whole app a LMK and run in in kernel space, do you?

I've written a JSON-RPC API which can be used to interact with GPIOs.
Currently I set/get a GPIO using sysfs. During handling of a request the
operations on sysfs take most of the response time, far more time than parsing
the request and writing the result to the client. How could I speed up the
GPIO interaction with a LKM?

~~~
sgt
As much as it's fun to create kernel modules and experiment with kernel space,
I'll have to agree with this. If you can keep things simple and use existing
facilities, that should generally be the goal.

------
revelation
None of this needs an actual kernel driver. You can use interrupt gpios from
userspace using poll.

~~~
kenz0r
You can, or you can use the gpio_keys driver to nicely handle it in kernel
space and give you key presses via the event subsystem. One small device tree
snippet, and you're sorted. There is even a gpio_keys_polled variant if you
can't get interrupts from your GPIO controller.

