Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e88338e
arm64: configs: Enable CONFIG_SUSPEND
PineappleBeech Jul 21, 2026
f06b1e5
watchdog: bcm2835: Stop watchdog during suspend/resume
PineappleBeech Jul 21, 2026
b07e653
arm64: dts: broadcom: bcm2712: Power off wireless during suspend/resume
PineappleBeech Jul 21, 2026
bd60a51
ACPI: PCI: bcm2712: Set acpi_storage_d3 to true on bcm2712
PineappleBeech Jul 23, 2026
9b38702
iommu: bcm2712-iommu: Add suspend/resume support
PineappleBeech Aug 12, 2026
964750b
drm/vc4: hdmi: Add suspend/resume support
PineappleBeech Aug 12, 2026
3a8d259
drm/vc4: Add suspend/resume support
PineappleBeech Aug 12, 2026
50238c7
drm/vc4: hvs: Add suspend/resume support
PineappleBeech Aug 12, 2026
0981b46
gpio-brcmstb: Enable hibernation support
PineappleBeech Aug 14, 2026
6b593a7
bcm2385: mailbox: Add resumer hander for S3 wakeup on Pi5
timg236 Aug 17, 2026
b7e14c2
arm64: configs: Enable PM Watchdog and Hibernation for testing
PineappleBeech Aug 17, 2026
0e9b665
pinctrl: pinctrl-brcmstb: Save pin mux and pad during suspend
PineappleBeech Aug 17, 2026
a8b7247
serial: amba-pl011: Add start_rx to re-enable interrupts
PineappleBeech Aug 18, 2026
d627f4f
drm/vc4: hdmi: Ignore the hsm clock on resume
PineappleBeech Aug 18, 2026
e2fe239
irqchip: bcm2712-mip: Restore registers after suspend
PineappleBeech Aug 18, 2026
33b71af
mailbox: rp1: check received event bits more carefully
P33M Aug 19, 2026
35fcd28
mmc: sdhci-brcmstb: Reconfigure on resume
PineappleBeech Aug 19, 2026
f4de196
media: pisp_be: Add suspend/resume support
PineappleBeech Aug 21, 2026
97ad88a
drm/rp1: dsi: Add suspend/resume support
PineappleBeech Aug 24, 2026
5cc829a
bluetooth: hci_bcm: Add support for powering off the device in suspend
PineappleBeech Aug 25, 2026
3a7cf14
arm64: dts: broadcom: bcm2712: Power off bluetooth in suspend
PineappleBeech Aug 25, 2026
70e8871
arm64: dts: bcm2712: Add a regulator for pcie 3v3
PineappleBeech Aug 25, 2026
f019f0c
drivers: rtc-rpi: Clear a pending alarm on resume and when setting an…
PineappleBeech Aug 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ properties:
if the device's initial baud rate in normal mode is not supported by the
host or if the device requires autobaud mode startup before loading FW.

brcm,power-off-in-suspend:
type: boolean
description:
Set this property if the controller is powered off during a system
suspend. The driver will need to reprobe the device on resume.

interrupts:
items:
- description: Handle to the line HOST_WAKE used to wake
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/boot/dts/overlays/README
Original file line number Diff line number Diff line change
Expand Up @@ -3992,6 +3992,8 @@ Params: l1ss Enable RC ASPM L1 sub-state support. Requires
requires DMA and MSI addresses to be 32bit.
mmio-hi Move the start of outbound 32bit addresses to
2GB and expand 64bit outbound space to 14GB.
no-pwr-ctrl Disable the regulator on the PCIe 3v3 supply.
This leaves it always enabled.


[ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ]
Expand Down
12 changes: 12 additions & 0 deletions arch/arm/boot/dts/overlays/pciex1-compat-pi5-overlay.dts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,22 @@
};
};

/*
* Disable the regulator on the PCIe 3v3 supply.
* Its is enabled by default by the firmware.
*/
fragment@4 {
target = <&pcie1_3v3>;
__dormant__ {
status = "disabled";
};
};

