For example look at typical audio codec drivers. They barely have any procedural code (and when they do it's just some form of register value mapping anyway), locking/concurency and almost all resource management is handled at the higher level and the driver is not exposed to it.
Another kind of a driver that features a very limited dependency on Linux interfaces is a SoC clock/reset driver. And clock drivers are even more boring in this aspect. Code vs data ratio is probably < 0.1 in many of those.
I guess some drivers that do more complicated stuff, and deal with concurrency issues or more complicated resource management may benefit, but they'll likely need to touch much larger API surface, too.
And I dunno, even the sample driver in the patchset has things like this:
let mut data = kernel::new_device_data!(
gpio::RegistrationWithIrqChip::new(),
PL061Resources {
// SAFETY: This device doesn't support DMA.
base: unsafe { IoMem::try_new(res)? },
parent_irq: irq,
},
// SAFETY: We call `spinlock_init` below.
unsafe { SpinLock::new(PL061Data::default()) },
"PL061::Registrations"
)?;
// SAFETY: General part of the data is pinned when `data` is.
let gen = unsafe { data.as_mut().map_unchecked_mut(|d| &mut **d) };
kernel::spinlock_init!(gen, "PL061::General");
let data = Ref::<DeviceData>::from(data);
It's barely readable. I don't know what type `data` is, what `gen` is or how it's different from `data`. Variable names don't really help. `data.as_mut().map_unchecked_mut(|d| &mut *d)` also looks like some kind of WTF to the uninitiated, that is somehow retrieving some 'general part of data' whatever that is.When I look at the kernel's spinlock type https://elixir.bootlin.com/linux/latest/source/include/linux... that doesn't really help me determine why whatever this `gen` [variable?] is needs to be passed to `spinlock_init`.
And what's with the two `let data`. Are they the same type or is the type now different and the first data variable now hidden? Because it looks like second `let data` gets somehow transformed from the first `data` into something else. So now we have two identically named `data` variables with different types in the same function?
Wasn't this supposed to be some simpler language to draw more people to the kernel development? At least with C each variable has a type that's quickly identifiable.
I guess after 15 minutes I see what this is trying to do. It passes some newly created spinlock object to `new_device_data` function and then calls `spinlock_init` on some part of the data returned from `new_device_data` that needs to be extracted from it via some really obtuse transformation, just to initialize the spinlock later instead of directly in `SpinLock::new` for some obscure reason, using two unsafe {} blocks in the process. But oh my god, if this kind of obfuscation is going to be the new standard for the kernel,... At least C is the devil I know. :)