82 lines
2.8 KiB
Rust
82 lines
2.8 KiB
Rust
//! Device tree driver interfaces
|
|
use core::ops::Range;
|
|
|
|
use alloc::sync::{Arc, Weak};
|
|
use device_api::{
|
|
bus::Bus,
|
|
clock::{ClockHandle, ResetHandle},
|
|
device::Device,
|
|
gpio::PinHandle,
|
|
interrupt::{ExternalInterruptController, FullIrq},
|
|
};
|
|
use libk::error::Error;
|
|
|
|
use crate::{driver::DeviceTreeGpioPins, TProp};
|
|
|
|
use super::{InitSequence, Node};
|
|
|
|
/// Device tree driver interface
|
|
pub trait Driver: Sync {
|
|
/// Constructs a [Device] for a given matching node
|
|
fn probe(&self, node: &Arc<Node>, context: &mut ProbeContext) -> Option<Arc<dyn Device>>;
|
|
}
|
|
|
|
/// Device-tree based interrupt mapper/controller interface
|
|
pub trait DeviceTreeInterruptController {
|
|
/// Reads interrupt information from `property` at given `offset` and maps it to
|
|
/// the interrupt used by the controller
|
|
fn map_interrupt(&self, property: &TProp, offset: usize) -> Option<FullIrq>;
|
|
|
|
/// Returns the [ExternalInterruptController] implementor of this node
|
|
fn as_interrupt_controller(self: Arc<Self>) -> Arc<dyn ExternalInterruptController>;
|
|
}
|
|
|
|
/// Device-tree based clock source interface
|
|
pub trait DeviceTreeClockController {
|
|
/// Reads clock information from `property` at given `offset` and maps it to a
|
|
/// [ClockHandle], returning the handle + the size of the clock entry.
|
|
fn map_clock(self: Arc<Self>, property: &TProp, offset: usize) -> Option<(ClockHandle, usize)>;
|
|
}
|
|
|
|
/// Device-tree based reset source interface
|
|
pub trait DeviceTreeResetController {
|
|
/// Reads reset information from `property` at given `offset` and maps it to a
|
|
/// [ResetHandle], returning the handle + the size of the reset entry.
|
|
fn map_reset(self: Arc<Self>, property: &TProp, offset: usize) -> Option<(ResetHandle, usize)>;
|
|
}
|
|
|
|
/// Context passed to the driver's `probe` function
|
|
pub struct ProbeContext {
|
|
/// Parent bus of the node being probed
|
|
pub bus: Option<Weak<dyn Bus>>,
|
|
/// Can be used to set a specific initialization sequence for the device
|
|
pub sequence: Option<InitSequence>,
|
|
}
|
|
|
|
/// `-pinctrl`-type devices, used for configuring pin groups
|
|
pub trait DeviceTreePinController {
|
|
/// Configure a pin group
|
|
fn configure_pin_group(self: Arc<Self>, pins: &Arc<Node>) -> Result<(), Error>;
|
|
/// Reads GPIO pin information from `property` at given `offset` and maps it to a
|
|
/// [PinHandle], returning the handle + the size of the GPIO entry.
|
|
fn map_gpio(
|
|
self: Arc<Self>,
|
|
property: &TProp,
|
|
offset: usize,
|
|
info: &DeviceTreeGpioPins,
|
|
) -> Option<(PinHandle, usize)>;
|
|
}
|
|
|
|
impl ProbeContext {
|
|
/// See [Node::map_range]
|
|
pub fn map_range(&self, range: Range<u64>) -> Option<Range<u64>> {
|
|
if let Some(bus) = self.bus.as_ref().and_then(Weak::upgrade) {
|
|
// Use parent bus to map the address
|
|
bus.map_range(range)
|
|
} else {
|
|
// Identity
|
|
Some(range)
|
|
}
|
|
}
|
|
}
|