__overrides__ {
l1ss = <0>, "+0";
no-l0s = <0>, "+1";
no-mip = <0>, "+2";
mmio-hi = <0>, "+3";
no-pwr-ctrl = <0>, "+4";
};
};
31 changes: 31 additions & 0 deletions arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,17 @@
gpio = <&rp1_gpio 46 0>; // CD1_IO0_MICCLK, to MIPI 1 connector
};

pcie1_3v3: pcie1_3v3 {
compatible = "regulator-fixed";
regulator-name = "pcie1-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
enable-active-high;
gpio = <&rp1_gpio 28 GPIO_ACTIVE_HIGH>; // PCIE_RP1_WAKE
startup-delay-us = <20000>;
};

cam_dummy_reg: cam_dummy_reg {
compatible = "regulator-fixed";
regulator-name = "cam-dummy-reg";
Expand All @@ -125,6 +136,24 @@ rp1_target: &pcie2 {

&pcie1 {
brcm,fifo-qos-map = /bits/ 8 <3 3 3 3>;

/*
* Hack to get linux to probe this pcie after pcie2.
* The pcie-brcmstb driver does not defer probe if
* the regulator is not found yet. This forces pcie1
* to be probed after pcie2 so that the regulator
* is found.
*/
vpcie3v3-supply = <&pcie1_3v3>;

pci@0,0 {
device_type = "pci";
reg = <0 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
ranges;
vpcie3v3-supply = <&pcie1_3v3>;
};
};

// The system SPI for the bootloader EEPROM
Expand Down Expand Up @@ -374,6 +403,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
compatible = "brcm,bcm43438-bt";
max-speed = <3000000>;
shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
brcm,power-off-in-suspend;
local-bd-address = [ 00 00 00 00 00 00 ];
};
};
Expand Down Expand Up @@ -426,6 +456,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
vmmc-supply = <&wl_on_reg>;
sd-uhs-ddr50;
non-removable;
cap-power-off-card;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
Expand Down
2 changes: 2 additions & 0 deletions arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
compatible = "brcm,bcm43438-bt";
max-speed = <3000000>;
shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
brcm,power-off-in-suspend;
local-bd-address = [ 00 00 00 00 00 00 ];
};
};
Expand Down Expand Up @@ -411,6 +412,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
vmmc-supply = <&wl_on_reg>;
sd-uhs-ddr50;
non-removable;
cap-power-off-card;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
Expand Down
33 changes: 33 additions & 0 deletions arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5io.dtsi
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
// SPDX-License-Identifier: GPL-2.0

/ {
pcie1_3v3: pcie1_3v3 {
compatible = "regulator-fixed";
regulator-name = "pcie1-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
enable-active-high;
gpio = <&rp1_gpio 28 GPIO_ACTIVE_HIGH>; // PCIE_PWR_EN
startup-delay-us = <20000>;
};
};

&pcie1 {
/*
* Hack to get linux to probe this pcie after pcie2.
* The pcie-brcmstb driver does not defer probe if
* the regulator is not found yet. This forces pcie1
* to be probed after pcie2 so that the regulator
* is found.
*/
vpcie3v3-supply = <&pcie1_3v3>;

pci@0,0 {
device_type = "pci";
reg = <0 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
ranges;
vpcie3v3-supply = <&pcie1_3v3>;
};
};

