1use alloc::vec::Vec;
2
3use crate::{
4 DeviceKind, DriverInfoKind, DriverRegister,
5 probe::ProbeData,
6 register::{OnProbeKindFdt, ProbeKind, RegisterContainer},
7};
8
9use crate::error::DriverError;
10
11use super::device;
12
13#[derive(Default)]
14pub struct Manager {
15 pub registers: RegisterContainer,
16 pub intc: device::intc::Container,
17 pub timer: device::timer::Container,
18 pub probe_kind: ProbeData,
19}
20
21impl Manager {
22 pub fn new(driver_info_kind: DriverInfoKind) -> Self {
23 Self {
24 probe_kind: driver_info_kind.into(),
25 ..Default::default()
26 }
27 }
28
29 pub fn probe_intc(&mut self) -> Result<(), DriverError> {
30 let ls = self
31 .registers
32 .unregistered()
33 .into_iter()
34 .filter(|(_, e)| {
35 let mut has = false;
36 for kind in e.probe_kinds {
37 match kind {
38 ProbeKind::Fdt {
39 compatibles: _,
40 on_probe,
41 } => {
42 if matches!(on_probe, OnProbeKindFdt::Intc(_)) {
43 has = true;
44 break;
45 }
46 }
47 }
48 }
49 has
50 })
51 .collect::<Vec<_>>();
52
53 self.probe_with(&ls)
54 }
55
56 pub fn probe_timer(&mut self) -> Result<(), DriverError> {
57 let ls = self
58 .registers
59 .unregistered()
60 .into_iter()
61 .filter(|(_, e)| {
62 let mut has = false;
63 for kind in e.probe_kinds {
64 match kind {
65 ProbeKind::Fdt {
66 compatibles: _,
67 on_probe,
68 } => {
69 if matches!(on_probe, OnProbeKindFdt::Timer(_)) {
70 has = true;
71 break;
72 }
73 }
74 }
75 }
76 has
77 })
78 .collect::<Vec<_>>();
79
80 self.probe_with(&ls)
81 }
82
83 pub fn probe(&mut self) -> Result<(), DriverError> {
84 let ls = self.registers.unregistered();
85
86 self.probe_with(&ls)
87 }
88
89 fn probe_with(&mut self, registers: &[(usize, DriverRegister)]) -> Result<(), DriverError> {
90 let probed_list = match &mut self.probe_kind {
91 ProbeData::Fdt(probe_data) => probe_data.probe(registers)?,
92 ProbeData::Static => Vec::new(),
93 };
94
95 for probed in probed_list {
96 match probed.kind {
97 DeviceKind::Intc(device) => {
98 self.intc.insert(device);
99 }
100 DeviceKind::Timer(device) => {
101 self.timer.insert(device);
102 }
103 }
104 self.registers.set_probed(probed.register_id);
105 }
106
107 Ok(())
108 }
109}