Sync up with changes to kernel's phandle irq scheme

This commit is contained in:
Andrey Turkin
2024-11-16 09:16:00 +03:00
parent 2f9e28e23e
commit e5e753a426
3 changed files with 36 additions and 18 deletions
+5 -3
View File
@@ -15,6 +15,7 @@ pub struct InterruptMap {
pub interrupt: u32,
pub parent_phandle: u32,
pub parent_interrupt: [u32; 3],
pub parent_interrupt_cells: usize,
}
// https://elinux.org/Device_Tree_Usage has a lot of useful information
@@ -55,11 +56,11 @@ fn locate_ecam_dtb<T>(
let mut interrupt_map = Vec::<InterruptMap>::new();
while let Ok([addr1, addr2, addr3, int1, phandle]) = interrupt_map_data.next_chunk::<5>() {
let parent = dt.find_phandle(phandle).unwrap();
let interrupt_cells = parent.interrupt_cells().unwrap();
let parent_interrupt = match interrupt_cells {
let parent_interrupt_cells = parent.interrupt_cells().unwrap();
let parent_interrupt = match parent_interrupt_cells {
1 if let Some(a) = interrupt_map_data.next() => [a, 0, 0],
2 if let Ok([a, b]) = interrupt_map_data.next_chunk::<2>() => [a, b, 0],
2 if let Ok([a, b, c]) = interrupt_map_data.next_chunk::<3>() => [a, b, c],
3 if let Ok([a, b, c]) = interrupt_map_data.next_chunk::<3>() => [a, b, c],
_ => break,
};
interrupt_map.push(InterruptMap {
@@ -67,6 +68,7 @@ fn locate_ecam_dtb<T>(
interrupt: int1,
parent_phandle: phandle,
parent_interrupt,
parent_interrupt_cells,
});
}
+24 -9
View File
@@ -25,18 +25,26 @@ pub mod msi;
pub struct LegacyInterruptLine {
#[doc(hidden)]
pub irq: u8,
pub phandled: Option<(u32, [u32; 3])>,
pub phandled: Option<(u32, [u32; 3], usize)>,
}
impl LegacyInterruptLine {
/// Get an IRQ handle for this interrupt line.
pub fn irq_handle(self, driver: &str) -> File {
if let Some((phandle, addr)) = self.phandled {
File::create(format!(
"/scheme/irq/phandle-{}/{},{},{}",
phandle, addr[0], addr[1], addr[2]
))
.unwrap_or_else(|err| panic!("{driver}: failed to open IRQ file: {err}"))
if let Some((phandle, addr, cells)) = self.phandled {
let path = match cells {
1 => format!("/scheme/irq/phandle-{}/{}", phandle, addr[0]),
2 => format!("/scheme/irq/phandle-{}/{},{}", phandle, addr[0], addr[1]),
3 => format!(
"/scheme/irq/phandle-{}/{},{},{}",
phandle, addr[0], addr[1], addr[2]
),
_ => panic!(
"unexpected number of IRQ description cells for phandle {phandle}: {cells}"
),
};
File::create(path)
.unwrap_or_else(|err| panic!("{driver}: failed to open IRQ file: {err}"))
} else {
File::open(format!("/scheme/irq/{}", self.irq))
.unwrap_or_else(|err| panic!("{driver}: failed to open IRQ file: {err}"))
@@ -46,8 +54,15 @@ impl LegacyInterruptLine {
impl fmt::Display for LegacyInterruptLine {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some((phandle, addr)) = self.phandled {
write!(f, "(phandle {}, {:?})", phandle, addr)
if let Some((phandle, addr, cells)) = self.phandled {
match cells {
1 => write!(f, "(phandle {}, {:?})", phandle, addr[0]),
2 => write!(f, "(phandle {}, {:?},{:?})", phandle, addr[0], addr[1]),
3 => write!(f, "(phandle {}, {:?})", phandle, addr),
_ => panic!(
"unexpected number of IRQ description cells for phandle {phandle}: {cells}"
),
}
} else {
write!(f, "{}", self.irq)
}
+7 -6
View File
@@ -136,7 +136,7 @@ fn handle_parsed_header(
}
};
let mut phandled: Option<(u32, [u32; 3])> = None;
let mut phandled: Option<(u32, [u32; 3], usize)> = None;
if legacy_interrupt_enabled {
let pci_address = endpoint_header.header().address();
let dt_address = ((pci_address.bus() as u32) << 16)
@@ -154,11 +154,12 @@ fn handle_parsed_header(
.iter()
.find(|x| x.addr == addr[0..3] && x.interrupt == addr[3]);
if let Some(mapping) = mapping {
debug!(
"found mapping: addr={:?} => (phandle={} irq={:?})",
addr, mapping.parent_phandle, mapping.parent_interrupt
);
phandled = Some((mapping.parent_phandle, mapping.parent_interrupt));
phandled = Some((
mapping.parent_phandle,
mapping.parent_interrupt,
mapping.parent_interrupt_cells,
));
debug!("found mapping: addr={:?} => {:?}", addr, phandled);
}
}