summaryrefslogtreecommitdiff
path: root/arch
AgeCommit message (Collapse)Author
2024-03-14rockchip: rk3328-nanopi-r2: Update defconfigJonas Karlman
Update defconfig for rk3328-nanopi-r2* boards with new defaults. Remove the SPL_DRIVERS_MISC=y option, no misc driver is used in SPL. Add CONFIG_SPL_FIT_SIGNATURE=y to let SPL verify an auto generated hash of FIT images. This help indicate if there is an issue loading any of the images to DRAM or SRAM. Also add LEGACY_IMAGE_FORMAT=y to keep support for scripts. Remove SPL_I2C=y and SPL_PMIC_RK8XX=y, the related i2c and pmic nodes is not included in the SPL fdt. Add CMD_GPIO=y and CMD_REGULATOR=y to add the helpful gpio and regulator commands. Add ROCKCHIP_EFUSE=y and remove NET_RANDOM_ETHADDR=y, ethaddr and eth1addr is set based on cpuid read from eFUSE. Add SPL_DM_SEQ_ALIAS=y option to use alias sequence number in SPL. Add DM_ETH_PHY=y, PHY_GIGE=y, PHY_MOTORCOMM=y, PHY_REALTEK=y and remove &gmac2io to support reset of onboard ethernet PHYs. Also add DM_MDIO=y to ensure device tree props is used by motorcomm PHY driver. Remove REGULATOR_PWM=y, the pwm-regulator compatible is not used. Add DM_REGULATOR_GPIO=y and SPL_DM_REGULATOR_GPIO=y to support the regulator-gpio compatible. Add RNG_ROCKCHIP=y and DM_RNG=y options to support the onboard random generator. Also add missing device tree files to MAINTAINERS file. Signed-off-by: Jonas Karlman <[email protected]> Reviewed-by: Tianling Shen <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2024-03-14rockchip: rk3328: Update default u-boot, spl-boot-order propJonas Karlman
Change to use a common FIT load order, same-as-spl > SD-card > eMMC on RK3328 boards. Only EVB and Radxa ROCK Pi E is affected by this change. Signed-off-by: Jonas Karlman <[email protected]> Reviewed-by: Dragan Simic <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2024-03-13stv0991: Remove stv0991 board and architecture codeTom Rini
This architecture and related board are unmaintained currently and have been for a long time. Remove them. Signed-off-by: Tom Rini <[email protected]>
2024-03-13arm: dts: k3-am64: Move to OF_UPSTREAMAndrew Davis
Enable OF_UPSTREAM for AM64-EVM and SK-AM64 boards. Remove DT files that are now available in dts/upstream. Update the appended files based on version of latest OF_UPSTREAM sync point (v6.7-rc7). Signed-off-by: Andrew Davis <[email protected]>
2024-03-13Merge tag 'mips-fixes-for-v2024.04' of ↵Tom Rini
https://source.denx.de/u-boot/custodians/u-boot-mips - mips: implement __udivdi3 to fix building of SquashFS - mips: fix bug in cache init on MIPS32r2 or later
2024-03-13mips: fix change_k0_cca()Daniel Schwierzeck
The intention of change_k0_cca() is to read the C0.Config register into register $t0, update $t0 with the new cache coherency mode passed in $a0 and write back $t0 to C0.Config. With MIPS32 R2 or later instruction sets, this can be achieved with a single instruction with INS. The source and destination register of the INS instruction is passed as first parameter. In case of change_k0_cca() it is register $t0. But for writing back the updated value to C0.Config, the incorrect $a0 register is used. This is only correct in the MIPS32 R1 code path. Fix the `mtc0` instruction to write back the value of the $t0 register. Fix the MIPS32 R1 code path to also store the updated value in $t0. Reported by user ddqxy138 on Github. https://github.com/u-boot/u-boot/commit/b838586086af3278bcaead3720c7a18813cf4619 Signed-off-by: Daniel Schwierzeck <[email protected]>
2024-03-13mips: implement __udivdi3Linus Walleij
Squashfs wasn't compiling because the lldiv() directives turn into __udivdi3 and we are using private libgcc. After this squashfs compiles for MIPS. Signed-off-by: Linus Walleij <[email protected]> Signed-off-by: Daniel Schwierzeck <[email protected]> Tested-by: Bartel Eerdekens <[email protected]>
2024-03-13arm64: Enable CONFIG_64BIT for static analysisDan Carpenter
In the Makefile there is a line that says this: # the checker needs the correct machine size CHECKFLAGS += $(if $(CONFIG_64BIT),-m64,-m32) Set CONFIG_64BIT for ARM64 so that we pass -m64 to the static checkers instead of -m32. Signed-off-by: Dan Carpenter <[email protected]>
2024-03-13Kconfig: move CONFIG_32/64BIT to arch/KconfigDan Carpenter
These configs are used in multiple places so put them in a shared Kconfig file. Signed-off-by: Dan Carpenter <[email protected]> Reviewed-by: Tom Rini <[email protected]>
2024-03-13arm: mach-k3: fixup whitespace in SPDX License IDsBryan Brattlof
The SPDX ID format usese a single space used after the 'SPDX-License-Identifier:'. Fix all files that use any other white-space character other than a single space. Signed-off-by: Bryan Brattlof <[email protected]>
2024-03-13arm: dts: introduce am62p5 U-Boot dts filesBryan Brattlof
Include the U-Boot device tree files needed to boot the board. Signed-off-by: Bryan Brattlof <[email protected]>
2024-03-13arch: mach-k3: introduce basic files to support the am62px SoC familyBryan Brattlof
Introduce the basic functions and definitions needed to properly initialize TI's am62p family of SoCs Signed-off-by: Bryan Brattlof <[email protected]>
2024-03-13arm: mach-k3: invert logic for split DM firmware configBryan Brattlof
Currently, for the K3 generation of SoCs, there are more SoCs that utilize the split firmware approach than the combined DMSC firmware. Invert the logic to avoid adding more and more SoCs to this list. Reviewed-by: Neha Malcom Francis <[email protected]> Acked-by: Andrew Davis <[email protected]> Signed-off-by: Bryan Brattlof <[email protected]>
2024-03-13arm: mach-k3: am62px: introduce clock and device files for wkup splBryan Brattlof
Include the clock and lpsc tree files needed for the wkup spl to initialize the proper PLLs and power domains to boot the SoC. Reviewed-by: Neha Malcom Francis <[email protected]> Signed-off-by: Bryan Brattlof <[email protected]>
2024-03-13soc: add info to identify the am62p SoC familyBryan Brattlof
Include the part number for TI's am62px family of SoCs so we can properly identify it during boot Reviewed-by: Igor Opaniuk <[email protected]> Reviewed-by: Neha Malcom Francis <[email protected]> Signed-off-by: Bryan Brattlof <[email protected]>
2024-03-13board: at91: sama7g54_curiosity: Add initial board supportMihai Sain
Add initial support for SAMA7G54 Curiosity board. Hardware: SoC: SAMA7G54D2G SiP 1000 MHz DRAM: DDR3 256 MiB PMIC: MCP16502 Debug: UART3 Flash: QSPI NOR 8 MiB, SLC NAND 512 MiB M.2 slot for wireless Mikrobus connectors x 2 SD-Card connectors x 1 USB 2.0 x 3 Signed-off-by: Mihai Sain <[email protected]>
2024-03-13ARM: dts: at91: sama7g54_curiosity: Add initial device tree of the boardMihai Sain
Add initial device tree of the SAMA7G54 Curiosity board. Signed-off-by: Mihai Sain <[email protected]>
2024-03-13ARM: dts: at91: sama7g5: Add flexcom 10 nodeMihai Sain
Add flexcom 10 node for usage on the SAMA7G54 Curiosity board. Signed-off-by: Mihai Sain <[email protected]>
2024-03-13board: rockchip: add Theobroma-Systems RK3588 Jaguar SBCQuentin Schulz
JAGUAR is a Single-Board Computer (SBC) based around the rk3588 SoC and is targeting Autonomous Mobile Robots (AMR). It features: * LPDDR4X (up to 16GB) * 1Gbps Ethernet on RJ45 connector (KSZ9031 or KSZ9131) * PCIe 3.0 4-lane on M.2 M-key connector * PCIe 2.1 1-lane on M.2 E-key * USB 2.0 on M.2 E-key * 2x USB3 OTG type-c ports with DP Alt-Mode * USB2 host port * HDMI output * 2x camera connectors, each exposing: * 2-lane MIPI-CSI * 1v2, 1v8, 2v8 power rails * I2C bus * GPIOs * PPS input * CAN * RS485 UART * FAN connector * SD card slot * eMMC (up to 256GB) * RTC backup battery * Companion microcontroller * ISL1208 RTC emulation * AMC6821 PWM emulation * On/off buzzer control * Secure Element * 80-pin Mezzanine connector for daughterboards: * GPIOs * 1Gbps Ethernet * PCIe 2.1 1-lane * 2x 2-lane MIPI-CSI * ADC channel * I2C bus * PWM * UART * SPI * SDIO * CAN * I2S * 1v8, 3v3, 5v0, dc-in (12-24V) power rails The Device Tree comes from next-20240110 Linux kernel. Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-13rockchip: rk3588: bind MMC controllers in U-Boot proper pre-relocQuentin Schulz
Since commit 9e644284ab81 ("dm: core: Report bootph-pre-ram/sram node as pre-reloc after relocation"), bootph-pre-ram doesn't make U-Boot proper bind the device before relocation. While this is usually not much of an issue, it is when there's a lookup for devices by code running before the relocation. Such is the case of env_init() which calls env_driver_lookup() which calls env_get_location() which is a weak symbol and may call arch_env_get_location() also a weak symbol. Those are two functions that may traverse UCLASS to find some devices (e.g. board/theobroma-systems/common/common.c:arch_env_get_location()). This allows something in the env_init() call stack to be able to use uclasses for SD and eMMC controller on RK3588S/RK3588. This aligns the behavior with what seems to be all SoCs except RK356x family. Additionally, if any other env function (e.g. env_load) were to be used before relocation, this is also required as otherwise it wouldn't be able to find the MMC device(s). Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-13rockchip: include asm/io.h directly in asm/arch-rockchip/hardware.hQuentin Schulz
The different macros use writel which is defined in asm/io.h, so let's include the header so users of hardware.h do not need to include asm/io.h as well. While at it, remove asm/io.h includes wherever asm/arch-rockchip/hardware.h is included already. Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-13rockchip: migrate hardware.h inclusion into appropriate filesQuentin Schulz
hardware.h is only defining macros which are "wrappers" around writel(). writel() is however not available in hardware.h, <asm/io.h> needs to be included. This means in order to use the wrappers in hardware.h, one also needs to include the <asm/io.h> header. However, this cannot be done currently because hardware.h is included in include/configs files, which are implicitly included by every code file by default, which makes the compilation of arch/arm/cpu/armv8/u-boot.lds fail because ALIGN (the ARM assembly directive) got redefined by some of the include files coming from <asm.io.h>. Because nothing in the include/configs file actually use hardware.h, let's remove the inclusion of hardware.h from the include/configs files and explicitly add it wherever it is required. This prepares for the next commit where <asm/io.h> will be included in hardware.h. Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-13rockchip: rk3588: add constants for some register address spacesQuentin Schulz
It's one thing to have the register mapped via a well-defined struct but it's another to be able to make use of it. For that to happen, one needs to cast the physical address memory of the beginning of the register address space with the struct. Since this cannot change, let's hardcode it in the include files so that users do not need to duplicate this line of code in their own implementation. Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-13rockchip: rk3588: disable force_jtag by defaultQuentin Schulz
Rockchip SoCs can automatically switch between jtag and sdmmc based on the following rules: - all the SDMMC pins including SDMMC_DET set as SDMMC function in GRF, - force_jtag bit in GRF is 1, - SDMMC_DET is low (no card detected), Note that the BootROM may mux all SDMMC pins in their SDMMC function or not, depending on the boot medium that were tried. Because SDMMC_DET pin is not guaranteed to be used as an SD card card detect pin, it could be low at boot or even switch at runtime, which would enable the jtag function and render the SD card unusable. This is the case for RK3588 Jaguar for example which has an SD card connector without an SD card card detect signal and has SDMMC_DET connected to ground. Because enabling JTAG at runtime could be a security issue and also to make sure that we have a consistent behavior on all boards by default, let's disable this force_jtag feature. However, let's make it easy to reenable it for debugging purposes by hiding it behind a Kconfig symbol. Note that soc_con[0] is reserved. But considering that it's way more user-friendly to access soc_con1 from the TRM with soc_con[1] than soc_con[0], and that soc_con0 would actually be located at 4 bytes before soc_con1, let's just make soc_con0 part of the soc_con array. Cc: Quentin Schulz <[email protected]> Signed-off-by: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2024-03-13rockchip: transform rockchip_capsule_update_board_setup into a weak function ↵Quentin Schulz
symbol There's only one user of rockchip_capsule_update_board_setup, which is in board.c, and only one board defines it, so instead of having a header only for one function symbol, let's just use a weak symbol instead. Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Reviewed-by: Dragan Simic <[email protected]> Reviewed-by: Peter Robinson <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-13rockchip: merge misc.c into board.cQuentin Schulz
The functions aren't used anywhere else than in board.c, therefore, let's not expose them anymore at all. This merges misc.c and board.c together and removes the functions from the misc.h header file. Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-13rockchip: add weak function symbol called at the beginning of misc_init_rQuentin Schulz
Most Rockchip boards who override misc_init_r do it only to call another function and keep the rest unchanged. Therefore to allow for less duplication, let's just add a weak function symbol that is called inside misc_init_r. Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Reviewed-by: Dragan Simic <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-13rockchip: avoid out-of-bounds when computing cpuidQuentin Schulz
The expected length of the cpuid, as passed with cpuid_length, determines the size of cpuid_str string. Therefore, care should be taken to make sure nothing is accessing data out-of-bounds. Instead of using hardcoded values, derive them from cpuid_length. Cc: Quentin Schulz <[email protected]> Reviewed-by: Kever Yang <[email protected]> Reviewed-by: Dragan Simic <[email protected]> Signed-off-by: Quentin Schulz <[email protected]>
2024-03-12arm64: zynqmp: Describe USB wakeup interruptMichal Simek
Describe usb wakeup interrupt. Signed-off-by: Michal Simek <[email protected]> Link: https://lore.kernel.org/r/d8109a218f70c257e4fc52b5032b7df68fc00786.1709887312.git.michal.simek@amd.com
2024-03-12arm64: zynqmp: Remove additional compatible string for sc-revBMichal Simek
Based on dt schema there is no need to specify flash via additional compatible string and generic are enough. Signed-off-by: Michal Simek <[email protected]> Link: https://lore.kernel.org/r/54e77ad480c5de8703cb5b22408dc3bf72f3f431.1709887280.git.michal.simek@amd.com
2024-03-12arm64: zynqmp: Fix gpio-key DT descriptionMichal Simek
All gpio-key descriptionos with dt-schema. Signed-off-by: Michal Simek <[email protected]> Link: https://lore.kernel.org/r/a67884f4fad98b94198123eef45ffdad511b0dc6.1709887234.git.michal.simek@amd.com
2024-03-12arm64: zynqmp: Add label to pmu fwnodeLukas Funke
ZynqMP CG series devices only have two cpus. In this case the interrupt-affinity property has to adapted, because cpu3 and cpu4 are missing. By adding a label to the pmu fwnode the interrupt-affinity can be adapted in a device specific DT. Signed-off-by: Lukas Funke <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michal Simek <[email protected]>
2024-03-12riscv: dts: jh7110: Enable PLL node in SPLBo Gan
Previously PLL node was missing from SPL dts. This caused BUS_ROOT to stay on OSC clock (24Mhz). As a result, all peripherals have to run at a much lower frequency, and loading from sdcard/emmc is slow. Thus, enabling PLL node in dts to fix this. Signed-off-by: Bo Gan <[email protected]> Reviewed-by: Leo Yu-Chi Liang <[email protected]>
2024-03-12riscv: cpu: improve multi-letter extension detection in supports_extension()Conor Dooley
The first multi-letter extension after the single-letter extensions does not have to be preceded by an underscore, which could cause the parser to mistakenly find a single-letter extension after the start of the multi-letter portion of the string. Three letters precede multi-letter extensions (s, x & z), none of which are valid single-letter extensions. The dt-binding also allows multi-letter extensions starting with h, but no such extension have been frozen or ratified, and the unprivileged spec no longer uses "h" as a prefix for multi-letter hypervisor extensions, having moved to "sh" instead. For that reason, modify the parser to stop at s, x & z to prevent this overrun, ignoring h. Signed-off-by: Conor Dooley <[email protected]> Reviewed-by: Heinrich Schuchardt <[email protected]>
2024-03-12riscv: dts: jh7110: fix indentationLeon M. Busch-George
Signed-off-by: Leon M. Busch-George <[email protected]> Reviewed-by: Leo Yu-Chi Liang <[email protected]>
2024-03-12riscv: sifive: fu740: reduce DDR speed from 1866MT/s to 1600MT/sThomas Perrot
It appears that there is some timing marginality either in the board layout or the SoC that results in occasional data corruption on some boards. We observed this issue on some of the new HiFive Unmatched RevB boards during volume production as well as some of the original HiFive Unmatched boards from 2021 in our possession. This means that there are other boards out there that might have the issue too. We have done some limited testing with DDR4 at 1600MT/s and faulty boards (failing at 1866MT/s) passed. We plan further testing after we procure a temperature chamber. Signed-off-by: Thomas Perrot <[email protected]> Reviewed-by: Leo Yu-Chi Liang <[email protected]>
2024-03-11Merge tag 'v2024.04-rc4' into nextTom Rini
Prepare v2024.04-rc4
2024-03-11arm: dts: imx8mp-beacon-kit: Resync DTS with Linux 6.8Adam Ford
The device tree has evolved over time, so re-sync. This also partial reverts one change on the PCIe, because U-Boot doesn't have a proper driver. However, since the clock is configured to generate a 100MHz reference clock by default, a proper driver isn't really necessary. Signed-off-by: Adam Ford <[email protected]> Acked-by: Peng Fan <[email protected]>
2024-03-07board: phytec: am64x: Add PHYTEC phyCORE-AM64x SoMWadim Egorov
Add support for PHYTEC phyCORE-AM64x SoM. Supported features: - 2GB DDR4 RAM - eMMC Flash - external uSD - OSPI NOR Flash - debug UART Product page SoM: https://www.phytec.com/product/phycore-am64x Device trees were taken from Linux v6.8-rc2. Signed-off-by: Wadim Egorov <[email protected]> Reviewed-by: Dhruva Gole <[email protected]>
2024-03-06Merge patch series "Move DRAM address of ATF"Tom Rini
Andrew Davis <[email protected]> says: Explanation for this series is mostly in [4/6]. First 3 patches should be safe to take independent of the last 3.
2024-03-06arm: mach-k3: Move DRAM address of ATF for AM62/AM62aAndrew Davis
The current address of TF-A in DRAM is just below the 512MB address line. This means if the DRAM in a system is 512MB then TF-A is right at the end of memory which is often reused, for instance U-Boot relocates itself here. If a system has less than 512MB then that system wouldn't work at all as TF-A would fail to load. To avoid the issues above, move TF-A to the start of DRAM, which doesn't change from system to system. As TF-A is position independent, this has no dependency on TF-A. We also fixup DT as needed when TF-A address is moved, so this change also has no dependency on Linux and is fully forward/backward compatible. Signed-off-by: Andrew Davis <[email protected]> Acked-by: Bryan Brattlof <[email protected]>
2024-03-06arm: mach-k3: am62a: Fixup TF-A/OP-TEE reserved-memory node in FDTAndrew Davis
The address we load TFA and OP-TEE to is configurable by CONFIG_K3_{ATF,OPTEE}_LOAD_ADDR, but the DT nodes reserving this memory are static. Fix that by updating this node when the loaded address does not match the address in DT. Signed-off-by: Andrew Davis <[email protected]> Acked-by: Bryan Brattlof <[email protected]>
2024-03-06arm: mach-k3: am62: Fixup TF-A/OP-TEE reserved-memory node in FDTAndrew Davis
The address we load TF-A and OP-TEE to is configurable by Kconfig CONFIG_K3_{ATF,OPTEE}_LOAD_ADDR, but the DT nodes reserving this memory are often statically defined. As these binaries are dynamically loadable, and in the case of OP-TEE may not even be loaded at all, hard-coding these addresses is not a hardware description, but rather a configuration. If the address that U-Boot loaded TF-A or OP-TEE does not match the address in hard-coded in DT, then fix that node address. This also handles the case when no reserved memory for these is provided by DT, which is more correct as explained above. Add this fixup function, and enable it for AM62. Signed-off-by: Andrew Davis <[email protected]> Acked-by: Bryan Brattlof <[email protected]> Reviewed-by: Neha Malcom Francis <[email protected]>
2024-03-06arm: mach-k3: am62: Enable OF_SYSTEM_SETUP for all boardsAndrew Davis
The fixups provided by ft_system_setup() are applicable for all AM62 based boards. Select this at the target selection level for all AM62 boards and remove it from any specific defconfig. Signed-off-by: Andrew Davis <[email protected]>
2024-03-06arm: mach-k3: Add config option for setting OP-TEE addressAndrew Davis
Much like we have for ATF, OP-TEE has a standard address that we load it too and run it from. Add a Kconfig item for this to remove some hard-coding and allow this address to be more easily changed. Signed-off-by: Andrew Davis <[email protected]> Acked-by: Bryan Brattlof <[email protected]> Reviewed-by: Neha Malcom Francis <[email protected]>
2024-03-06arm: mach-k3: Add default ATF location for AM62/AM62aAndrew Davis
There is a default ATF load address that is used for devices that have ATF running in SRAM. For AM62 and AM62a, ATF runs from DRAM. Instead of having to override the address in every defconfig, make add a default for these ATF in DRAM devices. Signed-off-by: Andrew Davis <[email protected]> Acked-by: Bryan Brattlof <[email protected]> Reviewed-by: Neha Malcom Francis <[email protected]>
2024-03-05arm: dts: k3-binman: Make optee optional as requirementMichael Trimarchi
Allow boards that use ti_spl_template to not use optee part in configuration. Vendor can have module with 256 Mb of memory and they try to optimize the available memory just using the essential components. This change allow to remove tee from configuration without binman fail. configurations { default = "conf-0"; conf-0 { description = "k3-am62_ccm_m3"; firmware = "atf"; loadables = "dm", "spl"; fdt = "fdt-0"; }; }; Signed-off-by: Michael Trimarchi <[email protected]>
2024-03-05Merge patch series "Enable OSPI on j721e"Tom Rini
Jonathan Humphreys <[email protected]> says: This series enables OSPI storage and boot.
2024-03-05arm: dts: k3-j721e-sk: Remove OSPI phypattern partitionJonathan Humphreys
The phy calibration pattern partition isn't needed as the Cadence driver isn't calibrating the phys. Signed-off-by: Jonathan Humphreys <[email protected]> Fixes: 58d61fb5a77e ("arm: dts: k3-j721e-sk: Add initial A72 specific dts support")
2024-03-05arm: mach-k3: j721e: Enable OSPI bootJonathan Humphreys
Add boot ROM XSPI bootmode, and set to BOOT_DEVICE_SPI if detected. Signed-off-by: Jonathan Humphreys <[email protected]> Reviewed-by: Udit Kumar <[email protected]>