Upstream Pinephone Pro Patches!

This is a noob-friendly guide on how to mainline patches to mainline linux for the pinephone pro (short form: ppp). This should help you get your first patch into the Linux kernel! Any questions? Ask away!

What does “mainlining” mean exactly? An Android or Linux device usually has some drivers to make peripherals (eg. touchscreen, battery, etc.) work. The problem is that these devices usually run an outdated Linux kernel. That means you are constantly rebasing and testing changes on top of mainline Linux. Anything breaks, and it’s up to you to fix it. It’s quite exhausting.

Instead we want to push these changes so that we can get the community to help maintain it for us. Any breakages that happen after our commit, and all we would have to do is report it upstream (providing important details like when the first problem started happened, etc.) and let whoever introduced the breaking bug fix it for us. It’s quite nice as we can start focusing on other things!

Luckily for us, the ppp is running a close to mainline Linux kernel. If you look at the commits, there are only a couple commits (114 commits!) on top of 6.13. Let’s change that to 0!

This guide could probably be generalized for other devices, but for now let’s focus on the Pinephone Pro. Let’s break this down into distinct steps: Build, Test, Upstream, Iterate.

Build

Let’s setup your environment first. Each distro is unique but the requirements to build the linux kernel is the same. Essentially you will need these packages listed in makedepends installed on your machine. Install these via your package manager.

Next, let’s get the Linux kernel tree! Note: This is a clone of the linux kernel tree. GitHub is not where Linux kernel development is done

  git clone https://github.com/torvalds/linux.git

Now we also want to get the ppp’s kernel as well. To make the clone faster this time, we want to cd into the cloned mainline tree we just got, and then we want to fetch the ppp tree in the mainline tree. They share commits so it’ll be a faster clone this time.

  cd linux
  git remote add ppp https://gitlab.com/pine64-org/linux.git
  git fetch ppp
  git switch linux-pinephonepro-6.13.y

Nice! We got our environment setup now. Let’s try building the kernel!

There are many mainline building tools out there. There is pmbootstrap (the one we are using today), mkosi, T2 SDE, Yocto, Buildroot, and you can even just do a simple Linux+busybox initramfs if you’d like! Use whatever tool you’d like (although you probably aren’t reading this if you know of another tool). pmbootstrap is good enough for our purposes and one of the easier setups to run mainline linux on arm devices.

Let’s start with the ppp’s close-to-mainline kernel. We want to make sure that our setup actually works before we actually start pushing commits upstream.

Building and Flashing Steps:

  # Assuming you somehow moved away from the linux directory you cloned. Make sure you are on the linux-pinephonepro-6.13.y branch!
  cd linux && \
  # I zap because chroot frequently gets corrupted on my machine... you don't need to do this if it's not required.
  pmbootstrap -y zap -a && \
  # Let's copy the Linux configuration that pmOS uses into our tree
  wget https://gitlab.postmarketos.org/postmarketOS/pmaports/-/raw/master/device/community/linux-pine64-pinephonepro/config-pine64-pinephonepro.aarch64 -O arch/arm64/configs/ppp_defconfig
  # We build using clang and output into .output. We build for arm64 with all the cores on our system. We configure Linux with ppp_defconfig, add/remove any configs we want, then build.
  make LLVM=1 O=.output ARCH=arm64 -j$(nproc) ppp_defconfig menuconfig all && \
  # Useful for our editors as if we need to edit anything in the Linux tree, there will be type hints available
  ./scripts/clang-tools/gen_compile_commands.py -d .output/ && \
  # Once our kernel build successfully, we tell pmbootstrap to use it
  pmbootstrap build --envkernel linux-pine64-pinephonepro && \
  # We force a ppp device build to use our new kernel
  pmbootstrap build --force device-pine64-pinephonepro && \
  # We walk through pmbootstrap install
  pmbootstrap install && \
  # We install the new package via https://wiki.postmarketos.org/wiki/PINE64_PinePhone_Pro_(pine64-pinephonepro)#Internal_storage_(eMMC)
  pmbootstrap install --fde --sdcard=
  # Once you have a base image installed, you can use this instead to update the kernel on an existing system
  # pmbootstrap sideload linux-pine64-pinephonepro

If this works, great! Go back to your computer and do:

  # We use v6.15 here, but this should be the latest Linux stable release. The reason we do stable and not tip is so that maintainers can easily apply it to their tree
  git checkout v6.15
  git switch -c ppp_mainline
  # Now doing git log should give you Linux stable release by Torvalds!
  git log

