Okay. Hello, my name is Bartos Gileshevsky. I'm based in France. I'm originally from Poland,
and I have been working in the embedded Linux space for 16 years, actually, in 15. I maintain
the GPIO subsystem and Linux kernel, and the new power sequencing subsystem, and also the counterpart
in user space for the GPIO subsystem, which is LiPGPAD. I also contribute to many other open source projects,
and I have a weird hobby of jumping out of perfectly good airplane for fun. I'm here on behalf of Flenaro.
Check us out. We make Linux, I'm running well on ARM. I'm personally in the Qualcomm landing team,
and this has been what I've been doing professionally for the last couple of years.
And today, I'm going to be talking about GPIO and the system class.
So over the course of the last years, I've given several talks about LiPGPAD, and about how I would prefer to remove
the old legacy SSFS class from the kernel, and why the collector device is better.
And I've been asked several times why we want to remove SSFS, like what's wrong, it's been around for so many years.
It's useful. Why do you hate it? And the answer to this is I don't only hate SSFS, there is a deeper problem to it.
It is a bad interface, and it cannot really be improved now, that has been covered in stone for many years.
But the problem is just much more complex. So GPIO lib, the kernel subsystem for GPIO, has been around for a very long time,
and it has a problem with craft. It has accumulated a lot of unnecessary things.
And I've talked about it in detail during my talk last year, or was it years ago not sure.
So what's the problem? We, GPIO lib, has been around for two decades.
That means that it has been created way before we even had a driver model in the kernel.
And it has been modified and improved by many people, had several maintainers.
And the main users for a long time for GPIO lib were ARM and MIPS in the dark times of board files.
This is when the entire driver model, it wasn't even there, was very fragmented.
The drivers would be implemented at Hawke in other arch in board files.
This has caused a lot of things being implemented.
It just caused a lot of bad engineering but program.
And what we ended up with now is, we have two interfaces in the kernel for using GPIOs.
We have the modern one, which is descriptors, opaque structures, which you get assigned in femur and dtore,
a CPI, and then relevant drivers can retrieve their GPIOs and use them.
And legacy numbers, space, base system, where you basically have magic numbers and you request GPIO 42 for no reason.
There's nothing to do with hardware offsets of controllers.
So, yeah, as I said, many people have tried to improve it.
We have made a lot of advancements recently.
We now support, for instance, hot pluggable USB chips, which wasn't the case before.
But still, we are stuck with these two interfaces.
So, why actually would I want to remove the global number space that legacy interface from the kernel?
So, first of all, having two interfaces for doing the same thing is just bad programming.
So, that alone would lead to a lot of code and duplication.
But also, the legacy interface is just that.
So, first of all, magic numbers, it allows basically any driver to fetch any GPIO that it wants,
even if, you know, nobody said that it's allowed to.
There are many drivers still in the kernel, which use a hard code that base GPIO number.
Because if you have several controllers and they come up different times, the probe ordering can change,
and then the numbers will not be the same.
They will not be what you expect.
So, this is what led to people to just hard code the base number in their GPIO drivers.
And again, that's not unnecessary.
If you use a proper descriptor-based interface.
And finally, since I do maintain that subsystem, I have a personal interest in reducing the maintainer, maintainer ship burden.
What do I? First of all, in the kernel, in the kernel, we still have drivers that use the old interface.
Because that is not a hard problem.
Basically, it's about converting drivers using old interface to using the new one.
We don't have to care about out of three drivers.
That's a them problem and not our problem.
So, if we convert every internal user to the new interface, we can drop the old interface.
It's just that it's very tedious.
It's a task that is not simple enough for kernel janitors to tackle,
but it's not very interesting for advanced developers who want to do something fun.
But as I said, this is not a hard problem. The hard problem is just past GPIO.
So, it's a major user of the legacy interface, but not in the way you think,
it actually uses the new descriptor based interface.
But the user space refers to GPIOs using the global number space.
So, we have to translate the numbers that we get from users' space to the descriptors,
and this is how we do it in the kernel.
This is a hard problem because we advertise the kernel,
UAPI, as indefinitely stable.
So, we cannot, as far as long as users want to keep using this interface, we are stuck with it.
And CISPAS GPIO also has issues.
First of all, just the same problem as for the legacy kernel interface.
It's very brittle if you have shell scripts that refer to some random magic numbers,
like 120, for a given GPIO, and then you have drivers that will come up,
get probed in a different order and the numbers don't mean anything anymore.
You can, of course, scan the labels and then calculate the offset from the base number
and the offset of the GPIO, but that's rather unnecessary calculation in your script.
It's quite feature poor compared to the character device,
which I will focus in a second.
It doesn't admit many, many things.
And the polling for interrupts is quite unreliable,
because it's not a buffer, you just get an notification about an event
and then you have to read it very fast, but if you get enough events in a given time span,
you will not be able to read all of them so you can lose them.
And yeah, so there has been an API in consistency in CISPAS,
that nobody noticed and I just recently realized.
So back in the days of the board files, if you exported a named GPIO,
the link to it in CISPAS would appear as its name,
but for DT-based system, device-driven based system,
that's no longer the case. That was a big change,
and nobody ever noticed.
I just realized when I was working on it on the thing recently,
and that got fixed.
I will give credit where it's due though,
and using the virtual file system actually is quite useful
for fine-grained permission control.
If that's what you are about, give a user permission to access
just this one GPIO line, and that's what you can easily
achieve using the file system.
And also, the CISPAS GPIO works kind of like a centralized authority
for all GPIOs just that it's implemented in the kernel.
So as a maintainer, my long-term goal is to remove CISPAS GPIO from the kernel entirely,
but, unfortunately, I have to first get everyone to stop using it.
And so a quick note on kernel interfaces.
It wouldn't be the first time that the kernel interface gets removed.
So it is true that we're saying,
okay, once it's carved in stone, it's ABI,
we will support it indefinitely,
but history knows at least a couple instances of removing existing kernel interfaces.
So there was a CISP control system call,
which was buggy, had problems with buffer overflows,
and eventually it was removed.
There was a safe death team,
which was a special device providing access to kernel memory.
It also got removed, there was dev raw.
Also, some CISPAS classes.
So there was an RTC class under class MISC.
That was moved to class RTC and reward.
So it wouldn't be the first time that an interface
from CISPAS would be dropped.
But the truth is that if user space objects
to any such backwards incompatible changes,
then we must not remove them.
And unless the interface is harmful, buggy,
but this is not the case here.
Yeah, so where are we at?
Unfortunately, we are not close yet.
And the problem is that I cannot really
don't trump my way out of it,
and impose tariffs on CISPAS.
So I have to go the good way.
And just propose a set of alternatives.
So the most of this one is the character device,
which has been around for almost a year now.
And unfortunately, if you tell users that they have
to drop their neat shell scripts that just write to files
and use custom C code that calls
include CUAPI, kernel headers,
and calls various system calls.
I octose, then the reaction will be quite predictable.
But, well, users want something that works simply simply.
This is why we provide it.
Logically at the set of command line GPIO tools.
So Logically, it is a C library that wraps the kernel interface
better in a better higher level API.
We have bindings to Python, Rust, C++,
G object bindings as well.
And of course, command line tools.
However, the character device inherently works with
file descriptors and file descriptors in unique systems.
When the last process that holds a reference
to a given file descriptor exits,
all the file descriptor file is closed.
And that has caused a lot of confusion for people that
were used to CFS because they realize very fast that
the state of a GPIO is not guaranteed when GPIO set
the program that sets a GPIO value exits.
Because anyone can grab it or even the driver can implement
some default state to which the line reverts.
And people naturally instinctively assume that
GPIO set this GPIO to act if we will make it
state that way, but that's not the case.
So I realize at some point that users do really
want this state persistence exactly what CFS does.
And I really like a fraction layers,
because there is no such problem that cannot be fixed with
another fraction layer.
And I created this thing called GPIO manager.
This is a demon that runs in the background and exposes
the class interface with which you can interact using either
the provided GPIO client or whatever library for
DBS that you want to use.
I presented it in detail during a talk last year.
And what it allows you now is to simply do GPIO
CLI request a line.
And then I'm actually, this slide is wrong.
This should be GPIO CLI set GPIO CLI get,
but sorry for that.
Basically, you request it and the line stays requested
because it's the demon that is responsible for holding it.
And then you can set it stay.
The demon retains it.
And then you can free it when you see it.
The problem is that people still, well, it has seen
some adoption.
I've integrated it in meta-open embedded.
I've had people report back to me.
I think someone started packaging it.
I'm not sure.
But there was some package maintenance
that reached out to me with questions.
But immediately, like, for instance,
after presenting GPIO manager last year,
I was approached by some people and saying,
you know, it's neat and all,
but I don't really want to change my programs.
Because I had my programs for a long time,
and I want to keep them.
So I thought that if you really cannot
be convinced to change, you really want to keep using
Cisco's GPIO, do you really care whether the code for that
runs in the kernel?
Or would you be okay if it run in user space?
So that idea occurred to me when I was looking
for a project to learn Rust and I figured that I need
something that will be useful that will keep me motivated
to actually do a good job.
I figured that I will write an abstraction layer
for CSS in Rust in user space.
And then I started looking at Rust,
because this was my first experience with it.
And I figured that, yeah, Python is good enough, right?
So now there is a thing called GPIO.
These CSS proxy.
This is exactly that.
This is an abstraction layer based on fuse.
And using live GPIO to control GPIOs,
implemented in user space.
So you can get it from GitHub.
You can get it from Python.
And there are some things.
So I would say that it's 99% compatible with CSS.
There is a problem with limitations with fuse.
So you cannot have multiple Polars of a single file in fuse.
And there is also no static GPIO based for chips.
I'm working on it.
I don't want to add it in some way,
but I am sort of consulting people who may have
interested in that on how to approach it.
So configuration file, listing labels of GPIO chips,
and they're predefined basis or something.
That sounds really it.
I will figure that.
I've written a comprehensive set of compatibility tests.
And this script passes them.
So I think it's rather compatible.
You can get it from, you can install from PIP.
And just mount it on the directory of your choice,
which typically would be CIS class GPIO.
But then you'll say, okay,
but I disabled CIS class GPIO in my kernel config.
I don't have that directory,
and I cannot empty the GPIO in CIS class.
So what do I do?
Well, you can use overlay FS.
And I actually sent a patch to Greg KH,
adding a predefined mount point for CIS class GPIO
if this class is disabled.
Just like what you have for debug FS or config FS.
He said that it's disgusting.
He was very, very unhappy with it.
And then I played with overlay FS and figured that I can simply overlay
this directory on top of CIS class.
And I sent the response to him saying,
I no longer need that patch.
I can do it in user space.
And he never responded.
And I can imagine that he's faced with something like this.
So what's next for that?
I want to support static predefined
to hardcore the GPIO base numbers.
I want to get some traction for it.
So please check it out.
I still want to learn Rust.
And I figured that maybe there is.
There would be interest in having a proper.
A better file system based interface for GPIOs.
This is something that Linux Valesh,
the commentator for GPIO float at some time ago.
Like, oh, I would, you know, I don't,
I'm not against having a user file system based interface.
Maybe you should work on a new one that would live in debug effects.
But I'm like, OK, let's not add anything to the kernel.
Let's do it in user space.
And I, my, my, my, my to do this is running over,
but I, I intend to get to it at some point.
And finally, oh, this is the last GPIO will stay there for a while.
We can remove it as long as it has users.
We have alternatives in the form of live GPIOD.
We have, I'll turn on a compatible alternative in the form of the system's proxy.
And well, the work continues on converting the kernel drivers,
the legacy kernel drivers to using the new API.
And once we get that done, that will make a much more strong,
stronger case for removing the old interface and subsequently the GPIO class.
And yeah, right on time, that's it.
Thank you very much.
And I'm open to question.
Question.
For other alternatives from a minimal user space,
like when you're most the only one to use things like busy box.
So if you only want to use busy box,
plan some scripts, but not even fully in it.
For other alternatives,
send this out, having to start a bunch of demons.
I think the question is.
Yeah, I, I, I, I, I'm trying to, I'm thinking about the answer.
If you really just want busy box and not run anything other than busy box,
then, all the closest thing is running GPIO tools.
They are very tiny.
These are very tiny programs.
And I guess you're not running only this box.
You typically will have something else.
Something on top of it.
So the closest will be just just running the GPIO tools.
I mean, yeah.
Oh, I'm not gonna.
That's enough.
Not yourself out.
So the broad come GPIO drivers,
that's used as Raspberry Pi's, has a kernel module parameter
to enable GPIO persistence.
So even if you release a release line,
it returns to the old value.
And it's upstream.
Why can't we have that for all GPIO controllers?
And just use GPIO set without having to use demons.
Why only this one driver is allowed to have it,
and the others, not couldn't we add like a flag?
And request, please, I want to have GPIO persistence,
and the drivers just do the correcting.
Do you have three hours?
So, uh, I, okay, but surely,
register that for the embedded dinners.
We sit next to each other.
I'm sure you know.
The idea of like,
safe state property in device three for GPIOs
has been around for a while.
We just couldn't get any traction of for it with
DT maintainers.
And yeah, there is this idea that,
oh, we should actually limit the available states of GPIOs
because some of them may be regulators that may damage hardware
if they enter a certain state.
Yes, that, that, that, that is an idea,
but I'm, I'm not sure if it's going to go anywhere
in, in, in the new future,
but we can talk about it doing the dinners.
Okay, but for respite, it went somewhere.
So why not?
I, I am not sure if it,
ever, so it's, is it a kernel module?
Is it a kernel parameter?
Or is it a device three property?
Okay.
I'll just follow up on this gentleman over there.
What happens if you have, in a drum of us,
with just visible.
Basically, at that point, you do not have python
to run the proxy.
You don't have potential GPIO tools
because you are limited in size.
What now, you are left with the system of a interface anyway.
And actually, this is of a interface for this stuff,
and it's nice because you can just echo stuff
and this is of us attributes.
I do agree, yes, that's another, another problem to think about.
And maybe adding some limited subset of GPIO tools,
functionality to your busy box is the way.
I had a use case like that back in the day with,
I, I, I, to see,
and I actually added, I, to see tools to busy box
because I, I required it in, in front of us.
So, that may be the way.
Or maybe the debug of us interface.
And you won a viable one.
That's, um, basically, I don't have enough to write now.
I will, I will think about it however.
That may be material for another,
another talk and another conference.
You can always use configFS.
We already have gadgets in configFS, right?
So, if we add another interface for GPIO,
that is configurable for configFS.
Okay, that does the end.
Thank you.