use alloc::{sync::Arc, vec::Vec};
use ax_errno::AxResult;
use axdevice_base::{BaseMmioDeviceOps, BasePortDeviceOps, BaseSysRegDeviceOps};
pub trait PollableDeviceOps: Send + Sync {
fn poll(&self, now_ns: u64) -> AxResult;
}
#[non_exhaustive]
pub enum DeviceRegistration {
Mmio(Arc<dyn BaseMmioDeviceOps>),
Port(Arc<dyn BasePortDeviceOps>),
SysReg(Arc<dyn BaseSysRegDeviceOps>),
Pollable(Arc<dyn PollableDeviceOps>),
}
#[derive(Default)]
pub struct DeviceBundle {
pub(crate) mmio: Vec<Arc<dyn BaseMmioDeviceOps>>,
pub(crate) port: Vec<Arc<dyn BasePortDeviceOps>>,
pub(crate) sysreg: Vec<Arc<dyn BaseSysRegDeviceOps>>,
pub(crate) pollable: Vec<Arc<dyn PollableDeviceOps>>,
}
impl DeviceBundle {
pub const fn new() -> Self {
Self {
mmio: Vec::new(),
port: Vec::new(),
sysreg: Vec::new(),
pollable: Vec::new(),
}
}
pub fn from_registration(registration: DeviceRegistration) -> Self {
let mut bundle = Self::new();
bundle.push(registration);
bundle
}
pub fn push(&mut self, registration: DeviceRegistration) {
match registration {
DeviceRegistration::Mmio(device) => self.mmio.push(device),
DeviceRegistration::Port(device) => self.port.push(device),
DeviceRegistration::SysReg(device) => self.sysreg.push(device),
DeviceRegistration::Pollable(device) => self.pollable.push(device),
}
}
pub fn with_registration(mut self, registration: DeviceRegistration) -> Self {
self.push(registration);
self
}
pub fn is_empty(&self) -> bool {
self.mmio.is_empty()
&& self.port.is_empty()
&& self.sysreg.is_empty()
&& self.pollable.is_empty()
}
}
impl From<DeviceRegistration> for DeviceBundle {
fn from(registration: DeviceRegistration) -> Self {
Self::from_registration(registration)
}
}