Unfortunately, there isn’t really an easy step-by-step guide on how to apply downstream patches. What you want to do is see what patch in downstream you would like to mainline, cherry-pick that into the mainline tree and build it according to Building and Flashing Steps referenced above. There might be other patches that depend on the patch you would like to mainline. Use your best judgement!

Test

Once you flash the ppp with the new kernel, can you do the thing that the commit said you could now do? Or was it already possible in mainline linux? If it’s new and it works, congrats! Let’s try to upstream it.

Upstream

Now that we have a working patch, let’s upstream it. We’ll use these 2 nice guides on how to upstream patches. I suggest you give these a watch:

Here’s the notes from the videos for quick reference:

  # First time
  b4 prep -n <label> -f <tag>
  
  # Follow up (Make changes first)
  b4 trailers -u
  b4 prep --edit-cover # Update what you changed
  rm -rf /tmp/tosend && b4 send -o /tmp/tosend && hx /tmp/tosend
  ./scripts/checkpatch.pl /tmp/tosend/*
  b4 prep --compare-to v#
  b4 prep --auto-to-cc
  b4 prep --check
  b4 send --reflect
  b4 send

One note: DO NOT rewrite the original author’s signed off by or any other tags. If there is none, add a signed off by with the original author and put your signed off by afterwards. You want to give credit where credit’s due. No exceptions.

Iterate

No doubt you will get feedback on this patch. That’s okay! Ask questions, and show interest that you want to get this patch merged in.

Once some people have put their reviewed by tags and there is no more feedback, the series will undoubtably go quiet. Don’t worry, they aren’t ignoring you, that is just how the patches are accepted. Once a new kernel is released (in this case 6.17, since 6.16-rc1 is already out), that is when your patch will go in. If you don’t get an ack email around this time, make sure to resend your patch or email within the previous patch to ask what happened. Communication is important!

Once Your Patch is in

Congrats! After a couple months long process, you have finally gotten your patch accepted into mainline Linux. I hope you continue your mainlining journey! There are still many devices running close to mainline :slight_smile:

The goal of this guide is to show kernel veterns that helping kernel newbies is well worth the effort. You can get tedious tasks off your plate, and kernel newbies can have an easy entry into kernel hacking. Hopefully others write similar guides to their devices. Feel free to steal this :D.

A Note about PINE64

Unfortunately, I’m of the opinion at this point that PINE64 is not worth buying hardware from. They have made millions from selling hardware and (I believe) have not adequately given back to the community.

It comes as no surprise to me that a company that relies on slave labor to make the hardware for their phone, also expects slave labor for the software of their phone as well. There was a lot riding on this experimental project (Linus Tech Tips was even excited about this project!) yet years later the ppp is barely useable as a mainline Linux smartphone (battery, charging, camera, maybe more still dysfunctional?).

Maybe Fairphone or some other company can steal the spotlight from PINE64 and truly invest into individual developers committed to making mobile Linux a reality. Sort of how Valve is revolutionizing Linux gaming. For that, take a book from Valve’s playbook and invest back into the community that believed in you in the first place.

Why am I wanting to mainline this phone now? Because it’s been a couple years that PINE64 can’t really claim my or other progress as their own. If they do, they’ll look a bit crazy since the progress was glacial slow. The reason I want to mainline is that I just want a nice Linux mainline phone.

Comments, Questions, Concerns?

Ask away! I will update this post if others have insightful comments/questions. We’re here to help each other (hopefully :P)!

Figured it might be better to track which commits people are working on getting upstream, so claim the one you are working on here so others don’t! I’ll update this post with interests/LKML patches so please keep me updated!

c16b0c7e3b99 arm64: dts: rk3399-pinephone-pro: Remove modem node
68a24f19a9bf misc: ppkb-manager: Disable debug mode
b4a3a6af07bf misc: ppkb-manager: Show read/write error codes
add62a308c72 misc: ppkb-manager: Disable ppkb-manager by default (can be enabled at runtime)
452d17bf0725 misc: ppkb-manager: Remove BLOCKED flag
19d56f927216 misc: ppkb-manager: Pinephone Keyboard power manager
a7c5a58a9cd4 input: pinephone-keyboard: Wait a bit after enabling vbus
a4b174e84c64 input: pinephone-keyboard: Don't print error when the keyboard is not connected
5e78ee9b42de input: pinephone-keyboard: Allow to disable Fn layer processing
50858f525419 input: pinephone-keyboard: Allow disabling the keyboard input
25b4de2ea606 power: supply: ip5xxx: Add support for POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN
4ef4e53c4ab3 power: supply: ip5xxx: Add support for POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR
d9c1576575ee power: supply: ip5xxx: Add ip5xxx-usb supply
fc1d99353e20 power: supply: ip5xxx: Add boost status property
52c5abdd9299 power: supply: ip5xxx: Modify initial configuration
165ed5263f91 power: supply: ip5xxx: Report remaining battery capacity
31075b5f0897 arm64: dts: rk3399-pinephone-pro: Add wcam link-frequesncies
cec92256d9a8 arm64: dts: rk3399-pinephone-pro: Assign power supplies to audio codec
3abba795c3c9 arm64: dts: rk3399-pinephone-pro: Improve SPI access speed
034c1a2bdbb8 arm64: dts: rk3399-pinephone-pro: Pre-configure DMC
5fa4e1b23355 arm64: dts: rk3399-pinephone-pro: Fix voltage threshold for volume down key
3cd557d45fcd arm64: dts: rk3399-pinephone-pro: Switch LED backlight PWM from 1kHz to 20kHz
e78a2a5853b4 arm64: dts: rk3399-pinephone-pro: Add pinephone keyboard support
f6b7439bb8f5 arm64: dts: rk3399-pinephone-pro: Enable POGO pins I2C
dee62cbdf59b arm64: dts: rk3399-pinephone-pro: Add mount-matrix for magnetometer
43cf07100d99 arm64: dts: rk3399-pinephone-pro: Add magnetometer sensor support
d58af81206ab arm64: dts: rk3399-pinephone-pro: Add accelerometer sensor support
b9db169eadb1 arm64: dts: rk3399-pinephone-pro: Add I2C supply to stk3311
620d9de1550d arm64: dts: rk3399-pinephone-pro: Add light/proximity sensor support
aece7c1ec8a6 arm64: dts: rk3399-pinephone-pro: Change modem codec samplerate to 16kHz
99699e4b2b5f arm64: dts: rk3399-pinephone-pro: Add modem support
3e9b835114be arm64: dts: rk3399-pinephone-pro: World cam doesn't have powerdown input
e3a9a8c0acaf arm64: dts: rk3399-pinephone-pro: Add camera orientations
12c7d18d7e30 arm64: dts: rk3399-pinephone-pro: Add correct camera rotation values
8d37acabe5b5 arm64: dts: rk3399-pinephone-pro: Add camera support
16295829fc96 arm64: dts: rk3399-pinephone-pro: Add Type-C port support
00b1fc49eefa arm64: dts: rk3399-pinephone-pro: Add sound support
58ca45c47f7c arm64: dts: rk3399-pinephone-pro: Add 5V power supply
a69a7e040eb8 arm64: dts: rk3399-pinephone-pro: Add BSP battery driver support
06b83ea3d0f7 arm64: dts: rk3399-pinephone-pro: Add internal display support
af6a5e466546 arm64: dts: rk3399: Add reboot mode driver
9e2f4be99653 arm64: dts: rk3399: Disable debug nodes
08ae426d82ec clk: rk3399: Export SCLK_CIF_OUT_SRC to device tree
168b38b8f7f2 mtd: spi-nor: gigadevice: add support for gd25lq128e
5cf1d9206c82 rt5640: DMIC debug
234805848dd4 clk: rockchip: rk3399: Don't allow to reparent dclk_vop0 to frac clock
e574156d8afc drm: panel: hs8394: Instrument the panel driver's callbacks
f8b678685725 drm: panel: hx8394: Add mode/init sequence update via firmware load
afc2c19f759d drm: bridge: dw-mipi-dsi: Tracing
91bf248b2366 drm: rockchip: dw-mipi-dsi: Fix hsclk calculation for non-burst video modes
df5019adcd6c sdhci: arasan: Add runtime PM support
8c6544ab4543 usb: typec: tcpm: Improve logs
c736b20f34e5 usb: typec: tcpm: Fix PD devices/capabilities registration
80ab88033ea8 usb: typec: tcpm: Unregister altmodes before registering new ones
413838a826f4 usb: typec: altmodes: displayport: Respect DP_CAP_RECEPTACLE bit
0ce50eca8ad3 Revert "usb: typec: tcpm: unregister existing source caps before re-registration"
ccc0d36395de usb: typec: typec-extcon: Allow to force reset on each mux change
c35f9357ddcb usb: typec: typec-extcon: Enable debugging for now
4e1bc1482141 usb: typec: typec-extcon: Add typec -> extcon bridge driver
cf46f6325a56 usb: dwc3: Extend reset quirk support to include role-switch
d96c9c4c6d8f usb: dwc3: Add support for snps,usb3-phy-reset-quirk
34da88341b13 usb: dwc3: Track the power state of usb3_generic_phy
4c60863377f5 phy: rockchip-inno-usb2: More robust charger detection extcon updates
882dd0c27aae phy: phy-rockchip-inno-usb2: Decrease delay between port init and charger detection
0fa888e4a378 drm: rockchip: cdn-dp: Disable CDN DP on disconnect
434f54303e2c ASoC: codecs: rt5640: Add support for power supplies
dafac498abd6 ASoC: codecs: rt5640: Keep the codec enabled when idle
e345e3f77f6d ASoC: codecs: rt5640: Allow to control single-ended/differential mode
8ff81f6074ca ASoC: codecs: rt5640: Add input mixer input volume controls
3694946f0888 ASoC: codecs: rt5640: Resolve failure to set DMIC clock after playback
d43a186fc2ed ASoC: codecs: rt5640: Fix hpout restore when lout is enabled
4f03032930e5 ASoC: codecs: rt5640: Fix output mixer input channel list
281c93970356 power: supply: rk818-battery: Don't reset dsoc to 0 on rk818_vb_low_irq
b3e9c1092e36 power: supply: rk818-charger: Add support for POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN
d143b6edeb04 power: supply: rk818-battery: Don't auto-poweroff the PMIC on low battery
2cdc58bb4473 power: supply: rk818-charger: Delay applying input current limit until first BC detection finishes
3d21bfe93a7a power: supply: rk818-battery: Speed up battery current readout
b00426db9d9f power: supply: rk818-charger: Unify rk818-charger and rk818-battery
20045b07a9fc power: supply: rk818-battery: Drop dependency on framebuffer
a2d4e7e15db4 power: supply: rk818-battery: Report charging status based on charging current
6106377defd8 power: supply: rk818-charger: Change charger type to MAINS
65c71af9932b power: supply: rk818-charger: Implement charger driver for RK818 PMIC
ee23d6486f4c power: supply: rk818-battery: Use a more propper compatible string
b65b352f4aab power: supply: rk818-battery: Add battery driver for RK818
a63a3d19df7f power: rk818: Configure `rk808-clkout2` function
63b73fd967bf media: imx258: Drop interface speed to 1224 mbps
e87f553c6d2a media: imx258: Add reset gpio
6ef684495585 media: i2c: imx258: Add debug register access
12f71d65da60 media: i2c: imx258: Add i2c supply
2196f54e1fdb usb: typec: fusb302: Clear interrupts before we start toggling
aa145be4b915 usb: typec: fusb302: Fix register definitions
d713b14e4dc4 usb: typec: fusb302: Add OF extcon support
3ad78184f2a9 usb: typec: fusb302: Update VBUS state even if VBUS interrupt is not triggered
816c138cfb4c usb: typec: fusb302: More useful of logging status on interrupt
e01e77ba9ad5 usb: typec: fusb302: Retry reading of CC pins status if activity is detected
4efe1c42cc05 usb: typec: fusb302: Extend debugging interface with driver state dumps
11dd5745c6a4 usb: typec: fusb302: Set the current before enabling pullups
d34aeeaf1ce5 usb: typec: fusb302: Slightly increase wait time for BC1.2 result
d7b37d05ea32 iio: stk3310: Fix regulator disable/enable order
8eba3d973e6c iio: light: stk3310: Add support for I2C regulator
d335ee027816 iio: light: stk3310: Implement vdd supply and power it off during suspend
35c705e39e94 input: touchscreen: goodix: Respect IRQ flags from DT when asked to
20f5d633c349 Input: goodix: Try to keep regulator enable/disable balanced
b86e0e5183fc Input: goodix: Add option to power off the controller during suspend
5b6bbff7d1c5 Input: goodix: Add config debugfs file
de29ddafa4d8 arm64: dts: rockchip: rk3399-s: Add DMC table
d3c673b8e87d arm64: dts: rk3399: Add dmc_opp_table
fd28685f6adf drm: rockchip: dw-mipi-dsi-rockchip: Fix ISP1 PHY initialization
454fc232f2f9 usb: serial: option: add 'reset_resume' callback for WWAN devices
03201cd5cb94 mmc: dw-mmc-rockchip: fix sdmmc after soft reboot
ea88da1ae23e usb: gadget: Fix dangling pointer in netdev private data
db0430ed29f0 drm: rockchip: Fix panic on reboot when DRM device fails to bind
5e03e395922f ASoC: rockchip: Fix doubling of playback speed after system sleep
ffd294d346d1 Linux 6.13

@Adrian i cant seem to edit the posts above anymore. is it possible to change that so i can edit it indefinitely?

got some useful feedback and i wanted to change the note about pine64 to sound a little less harsher

edit: i can edit this new one but not older posts it seems