Skip to content

Commit

Permalink
Merge pull request #1136 from balena-os/mtoman/cm4-fwgpio
Browse files Browse the repository at this point in the history
initrdscripts: Restore the state of Pi4/CM4 firmware GPIOs after kexec
  • Loading branch information
flowzone-app[bot] authored Jun 19, 2024
2 parents c5331e8 + 7e4cfb9 commit a931dc7
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PACKAGE_INSTALL:append:raspberrypi4-64 = " initramfs-module-kexec-pi4-fwgpio"
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
PACKAGE_INSTALL:remove:revpi = "initramfs-module-migrate"

PACKAGE_INSTALL:append:raspberrypicm4-ioboard-sb = " initramfs-module-kexec-pi4-fwgpio"
IMAGE_ROOTFS_MAXSIZE:raspberrypicm4-ioboard-sb = "51200"
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/bin/sh

# shellcheck disable=SC1091
. /usr/libexec/os-helpers-logging

kexec_pi4_fwgpio_enabled() {
if [ "$bootparam_balena_stage2" = "true" ]; then
return 0
fi

if [ -n "$bootparam_balena_pi4_fwgpio" ]; then
return 0
fi

return 1
}

kexec_pi4_fwgpio_run() {
# Find the wifi/bt device labelled "mmcnr" in the device tree
WIFI_DT_NODE="mmcnr"
WIFI_SYSFS_PATH="$(find /sys/bus/platform/devices -name "*.${WIFI_DT_NODE}")"

# Exactly one device should match, but let's be defensive
if [ "$(echo "${WIFI_SYSFS_PATH}" | wc -l)" -gt 1 ]; then
warn "Multiple '${WIFI_DT_NODE}' devices found, will use the first one"
WIFI_SYSFS_PATH="$(echo "${WIFI_SYSFS_PATH}" | head -n 1)"
fi

# readlink here, because the driver unbinds as we manipulate the GPIOs
WIFI_DRIVER_DIR="$(readlink -f "${WIFI_SYSFS_PATH}/driver")"
WIFI_DEV="$(basename "${WIFI_SYSFS_PATH}")"

GPIO_SYSFS_DIR="/sys/class/gpio"

FW_GPIO_BASE="504"
BT_ON="0"
WL_ON="1"

NEED_RESET="0"
CURRENT_STATE="0"
for PIN in "${BT_ON}" "${WL_ON}"; do
GPIO=$["${FW_GPIO_BASE}" + "${PIN}"]
echo "${GPIO}" > "${GPIO_SYSFS_DIR}/export"
PIN_VALUE="$(cat "${GPIO_SYSFS_DIR}/gpio${GPIO}/value")"

if [ "$bootparam_balena_stage2" = "true" ]; then
CURRENT_STATE=$["${CURRENT_STATE}" | ("${PIN_VALUE}" << "${PIN}")]
elif [ -n "$bootparam_balena_pi4_fwgpio" ]; then
NEW_VALUE=$[("$bootparam_balena_pi4_fwgpio" >> "${PIN}") & 1]
echo "${NEW_VALUE}" > "${GPIO_SYSFS_DIR}/gpio${GPIO}/value"
if [ "${PIN_VALUE}" != "${NEW_VALUE}" ]; then
NEED_RESET="1"
fi
fi
echo "${GPIO}" > "${GPIO_SYSFS_DIR}/unexport"
done
if [ "${NEED_RESET}" = "1" ]; then
echo -n "${WIFI_DEV}" > "${WIFI_DRIVER_DIR}/unbind"
echo -n "${WIFI_DEV}" > "${WIFI_DRIVER_DIR}/bind"
fi
if [ "$bootparam_balena_stage2" = "true" ]; then
export KEXEC_EXTRA_ARGS="${KEXEC_EXTRA_ARGS} balena_pi4_fwgpio=${CURRENT_STATE}"
fi
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

SRC_URI:append = " \
file://cryptsetup-rpi \
file://kexec_pi4_fwgpio \
"

PACKAGES:append = " initramfs-module-kexec-pi4-fwgpio"
SUMMARY:initramfs-module-kexec-pi4-fwgpio = "Hook necessary to persist the value of Pi4/CM4 firmware GPIOs after kexec"
RDEPENDS:initramfs-module-kexec-pi4-fwgpio = "initramfs-module-kexec"
FILES:initramfs-module-kexec-pi4-fwgpio = "/init.d/73-kexec_pi4_fwgpio"

PACKAGES:remove:revpi = "initramfs-module-migrate"
do_install:append:revpi() {
rm -f ${D}/init.d/92-migrate
}

do_install:append() {
install -d ${D}/init.d

install -m 0755 ${WORKDIR}/cryptsetup-rpi ${D}/init.d/72-cryptsetup
sed -i -e "s/@@BALENA_NONENC_BOOT_LABEL@@/${BALENA_NONENC_BOOT_LABEL}/g" ${D}/init.d/72-cryptsetup

install -m 0755 ${WORKDIR}/kexec_pi4_fwgpio ${D}/init.d/73-kexec_pi4_fwgpio
}

RDEPENDS:initramfs-module-cryptsetup:append = " os-helpers-otp gnupg"

0 comments on commit a931dc7

Please sign in to comment.