diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index bf8400ca9..5145bd689 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -449,3 +449,17 @@ crate::pac::pins!(
         }
     };
 );
+
+pub(crate) unsafe fn init() {
+    crate::pac::gpio_rcc! {
+        ($en_reg:ident) => {
+            crate::pac::RCC.$en_reg().modify(|reg| {
+                crate::pac::gpio_rcc! {
+                    ($name:ident, $clock:ident, $en_reg, $rst_reg:ident, $en_fn:ident, $rst_fn:ident) => {
+                        reg.$en_fn(true);
+                    };
+                }
+            });
+        };
+    }
+}
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 07f8b9f3b..89fd86448 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -89,6 +89,7 @@ pub fn init(config: Config) -> Peripherals {
     let p = Peripherals::take();
 
     unsafe {
+        gpio::init();
         dma::init();
         #[cfg(exti)]
         exti::init();
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs
index 097466cea..907356500 100644
--- a/examples/stm32h7/src/bin/usart_dma.rs
+++ b/examples/stm32h7/src/bin/usart_dma.rs
@@ -71,22 +71,10 @@ fn main() -> ! {
         .pll1_q_ck(48.mhz())
         .freeze(pwrcfg, &pp.SYSCFG);
 
-    let pp = unsafe { pac::Peripherals::steal() };
-
     unsafe {
         Dbgmcu::enable_all();
     }
 
-    pp.RCC.ahb4enr.modify(|_, w| {
-        w.gpioaen().set_bit();
-        w.gpioben().set_bit();
-        w.gpiocen().set_bit();
-        w.gpioden().set_bit();
-        w.gpioeen().set_bit();
-        w.gpiofen().set_bit();
-        w
-    });
-
     unsafe { embassy::time::set_clock(&ZeroClock) };
 
     let executor = EXECUTOR.put(Executor::new());
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index bfc2384cd..203d943de 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -287,6 +287,8 @@ pub fn gen(options: Options) {
         let mut peripheral_counts: HashMap<String, u8> = HashMap::new();
         let mut dma_channel_counts: HashMap<String, u8> = HashMap::new();
         let mut dbgmcu_table: Vec<Vec<String>> = Vec::new();
+        let mut gpio_rcc_table: Vec<Vec<String>> = Vec::new();
+        let mut gpio_regs: HashSet<String> = HashSet::new();
 
         let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address;
         let gpio_stride = 0x400;
@@ -465,29 +467,33 @@ pub fn gen(options: Options) {
                                     clock.to_ascii_lowercase()
                                 };
 
-                                if !name.starts_with("GPIO") {
-                                    let mut row = Vec::with_capacity(6);
-                                    row.push(name.clone());
-                                    row.push(clock);
-                                    row.push(enable_reg.to_ascii_lowercase());
+                                let mut row = Vec::with_capacity(6);
+                                row.push(name.clone());
+                                row.push(clock);
+                                row.push(enable_reg.to_ascii_lowercase());
 
-                                    if let Some((reset_reg, reset_field)) = reset_reg_field {
-                                        row.push(reset_reg.to_ascii_lowercase());
-                                        row.push(format!(
-                                            "set_{}",
-                                            enable_field.to_ascii_lowercase()
-                                        ));
-                                        row.push(format!(
-                                            "set_{}",
-                                            reset_field.to_ascii_lowercase()
-                                        ));
-                                    } else {
-                                        row.push(format!(
-                                            "set_{}",
-                                            enable_field.to_ascii_lowercase()
-                                        ));
-                                    }
+                                if let Some((reset_reg, reset_field)) = reset_reg_field {
+                                    row.push(reset_reg.to_ascii_lowercase());
+                                    row.push(format!(
+                                        "set_{}",
+                                        enable_field.to_ascii_lowercase()
+                                    ));
+                                    row.push(format!(
+                                        "set_{}",
+                                        reset_field.to_ascii_lowercase()
+                                    ));
+                                } else {
+                                    row.push(format!(
+                                        "set_{}",
+                                        enable_field.to_ascii_lowercase()
+                                    ));
+                                }
+
+                                if !name.starts_with("GPIO") {
                                     peripheral_rcc_table.push(row);
+                                } else {
+                                    gpio_rcc_table.push(row);
+                                    gpio_regs.insert( enable_reg.to_ascii_lowercase() );
                                 }
                             }
                             (None, Some(_)) => {
@@ -504,6 +510,10 @@ pub fn gen(options: Options) {
             dev.peripherals.push(ir_peri);
         }
 
+        for reg in gpio_regs {
+            gpio_rcc_table.push( vec!( reg ) );
+        }
+
         for (id, channel_info) in &core.dma_channels {
             let mut row = Vec::new();
             let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
@@ -586,6 +596,7 @@ pub fn gen(options: Options) {
             &peripheral_dma_channels_table,
         );
         make_table(&mut extra, "peripheral_rcc", &peripheral_rcc_table);
+        make_table(&mut extra, "gpio_rcc", &gpio_rcc_table);
         make_table(&mut extra, "dma_channels", &dma_channels_table);
         make_table(&mut extra, "dbgmcu", &dbgmcu_table);
         make_peripheral_counts(&mut extra, &peripheral_counts);