1use core::fmt::Debug;
2
3use crate::{node::Node, read::FdtReader, Fdt, Phandle};
4
5pub struct ClocksIter<'a> {
6 pub fdt: Fdt<'a>,
7 pub id_list: Option<FdtReader<'a>>,
8 pub name_list: Option<FdtReader<'a>>,
9}
10
11impl<'a> ClocksIter<'a> {
12 pub fn new(node: &'a Node<'a>) -> Self {
13 let fdt = node.fdt.clone();
14 let id_list = node.find_property("clocks");
15 let name_list = node.find_property("clock-names");
16
17 Self {
18 fdt,
19 id_list: id_list.map(|p| p.data),
20 name_list: name_list.map(|p| p.data),
21 }
22 }
23}
24
25impl<'a> Iterator for ClocksIter<'a> {
26 type Item = ClockRef<'a>;
27
28 fn next(&mut self) -> Option<Self::Item> {
29 let p = self.id_list.as_mut()?;
30 let phandle = Phandle::from(p.take_u32()?);
31
32 let node = self.fdt.get_node_by_phandle(phandle)?;
33 let mut select = 0;
34 let mut name = None;
35 let mut clock_frequency = None;
36
37 let cell_size = node
38 .find_property("#clock-cells")
39 .expect("#clock-cells not found")
40 .u32();
41
42 if cell_size > 0 {
43 select = p.take_u32().expect("invalid clock cells");
44 } else {
45 clock_frequency = node.clock_frequency()
46 }
47
48 if let Some(name_prop) = &mut self.name_list {
49 name = name_prop.take_str().ok();
50 }
51
52 Some(ClockRef {
53 node,
54 select: select as _,
55 name,
56 clock_frequency,
57 })
58 }
59}
60
61pub struct ClockRef<'a> {
62 pub node: Node<'a>,
63 pub select: usize,
65 pub name: Option<&'a str>,
66 pub clock_frequency: Option<u32>,
67}
68
69impl Debug for ClockRef<'_> {
70 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
71 f.debug_struct("ClockRef")
72 .field("node", &self.node.name())
73 .field("select", &self.select)
74 .field("name", &self.name)
75 .field("clock-frequency", &self.clock_frequency)
76 .finish()
77 }
78}