diff --git a/kernel/src/device/clock/jh7110_aoncrg.rs b/kernel/src/device/clock/jh7110_aoncrg.rs index 49941204..8c47f014 100644 --- a/kernel/src/device/clock/jh7110_aoncrg.rs +++ b/kernel/src/device/clock/jh7110_aoncrg.rs @@ -13,7 +13,7 @@ use device_tree::{ DeviceTreePropertyRead, TProp, }; use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIo}; -use libk_util::{sync::IrqSafeSpinlock, OneTimeInit}; +use libk_util::sync::IrqSafeSpinlock; use tock_registers::{ interfaces::{Readable, Writeable}, register_structs, @@ -58,28 +58,21 @@ enum ClockParent { pub struct Aoncrg { base: PhysicalAddress, clock_parents: [ClockHandle; 7], - mapping: OneTimeInit>>, + mapping: IrqSafeSpinlock>, } impl Aoncrg { - fn ensure_init(&self) -> Result<&IrqSafeSpinlock>, Error> { - self.mapping.or_try_init_with(|| { - unsafe { DeviceMemoryIo::map(self.base, Default::default()) }.map(IrqSafeSpinlock::new) - }) - } - fn clk_enable_int(&self, index: u32) -> Result<(), Error> { let (name, reg) = Self::map_clock_index(index) .ok_or(Error::InvalidArgument) .inspect_err(|_| log::warn!("jh7110-syscrg: undefined clock {:?}", index))?; - let regs = self.ensure_init()?; match reg { ClockRegister::Fixed => Ok(()), ClockRegister::Gate(bit, parent) => { self.clk_enable_parent(parent)?; log::info!("jh7110-aoncrg: enable {name:?} @ {index}"); - let lock = regs.lock(); + let lock = self.mapping.lock(); lock.CLOCKS[index as usize].set(lock.CLOCKS[index as usize].get() | (1 << bit)); Ok(()) } @@ -145,8 +138,7 @@ impl ClockController for Aoncrg { impl ResetController for Aoncrg { fn assert_reset(&self, reset: Option) -> Result<(), Error> { let reset = reset.ok_or(Error::InvalidArgument)?; - let mapping = self.ensure_init()?; - let regs = mapping.lock(); + let regs = self.mapping.lock(); let val = regs.RESETS.get(); regs.RESETS.set(val | (1 << reset)); Ok(()) @@ -154,8 +146,7 @@ impl ResetController for Aoncrg { fn deassert_reset(&self, reset: Option) -> Result<(), Error> { let reset = reset.ok_or(Error::InvalidArgument)?; - let mapping = self.ensure_init()?; - let regs = mapping.lock(); + let regs = self.mapping.lock(); let val = regs.RESETS.get(); regs.RESETS.set(val & !(1 << reset)); Ok(()) @@ -204,11 +195,14 @@ device_tree_driver! { node.named_clock("rtc_osc")?, ]; + let mapping = unsafe { DeviceMemoryIo::map(base, Default::default()) }.ok()?; + let aoncrg = Arc::new(Aoncrg { base, clock_parents, - mapping: OneTimeInit::new() + mapping: IrqSafeSpinlock::new(mapping) }); + node.make_reset_controller(aoncrg.clone()); node.make_clock_controller(aoncrg.clone()); Some(aoncrg) diff --git a/kernel/src/device/clock/jh7110_syscrg.rs b/kernel/src/device/clock/jh7110_syscrg.rs index 3359d195..88c5dc7b 100644 --- a/kernel/src/device/clock/jh7110_syscrg.rs +++ b/kernel/src/device/clock/jh7110_syscrg.rs @@ -14,14 +14,14 @@ use device_tree::{ DeviceTreePropertyRead, TProp, }; use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIoMut}; -use libk_util::{sync::IrqSafeSpinlock, OneTimeInit}; +use libk_util::sync::IrqSafeSpinlock; const PARENT_CLK_OSC: usize = 0; struct Syscrg { base: PhysicalAddress, parents: [ClockHandle; 1], - mapping: OneTimeInit>>, + mapping: IrqSafeSpinlock>, } #[derive(Debug, Clone, Copy)] @@ -43,31 +43,23 @@ enum ClockRegister { } impl Syscrg { - fn ensure_init(&self) -> Result<&IrqSafeSpinlock>, Error> { - self.mapping.or_try_init_with(move || { - unsafe { DeviceMemoryIoMut::map_slice(self.base, 256, Default::default()) } - .map(IrqSafeSpinlock::new) - }) - } - fn clk_enable_int(&self, index: u32, depth: u32) -> Result<(), Error> { let (name, reg) = Self::map_clock_index(index) .ok_or(Error::InvalidArgument) .inspect_err(|_| log::warn!("jh7110-syscrg: undefined clock {:?}", index))?; - let regs = self.ensure_init()?; match reg { ClockRegister::Gate(bit, parent) => { log::info!("jh7110-syscrg: enable {name:?} @ {index} /{depth}"); self.clk_enable_parent(parent, depth)?; - let mut lock = regs.lock(); + let mut lock = self.mapping.lock(); lock[index as usize] |= 1 << bit; Ok(()) } ClockRegister::Inv(bit, parent) => { log::info!("jh7110-syscrg: enable clk inv {name:?} @ {index}"); self.clk_enable_parent(parent, depth)?; - let mut lock = regs.lock(); + let mut lock = self.mapping.lock(); lock[index as usize] |= 1 << bit; Ok(()) } @@ -182,8 +174,7 @@ impl Syscrg { fn rst_trigger(&self, reset: u32, assert: bool) -> Result<(), Error> { let reg = (190 + reset / 32) as usize; let bit = reset % 32; - let regs = self.ensure_init()?; - let mut regs = regs.lock(); + let mut regs = self.mapping.lock(); let expect = if assert { regs[reg] |= 1 << bit; @@ -246,17 +237,23 @@ impl DeviceTreeResetController for Syscrg { } } +unsafe impl Sync for Syscrg {} +unsafe impl Send for Syscrg {} + device_tree_driver! { compatible: ["starfive,jh7110-syscrg"], driver: { fn probe(&self, node: &Arc, context: &mut ProbeContext) -> Option> { let base = node.map_base(context, 0)?; let osc = node.named_clock("osc")?; + let mapping = unsafe { DeviceMemoryIoMut::map_slice(base, 256, Default::default()) } + .inspect_err(|error| log::error!("jh7110-syscrg: {error:?}")) + .ok()?; let syscrg = Arc::new(Syscrg { base, parents: [osc], - mapping: OneTimeInit::new(), + mapping: IrqSafeSpinlock::new(mapping), }); node.make_reset_controller(syscrg.clone()); node.make_clock_controller(syscrg.clone());