Files
yggdrasil/kernel/lib/device-tree/src/driver/traits.rs
T

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)
}
}
}