Adding a pps-gpio device to the Devicetree

I’m going to be connecting a signal to one of the GPIOs on the control header (probably GPIO A), with the intent of using it as a PPS input for the NTP server running on the box.

In Linux this means that the pps-gpio kernel module will be setting up the GPIO and its associated IRQ, then when the interrupts arrive reporting a PPS ‘event’ to applications which are listening. Unfortunately the pps-gpio module in the mainline kernel only understands Devicetree devices… when I did this using a Raspberry Pi, I was able to use their ‘dt-overlay’ method to add a device during boot to the existing DTB (in memory) which specified a GPIO pin to be used for PPS.

Since the ten64 system doesn’t offer a similar thing, I’ve got two choices: build a custom DTB with the necessary pps-cpio ‘compatible’ entry in it, or use one of the forked/hacked versions of pps-gpio which allow the GPIO/IRQ to be specified as module parameters.

I’d prefer to stick with the normal kernel driver if possible, but that leaves me wondering how difficult it would be for me to use the firmware-builder repo to build my own DTB. The additions necessary are fairly easy to make once I know the GPIO->IRQ mapping.

Is this a bad idea, to use a customized DTB?

Well based on this version of the driver, it appears that GPIO->IRQ mapping is dynamic, so that’s even better… I just need to add a DTB entry for the GPIO number I’ve selected.

And finally… this idea won’t work, as the Debian kernels don’t include the pps-gpio module anyway. Since I have to build a module using DKMS, I might as well use the one that isn’t dependent on Devicetree!

In case you end up having to revisit the DT version again:

At the moment our firmware doesn’t have DT overlay functions, but we intend to implement in the next major firmware update.
The firmware update has been delayed for a while but we intend to do some intensive work on it within the next few weeks.

Not very difficult, but as a DTB needs to be built from a Linux kernel tree (to access the constants/defines etc.), the build-dtb.sh does pull down a full kernel tree.

As a quicker method, you can decompile the device tree in the recovery firmware, edit it and recompile.
The downside is that the decompiled dts is not as “friendly” as the original (e.g you will need to substitute any kernel keywords/constants with their actual values)

# Decompile the DTB from flash (must be done from recovery or OpenWrt running from flash)
dtc -I dtb -O dts -o devicetree.dts < /dev/mtd6
# edit the dts
vi devicetree.dts
# recompile (there will be many formatting warnings, these can be ignored)
dtc -I dts -O dtb -o devicetree-edited.dtb < devicetree.dts
# write
mtd erase devicetree && mtd write devicetree-edited.dtb devicetree

If you make a mistake, the recovery environment runs from it’s own devicetree copy so you will be able to get back in and fix the issue.
If you need the original version, click the “browse” link under “Firmware builds” on archive.traverse.com.au and you will be able to download the original DTB blob by itself.

Note that the “new” firmware release (that will do DT-overlay) is likely to change where the DTB is sourced from, when that happens I’ll edit this post.