1+ // SPDX-License-Identifier: MIT OR Apache-2.0
2+ //
3+ // Copyright (c) 2018-2025 Andre Richter <[email protected] > 4+ // Copyright (c) 2025 Devansh Lodha <[email protected] > 5+
6+ //! BSP driver support for the Raspberry Pi 5.
7+
8+ use super :: memory:: map:: mmio;
9+ use crate :: { bsp:: device_driver, console, driver as generic_driver} ;
10+ use core:: sync:: atomic:: { AtomicBool , Ordering } ;
11+
12+ //--------------------------------------------------------------------------------------------------
13+ // Global instances
14+ //--------------------------------------------------------------------------------------------------
15+
16+ static PL011_UART : device_driver:: PL011Uart =
17+ unsafe { device_driver:: PL011Uart :: new ( mmio:: PL011_UART_START ) } ;
18+
19+ static GPIO : device_driver:: GPIO =
20+ unsafe { device_driver:: GPIO :: new ( mmio:: GPIO_START , mmio:: PADS_BANK0_START ) } ;
21+
22+ //--------------------------------------------------------------------------------------------------
23+ // Private Code
24+ //--------------------------------------------------------------------------------------------------
25+
26+ /// This must be called only after successful init of the UART driver.
27+ fn post_init_uart ( ) -> Result < ( ) , & ' static str > {
28+ console:: register_console ( & PL011_UART ) ;
29+ Ok ( ( ) )
30+ }
31+
32+ /// This must be called only after successful init of the GPIO driver.
33+ fn post_init_gpio ( ) -> Result < ( ) , & ' static str > {
34+ GPIO . map_pl011_uart ( ) ;
35+ Ok ( ( ) )
36+ }
37+
38+ fn driver_uart ( ) -> Result < ( ) , & ' static str > {
39+ let uart_descriptor =
40+ generic_driver:: DeviceDriverDescriptor :: new ( & PL011_UART , Some ( post_init_uart) ) ;
41+ generic_driver:: driver_manager ( ) . register_driver ( uart_descriptor) ;
42+ Ok ( ( ) )
43+ }
44+
45+ fn driver_gpio ( ) -> Result < ( ) , & ' static str > {
46+ let gpio_descriptor = generic_driver:: DeviceDriverDescriptor :: new ( & GPIO , Some ( post_init_gpio) ) ;
47+ generic_driver:: driver_manager ( ) . register_driver ( gpio_descriptor) ;
48+ Ok ( ( ) )
49+ }
50+
51+ //--------------------------------------------------------------------------------------------------
52+ // Public Code
53+ //--------------------------------------------------------------------------------------------------
54+
55+ /// Initialize the driver subsystem.
56+ ///
57+ /// # Safety
58+ ///
59+ /// See child function calls.
60+ pub unsafe fn init ( ) -> Result < ( ) , & ' static str > {
61+ static INIT_DONE : AtomicBool = AtomicBool :: new ( false ) ;
62+ if INIT_DONE . load ( Ordering :: Relaxed ) {
63+ return Err ( "Init already done" ) ;
64+ }
65+
66+ // On the Raspberry Pi 5, GPIO pins must be configured for their peripheral
67+ // function (e.g., UART) before the peripheral itself is initialized.
68+ driver_gpio ( ) ?;
69+ driver_uart ( ) ?;
70+
71+ INIT_DONE . store ( true , Ordering :: Relaxed ) ;
72+ Ok ( ( ) )
73+ }
0 commit comments