i2c_csi_dsi1: &i2c0 { // Note: This is for CAM/DISP 1 connector
symlink = "i2c-11";
};
Expand Down
7 changes: 4 additions & 3 deletions arch/arm64/configs/bcm2712_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ CONFIG_ARM64_ERRATUM_2441009=y
CONFIG_ARM64_16K_PAGES=y
CONFIG_ARM64_VA_BITS_47=y
CONFIG_NR_CPUS=4
CONFIG_HOTPLUG_CPU=y
CONFIG_NUMA=y
CONFIG_COMPAT=y
CONFIG_ARMV8_DEPRECATED=y
Expand All @@ -59,9 +58,11 @@ CONFIG_CP15_BARRIER_EMULATION=y
CONFIG_SETEND_EMULATION=y
CONFIG_RANDOMIZE_BASE=y
CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
# CONFIG_SUSPEND is not set
CONFIG_PM=y
CONFIG_HIBERNATION=y
CONFIG_PM_DEBUG=y
CONFIG_DPM_WATCHDOG=y
CONFIG_DPM_WATCHDOG_TIMEOUT=30
CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT=5
CONFIG_CPU_IDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
Expand Down
63 changes: 61 additions & 2 deletions drivers/bluetooth/hci_bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ struct bcm_device_data {
* @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable
* @pcm_int_params: keep the initial PCM configuration
* @use_autobaud_mode: start Bluetooth device in autobaud mode
* @power_off_in_suspend: controller loses power during a system suspend and
* has to be rebuilt from scratch on resume
* @max_autobaud_speed: max baudrate supported by device in autobaud mode
*/
struct bcm_device {
Expand Down Expand Up @@ -147,6 +149,7 @@ struct bcm_device {
bool drive_rts_on_open;
bool no_uart_clock_set;
bool use_autobaud_mode;
bool power_off_in_suspend;
u8 pcm_int_params[5];
u32 max_autobaud_speed;
};
Expand Down Expand Up @@ -485,6 +488,14 @@ static int bcm_open(struct hci_uart *hu)

out:
if (bcm->dev) {
/*
* Since bcm_resume() reprobes the device, the suspend handling
* done by the hci_suspend_notifier is not necessary.
*/
if (IS_ENABLED(CONFIG_PM_SLEEP) && hu->serdev &&
bcm->dev->power_off_in_suspend)
set_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &hu->flags);

if (bcm->dev->use_autobaud_mode)
hci_uart_set_flow_control(hu, false); /* Assert BT_UART_CTS_N */
else if (bcm->dev->drive_rts_on_open)
Expand Down Expand Up @@ -817,6 +828,26 @@ static int bcm_resume_device(struct device *dev)
#endif

#ifdef CONFIG_PM_SLEEP
struct bcm_reprobe {
struct device *dev;
struct work_struct work;
};

static void bcm_reprobe_worker(struct work_struct *work)
{
struct bcm_reprobe *reprobe =
container_of(work, struct bcm_reprobe, work);
int ret;

ret = device_reprobe(reprobe->dev);
if (ret && ret != -EPROBE_DEFER)
dev_err(reprobe->dev, "Reprobe error %d\n", ret);

put_device(reprobe->dev);
kfree(reprobe);
module_put(THIS_MODULE);
}

/* suspend callback */
static int bcm_suspend(struct device *dev)
{
Expand All @@ -836,9 +867,13 @@ static int bcm_suspend(struct device *dev)
if (!bdev->hu)
goto unlock;

if (pm_runtime_active(dev))
if (pm_runtime_active(dev)) {
bcm_suspend_device(dev);

if (bdev->power_off_in_suspend)
bdev->set_shutdown(bdev, false);
}

if (device_may_wakeup(dev) && bdev->irq > 0) {
error = enable_irq_wake(bdev->irq);
if (!error)
Expand All @@ -855,6 +890,7 @@ static int bcm_suspend(struct device *dev)
static int bcm_resume(struct device *dev)
{
struct bcm_device *bdev = dev_get_drvdata(dev);
struct hci_uart *hu;
int err = 0;

bt_dev_dbg(bdev, "resume: is_suspended %d", bdev->is_suspended);
Expand All @@ -867,7 +903,8 @@ static int bcm_resume(struct device *dev)
*/
mutex_lock(&bcm_device_lock);

if (!bdev->hu)
hu = bdev->hu;
if (!hu)
goto unlock;

if (device_may_wakeup(dev) && bdev->irq > 0) {
Expand All @@ -886,6 +923,26 @@ static int bcm_resume(struct device *dev)
pm_runtime_enable(dev);
}

/*
* On boards flagged with brcm,power-off-in-suspend the controller is
* powered down entirely across a system suspend.
*
* Reprobe the device to resume it.
*/
if (hu && hu->serdev && bdev->power_off_in_suspend) {
struct bcm_reprobe *reprobe;

reprobe = kzalloc(sizeof(*reprobe), GFP_KERNEL);
if (!reprobe)
return 0;

__module_get(THIS_MODULE);

INIT_WORK(&reprobe->work, bcm_reprobe_worker);
reprobe->dev = get_device(&hu->serdev->dev);
queue_work(system_long_wq, &reprobe->work);
}

return 0;
}
#endif
Expand Down Expand Up @@ -1229,6 +1286,8 @@ static int bcm_of_probe(struct bcm_device *bdev)
{
bdev->use_autobaud_mode = device_property_read_bool(bdev->dev,
"brcm,requires-autobaud-mode");
bdev->power_off_in_suspend = device_property_read_bool(bdev->dev,
"brcm,power-off-in-suspend");
device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed);
device_property_read_u8_array(bdev->dev, "brcm,bt-pcm-int-params",
bdev->pcm_int_params, 5);
Expand Down
12 changes: 10 additions & 2 deletions drivers/gpio/gpio-brcmstb.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/irqchip/chained_irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/string_choices.h>

enum gio_reg_index {
Expand Down Expand Up @@ -576,8 +577,15 @@ static int brcmstb_gpio_resume(struct device *dev)
#endif /* CONFIG_PM_SLEEP */

static const struct dev_pm_ops brcmstb_gpio_pm_ops = {
.suspend_noirq = brcmstb_gpio_suspend,
.resume_noirq = brcmstb_gpio_resume,
/*
* A hibernate power cycle wipes this GPIO bank's registers, same
* as a suspend-to-RAM transition. Only wiring .suspend_noirq/
* .resume_noirq left the save/restore logic below unreachable on
* the freeze/thaw and poweroff/restore phases hibernate actually
* uses, so an output pin's level (and anything else save/restore
* covers) was silently lost across hibernate specifically.
*/
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(brcmstb_gpio_suspend, brcmstb_gpio_resume)
};

static int brcmstb_gpio_probe(struct platform_device *pdev)
Expand Down
35 changes: 35 additions & 0 deletions drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_of.h>
#include <drm/drm_print.h>
Expand Down Expand Up @@ -522,6 +523,39 @@ static void rp1dsi_platform_shutdown(struct platform_device *pdev)
rp1dsi_stopall(drm);
}

static int rp1dsi_platform_suspend(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct rp1_dsi *dsi = drm->dev_private;
int ret;

ret = drm_mode_config_helper_suspend(drm);
if (ret)
return ret;

if (dsi->clocks[RP1DSI_CLOCK_CFG])
clk_disable_unprepare(dsi->clocks[RP1DSI_CLOCK_CFG]);

return 0;
}

static int rp1dsi_platform_resume(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct rp1_dsi *dsi = drm->dev_private;
int ret;

if (dsi->clocks[RP1DSI_CLOCK_CFG])
clk_prepare_enable(dsi->clocks[RP1DSI_CLOCK_CFG]);

ret = drm_mode_config_helper_resume(drm);

return ret;
}

static DEFINE_SIMPLE_DEV_PM_OPS(rp1dsi_pm_ops, rp1dsi_platform_suspend,
rp1dsi_platform_resume);

static const struct of_device_id rp1dsi_of_match[] = {
{
.compatible = "raspberrypi,rp1dsi",
Expand All @@ -539,6 +573,7 @@ static struct platform_driver rp1dsi_platform_driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = rp1dsi_of_match,
.pm = pm_sleep_ptr(&rp1dsi_pm_ops),
},
};

Expand Down
Loading