123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146 |
- use core::ops::{BitXor, Deref, DerefMut};
- use alloc::{string::String, sync::Arc};
- use log::{debug, error, warn};
- use system_error::SystemError;
- use crate::{
- driver::base::device::DeviceId,
- exception::{
- irqchip::IrqChipSetMaskResult,
- irqdesc::{irq_desc_manager, InnerIrqDesc, IrqAction},
- },
- libs::{cpumask::CpuMask, spinlock::SpinLockGuard},
- process::{kthread::KernelThreadMechanism, ProcessManager},
- smp::cpu::ProcessorId,
- };
- use super::{
- dummychip::no_irq_chip,
- irqchip::IrqChipFlags,
- irqdata::{IrqData, IrqHandlerData, IrqLineStatus, IrqStatus},
- irqdesc::{InnerIrqAction, IrqDesc, IrqDescState, IrqHandleFlags, IrqHandler, IrqReturn},
- irqdomain::irq_domain_manager,
- IrqNumber,
- };
- lazy_static! {
-
- static ref IRQ_DEFAULT_AFFINITY: CpuMask = {
- let mut mask = CpuMask::new();
-
- mask.set(ProcessorId::new(0), true);
- mask
- };
- }
- pub fn irq_manager() -> &'static IrqManager {
- &IrqManager
- }
- pub struct IrqManager;
- impl IrqManager {
- pub const IRQ_RESEND: bool = true;
- #[allow(dead_code)]
- pub const IRQ_NORESEND: bool = false;
- #[allow(dead_code)]
- pub const IRQ_START_FORCE: bool = true;
- pub const IRQ_START_COND: bool = false;
-
-
-
-
-
-
-
-
-
- pub fn request_irq(
- &self,
- irq: IrqNumber,
- name: String,
- handler: &'static dyn IrqHandler,
- flags: IrqHandleFlags,
- dev_id: Option<Arc<DeviceId>>,
- ) -> Result<(), SystemError> {
- return self.request_threaded_irq(irq, Some(handler), None, flags, name, dev_id);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- pub fn request_threaded_irq(
- &self,
- irq: IrqNumber,
- mut handler: Option<&'static dyn IrqHandler>,
- thread_fn: Option<&'static dyn IrqHandler>,
- flags: IrqHandleFlags,
- dev_name: String,
- dev_id: Option<Arc<DeviceId>>,
- ) -> Result<(), SystemError> {
- if irq == IrqNumber::IRQ_NOTCONNECTED {
- return Err(SystemError::ENOTCONN);
- }
-
-
-
-
- if ((flags.contains(IrqHandleFlags::IRQF_SHARED)) && dev_id.is_none())
- || ((flags.contains(IrqHandleFlags::IRQF_SHARED))
- && (flags.contains(IrqHandleFlags::IRQF_NO_AUTOEN)))
- || (!(flags.contains(IrqHandleFlags::IRQF_SHARED))
- && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND)))
- || ((flags.contains(IrqHandleFlags::IRQF_NO_SUSPEND))
- && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND)))
- {
- return Err(SystemError::EINVAL);
- }
- let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
- if !desc.can_request() {
- warn!("desc {} can not request", desc.irq().data());
- return Err(SystemError::EINVAL);
- }
- if handler.is_none() {
- if thread_fn.is_none() {
-
- return Err(SystemError::EINVAL);
- }
-
- handler = Some(&DefaultPrimaryIrqHandler);
- }
- let irqaction = IrqAction::new(irq, dev_name, handler, thread_fn);
- let mut action_guard = irqaction.inner();
- *action_guard.flags_mut() = flags;
- *action_guard.dev_id_mut() = dev_id;
- drop(action_guard);
- debug!("to inner_setup_irq: {irq:?}");
- return self.inner_setup_irq(irq, irqaction, desc);
- }
-
- #[inline(never)]
- fn inner_setup_irq(
- &self,
- irq: IrqNumber,
- action: Arc<IrqAction>,
- desc: Arc<IrqDesc>,
- ) -> Result<(), SystemError> {
-
- let err_out_thread =
- |e: SystemError, mut action_guard: SpinLockGuard<'_, InnerIrqAction>| -> SystemError {
- if let Some(thread_pcb) = action_guard.thread() {
- action_guard.set_thread(None);
- KernelThreadMechanism::stop(&thread_pcb).ok();
- }
- if let Some(secondary) = action_guard.secondary() {
- let mut secondary_guard = secondary.inner();
- if let Some(thread_pcb) = secondary_guard.thread() {
- secondary_guard.set_thread(None);
- KernelThreadMechanism::stop(&thread_pcb).ok();
- }
- }
- return e;
- };
- let err_out_bus_unlock = |e: SystemError,
- desc: Arc<IrqDesc>,
- req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>,
- action_guard: SpinLockGuard<'_, InnerIrqAction>|
- -> SystemError {
- desc.chip_bus_sync_unlock();
- drop(req_mutex_guard);
- return err_out_thread(e, action_guard);
- };
- let err_out_unlock = |e: SystemError,
- desc_guard: SpinLockGuard<'_, InnerIrqDesc>,
- desc: Arc<IrqDesc>,
- req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>,
- action_guard: SpinLockGuard<'_, InnerIrqAction>|
- -> SystemError {
- drop(desc_guard);
- return err_out_bus_unlock(e, desc, req_mutex_guard, action_guard);
- };
- let err_out_mismatch = |old_action_guard: SpinLockGuard<'_, InnerIrqAction>,
- desc_guard: SpinLockGuard<'_, InnerIrqDesc>,
- action_guard: SpinLockGuard<'_, InnerIrqAction>,
- desc: Arc<IrqDesc>,
- req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>|
- -> SystemError {
- if !action_guard
- .flags()
- .contains(IrqHandleFlags::IRQF_PROBE_SHARED)
- {
- error!("Flags mismatch for irq {} (name: {}, flags: {:?}). old action name: {}, old flags: {:?}", irq.data(), action_guard.name(), action_guard.flags(), old_action_guard.name(), old_action_guard.flags());
- }
- return err_out_unlock(
- SystemError::EBUSY,
- desc_guard,
- desc,
- req_mutex_guard,
- action_guard,
- );
- };
-
- if Arc::ptr_eq(
- &desc.irq_data().chip_info_read_irqsave().chip(),
- &no_irq_chip(),
- ) {
- return Err(SystemError::ENOSYS);
- }
- let mut action_guard = action.inner();
- if !action_guard.flags().trigger_type_specified() {
-
- action_guard
- .flags_mut()
- .insert_trigger_type(desc.irq_data().common_data().trigger_type())
- }
- let nested = desc.nested_thread();
- if nested {
- if action_guard.thread_fn().is_none() {
- return Err(SystemError::EINVAL);
- }
- action_guard.set_handler(Some(&IrqNestedPrimaryHandler));
- } else if desc.can_thread() {
- self.setup_forced_threading(action_guard.deref_mut())?;
- }
-
- if action_guard.thread_fn().is_some() && !nested {
- self.setup_irq_thread(irq, action_guard.deref(), false)?;
- if let Some(secondary) = action_guard.secondary() {
- let secondary_guard = secondary.inner();
- if let Err(e) = self.setup_irq_thread(irq, secondary_guard.deref(), true) {
- return Err(err_out_thread(e, action_guard));
- }
- }
- }
-
-
-
-
-
-
-
- if desc
- .irq_data()
- .chip_info_read_irqsave()
- .chip()
- .flags()
- .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
- {
- *action_guard.flags_mut() &= !IrqHandleFlags::IRQF_ONESHOT;
- }
-
-
-
-
-
- let req_mutex_guard = desc.request_mutex_lock();
-
-
-
- desc.chip_bus_lock();
-
- if desc.actions().is_empty() {
- if let Err(e) = self.irq_request_resources(desc.clone()) {
- error!(
- "Failed to request resources for {} (irq {}) on irqchip {}, error {:?}",
- action_guard.name(),
- irq.data(),
- desc.irq_data().chip_info_read_irqsave().chip().name(),
- e
- );
- return Err(err_out_bus_unlock(
- e,
- desc.clone(),
- req_mutex_guard,
- action_guard,
- ));
- }
- }
- let mut desc_inner_guard: SpinLockGuard<'_, InnerIrqDesc> = desc.inner();
-
- let mut irq_shared = false;
- if !desc_inner_guard.actions().is_empty() {
-
-
-
-
- if desc_inner_guard
- .internal_state()
- .contains(IrqDescState::IRQS_NMI)
- {
- error!(
- "Invalid attempt to share NMI for {} (irq {}) on irqchip {}",
- action_guard.name(),
- irq.data(),
- desc_inner_guard
- .irq_data()
- .chip_info_read_irqsave()
- .chip()
- .name()
- );
- return Err(err_out_unlock(
- SystemError::EINVAL,
- desc_inner_guard,
- desc.clone(),
- req_mutex_guard,
- action_guard,
- ));
- }
- let irq_data = desc_inner_guard.irq_data();
- let old_trigger_type: super::irqdata::IrqLineStatus;
- let status = irq_data.common_data().status();
- if status.trigger_type_was_set() {
- old_trigger_type = status.trigger_type();
- } else {
- old_trigger_type = action_guard.flags().trigger_type();
- irq_data.common_data().set_trigger_type(old_trigger_type);
- }
- let old = &desc_inner_guard.actions()[0].clone();
- let old_guard = old.inner();
- if (!(old_guard
- .flags()
- .intersection(*action_guard.flags())
- .contains(IrqHandleFlags::IRQF_SHARED)))
- || (old_trigger_type != (action_guard.flags().trigger_type()))
- || ((old_guard.flags().bitxor(*action_guard.flags()))
- .contains(IrqHandleFlags::IRQF_ONESHOT))
- {
- debug!(
- "Flags mismatch for irq {} (name: {}, flags: {:?}). old action name: {}, old flags: {:?}",
- irq.data(),
- action_guard.name(),
- action_guard.flags(),
- old_guard.name(),
- old_guard.flags()
- );
- return Err(err_out_mismatch(
- old_guard,
- desc_inner_guard,
- action_guard,
- desc.clone(),
- req_mutex_guard,
- ));
- }
-
- if *old_guard.flags() & IrqHandleFlags::IRQF_PERCPU
- != *action_guard.flags() & IrqHandleFlags::IRQF_PERCPU
- {
- debug!(
- "Per-cpu mismatch for irq {} (name: {}, flags: {:?})",
- irq.data(),
- action_guard.name(),
- action_guard.flags()
- );
- return Err(err_out_mismatch(
- old_guard,
- desc_inner_guard,
- action_guard,
- desc.clone(),
- req_mutex_guard,
- ));
- }
- irq_shared = true;
- }
- if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) {
-
- } else if action_guard.handler().is_some_and(|h| {
- h.type_id() == (&DefaultPrimaryIrqHandler as &dyn IrqHandler).type_id()
- }) && !desc_inner_guard
- .irq_data()
- .chip_info_read_irqsave()
- .chip()
- .flags()
- .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
- {
-
-
-
-
-
-
-
- error!(
- "Requesting irq {} without a handler, and ONESHOT flags not set for irqaction: {}",
- irq.data(),
- action_guard.name()
- );
- return Err(err_out_unlock(
- SystemError::EINVAL,
- desc_inner_guard,
- desc.clone(),
- req_mutex_guard,
- action_guard,
- ));
- }
-
- if !irq_shared {
-
- if action_guard.flags().trigger_type_specified() {
- let trigger_type = action_guard.flags().trigger_type();
- if let Err(e) =
- self.do_set_irq_trigger(desc.clone(), &mut desc_inner_guard, trigger_type)
- {
- debug!(
- "Failed to set trigger type for irq {} (name: {}, flags: {:?}), error {:?}",
- irq.data(),
- action_guard.name(),
- action_guard.flags(),
- e
- );
- return Err(err_out_unlock(
- e,
- desc_inner_guard,
- desc.clone(),
- req_mutex_guard,
- action_guard,
- ));
- }
- }
- debug!("to irq_activate");
-
- if let Err(e) = self.irq_activate(&desc, &mut desc_inner_guard) {
- debug!(
- "Failed to activate irq {} (name: {}, flags: {:?}), error {:?}",
- irq.data(),
- action_guard.name(),
- action_guard.flags(),
- e
- );
- return Err(err_out_unlock(
- e,
- desc_inner_guard,
- desc.clone(),
- req_mutex_guard,
- action_guard,
- ));
- }
- *desc_inner_guard.internal_state_mut() &= !(IrqDescState::IRQS_AUTODETECT
- | IrqDescState::IRQS_SPURIOUS_DISABLED
- | IrqDescState::IRQS_ONESHOT
- | IrqDescState::IRQS_WAITING);
- desc_inner_guard
- .common_data()
- .clear_status(IrqStatus::IRQD_IRQ_INPROGRESS);
- if action_guard.flags().contains(IrqHandleFlags::IRQF_PERCPU) {
- desc_inner_guard
- .common_data()
- .insert_status(IrqStatus::IRQD_PER_CPU);
- desc_inner_guard.line_status_set_per_cpu();
- if action_guard.flags().contains(IrqHandleFlags::IRQF_NO_DEBUG) {
- desc_inner_guard.line_status_set_no_debug();
- }
- }
- if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) {
- *desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_ONESHOT;
- }
-
- if action_guard
- .flags()
- .contains(IrqHandleFlags::IRQF_NOBALANCING)
- {
- todo!("IRQF_NO_BALANCING");
- }
- if !action_guard
- .flags()
- .contains(IrqHandleFlags::IRQF_NO_AUTOEN)
- && desc_inner_guard.can_autoenable()
- {
-
- self.irq_startup(
- &desc,
- &mut desc_inner_guard,
- Self::IRQ_RESEND,
- Self::IRQ_START_COND,
- )
- .ok();
- } else {
-
-
- static mut WARNED: bool = false;
- if action_guard.flags().contains(IrqHandleFlags::IRQF_SHARED) && unsafe { !WARNED }
- {
- warn!(
- "Shared interrupt {} for {} requested but not auto enabled",
- irq.data(),
- action_guard.name()
- );
- unsafe { WARNED = true };
- }
- desc_inner_guard.set_depth(1);
- }
- } else if action_guard.flags().trigger_type_specified() {
- let new_trigger_type = action_guard.flags().trigger_type();
- let old_trigger_type = desc_inner_guard.common_data().trigger_type();
- if new_trigger_type != old_trigger_type {
- warn!("Irq {} uses trigger type: {old_trigger_type:?}, but requested trigger type: {new_trigger_type:?}.", irq.data());
- }
- }
-
- desc_inner_guard.add_action(action.clone());
-
- if irq_shared
- && desc_inner_guard
- .internal_state()
- .contains(IrqDescState::IRQS_SPURIOUS_DISABLED)
- {
- desc_inner_guard
- .internal_state_mut()
- .remove(IrqDescState::IRQS_SPURIOUS_DISABLED);
- self.do_enable_irq(desc.clone(), &mut desc_inner_guard).ok();
- }
- drop(desc_inner_guard);
- desc.chip_bus_sync_unlock();
- drop(req_mutex_guard);
- drop(action_guard);
- self.wake_up_and_wait_for_irq_thread_ready(&desc, Some(action.clone()));
- self.wake_up_and_wait_for_irq_thread_ready(&desc, action.inner().secondary());
- return Ok(());
- }
-
-
-
-
-
-
-
-
-
-
- fn wake_up_and_wait_for_irq_thread_ready(
- &self,
- desc: &Arc<IrqDesc>,
- action: Option<Arc<IrqAction>>,
- ) {
- if action.is_none() {
- return;
- }
- let action = action.unwrap();
- let action_guard = action.inner();
- if action_guard.thread().is_none() {
- return;
- }
- ProcessManager::wakeup(&action_guard.thread().unwrap()).ok();
- drop(action_guard);
- action
- .thread_completion()
- .wait_for_completion()
- .map_err(|e| {
- warn!(
- "Failed to wait for irq thread ready for {} (irq {:?}), error {:?}",
- action.inner().name(),
- desc.irq_data().irq(),
- e
- );
- })
- .ok();
- }
- pub(super) fn irq_activate_and_startup(
- &self,
- desc: &Arc<IrqDesc>,
- desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
- resend: bool,
- ) -> Result<(), SystemError> {
- debug!(
- "irq_activate_and_startup: irq: {}, name: {:?}",
- desc.irq().data(),
- desc_inner_guard.name()
- );
- self.irq_activate(desc, desc_inner_guard)?;
- self.irq_startup(desc, desc_inner_guard, resend, Self::IRQ_START_FORCE)
- }
- pub(super) fn irq_activate(
- &self,
- _desc: &Arc<IrqDesc>,
- desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
- ) -> Result<(), SystemError> {
- let irq_data = desc_inner_guard.irq_data();
- if !desc_inner_guard.common_data().status().affinity_managed() {
- return irq_domain_manager().activate_irq(irq_data, false);
- }
- return Ok(());
- }
-
- pub(super) fn irq_startup(
- &self,
- desc: &Arc<IrqDesc>,
- desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
- resend: bool,
- force: bool,
- ) -> Result<(), SystemError> {
- debug!(
- "irq_startup: irq: {}, name: {:?}",
- desc_inner_guard.irq_data().irq().data(),
- desc_inner_guard.name()
- );
- let mut ret = Ok(());
- let irq_data = desc_inner_guard.irq_data().clone();
- let affinity = desc_inner_guard.common_data().affinity();
- desc_inner_guard.set_depth(0);
- if desc_inner_guard.common_data().status().started() {
- self.irq_enable(desc_inner_guard);
- } else {
- match self.__irq_startup_managed(desc_inner_guard, &affinity, force) {
- IrqStartupResult::Normal => {
- if irq_data
- .chip_info_read_irqsave()
- .chip()
- .flags()
- .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP)
- {
- self.irq_setup_affinity(desc, desc_inner_guard).ok();
- }
- ret = self.__irq_startup(desc_inner_guard);
- if !irq_data
- .chip_info_read_irqsave()
- .chip()
- .flags()
- .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP)
- {
- self.irq_setup_affinity(desc, desc_inner_guard).ok();
- }
- }
- IrqStartupResult::Managed => {
- self.irq_do_set_affinity(&irq_data, desc_inner_guard, &affinity, false)
- .ok();
- ret = self.__irq_startup(desc_inner_guard);
- }
- IrqStartupResult::Abort => {
- desc_inner_guard
- .common_data()
- .insert_status(IrqStatus::IRQD_MANAGED_SHUTDOWN);
- return Ok(());
- }
- }
- }
- if resend {
- if let Err(e) = self.irq_check_and_resend(desc_inner_guard, false) {
- error!(
- "Failed to check and resend irq {}, error {:?}",
- irq_data.irq().data(),
- e
- );
- }
- }
- return ret;
- }
- pub fn irq_enable(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
- let common_data = desc_inner_guard.common_data();
- if !common_data.status().disabled() {
- self.unmask_irq(desc_inner_guard);
- } else {
- common_data.clear_disabled();
- let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
- if let Err(e) = chip.irq_enable(desc_inner_guard.irq_data()) {
- if e == SystemError::ENOSYS {
- self.unmask_irq(desc_inner_guard);
- }
- error!(
- "Failed to enable irq {} (name: {:?}), error {:?}",
- desc_inner_guard.irq_data().irq().data(),
- desc_inner_guard.name(),
- e
- );
- } else {
- common_data.clear_masked();
- }
- }
- }
-
-
-
-
- pub fn irq_setup_affinity(
- &self,
- _desc: &Arc<IrqDesc>,
- desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
- ) -> Result<(), SystemError> {
- let common_data = desc_inner_guard.common_data();
- if !desc_inner_guard.can_set_affinity() {
- return Ok(());
- }
- let mut to_set = IRQ_DEFAULT_AFFINITY.clone();
- if common_data.status().affinity_managed()
- || common_data.status().contains(IrqStatus::IRQD_AFFINITY_SET)
- {
-
- let irq_aff = common_data.affinity();
- if irq_aff.is_empty() {
- common_data.clear_status(IrqStatus::IRQD_AFFINITY_SET);
- } else {
- to_set = irq_aff;
- }
- }
-
- return self.irq_do_set_affinity(
- desc_inner_guard.irq_data(),
- desc_inner_guard,
- &to_set,
- false,
- );
- }
- #[allow(dead_code)]
- pub fn irq_set_affinity(
- &self,
- irq_data: &Arc<IrqData>,
- desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
- cpumask: &CpuMask,
- ) -> Result<(), SystemError> {
- return self.irq_do_set_affinity(irq_data, desc_inner_guard, cpumask, false);
- }
- fn irq_do_set_affinity(
- &self,
- irq_data: &Arc<IrqData>,
- desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
- cpumask: &CpuMask,
- force: bool,
- ) -> Result<(), SystemError> {
- let chip = irq_data.chip_info_read_irqsave().chip();
- if !chip.can_set_affinity() {
- return Err(SystemError::EINVAL);
- }
-
- let common_data = desc_inner_guard.common_data();
- let r = if force || !cpumask.is_empty() {
- chip.irq_set_affinity(irq_data, cpumask, force)
- } else {
- return Err(SystemError::EINVAL);
- };
- let mut ret = Ok(());
- if let Ok(rs) = r {
- match rs {
- IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => {
- common_data.set_affinity(cpumask.clone());
- }
- IrqChipSetMaskResult::NoChange => {
-
-
- }
- }
- } else {
- ret = Err(r.unwrap_err());
- }
- return ret;
- }
- fn __irq_startup(
- &self,
- desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
- ) -> Result<(), SystemError> {
- let common_data = desc_inner_guard.common_data();
- if let Err(e) = desc_inner_guard
- .irq_data()
- .chip_info_read_irqsave()
- .chip()
- .irq_startup(desc_inner_guard.irq_data())
- {
- if e == SystemError::ENOSYS {
- self.irq_enable(desc_inner_guard);
- } else {
- return Err(e);
- }
- } else {
- common_data.clear_disabled();
- common_data.clear_masked();
- }
- common_data.set_started();
- return Ok(());
- }
- fn __irq_startup_managed(
- &self,
- desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
- _affinity: &CpuMask,
- _force: bool,
- ) -> IrqStartupResult {
- let irq_data = desc_inner_guard.irq_data();
- let common_data = desc_inner_guard.common_data();
- if !common_data.status().affinity_managed() {
- return IrqStartupResult::Normal;
- }
- common_data.clear_managed_shutdown();
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- let r = irq_domain_manager().activate_irq(irq_data, false);
- if r.is_err() {
- return IrqStartupResult::Abort;
- }
- return IrqStartupResult::Managed;
- }
- pub fn do_enable_irq(
- &self,
- _desc: Arc<IrqDesc>,
- _desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
- ) -> Result<(), SystemError> {
-
- todo!("do_enable_irq")
- }
- #[inline(never)]
- pub fn do_set_irq_trigger(
- &self,
- _desc: Arc<IrqDesc>,
- desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
- mut trigger_type: IrqLineStatus,
- ) -> Result<(), SystemError> {
- let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
- let mut to_unmask = false;
- if !chip.can_set_flow_type() {
-
-
-
-
-
- return Ok(());
- }
- if chip.flags().contains(IrqChipFlags::IRQCHIP_SET_TYPE_MASKED) {
- if !desc_inner_guard.common_data().status().masked() {
- self.mask_irq(desc_inner_guard.irq_data());
- }
- if !desc_inner_guard.common_data().status().disabled() {
- to_unmask = true;
- }
- }
- trigger_type &= IrqLineStatus::IRQ_TYPE_SENSE_MASK;
- let r = chip.irq_set_type(desc_inner_guard.irq_data(), trigger_type);
- let ret;
- if let Ok(rs) = r {
- match rs {
- IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => {
- let common_data = desc_inner_guard.common_data();
- common_data.clear_status(IrqStatus::IRQD_TRIGGER_MASK);
- let mut irqstatus = IrqStatus::empty();
- irqstatus.set_trigger_type(trigger_type);
- common_data.insert_status(irqstatus);
- }
- IrqChipSetMaskResult::NoChange => {
- let flags = desc_inner_guard.common_data().trigger_type();
- desc_inner_guard.set_trigger_type(flags);
- desc_inner_guard
- .common_data()
- .clear_status(IrqStatus::IRQD_LEVEL);
- desc_inner_guard.clear_level();
- if !(flags & IrqLineStatus::IRQ_TYPE_LEVEL_MASK).is_empty() {
- desc_inner_guard.set_level();
- desc_inner_guard
- .common_data()
- .insert_status(IrqStatus::IRQD_LEVEL);
- }
- }
- }
- ret = Ok(());
- } else {
- error!(
- "Failed to set irq {} trigger type to {:?} on irqchip {}, error {:?}",
- desc_inner_guard.irq_data().irq().data(),
- trigger_type,
- chip.name(),
- r
- );
- ret = Err(r.unwrap_err());
- }
- if to_unmask {
- self.unmask_irq(desc_inner_guard);
- }
- return ret;
- }
- fn irq_request_resources(&self, desc: Arc<IrqDesc>) -> Result<(), SystemError> {
- let irq_data = desc.irq_data();
- let irq_chip = irq_data.chip_info_read_irqsave().chip();
- irq_chip.irq_request_resources(&irq_data)
- }
-
- fn setup_irq_thread(
- &self,
- _irq: IrqNumber,
- _action: &InnerIrqAction,
- _secondary: bool,
- ) -> Result<(), SystemError> {
-
-
-
- todo!("setup_irq_thread")
- }
- fn setup_forced_threading(&self, _action: &mut InnerIrqAction) -> Result<(), SystemError> {
-
- return Ok(());
- }
- pub fn irq_clear_status_flags(
- &self,
- irq: IrqNumber,
- status: IrqLineStatus,
- ) -> Result<(), SystemError> {
- let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
- desc.modify_status(status, IrqLineStatus::empty());
- return Ok(());
- }
-
- pub(super) fn mask_irq(&self, irq_data: &Arc<IrqData>) {
- if irq_data.common_data().status().masked() {
- return;
- }
- let chip = irq_data.chip_info_read_irqsave().chip();
- let r = chip.irq_mask(irq_data);
- if r.is_ok() {
- irq_data.common_data().set_masked();
- }
- }
-
- pub(super) fn unmask_irq(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
- if !desc_inner_guard.common_data().status().masked() {
- return;
- }
- let r = desc_inner_guard
- .irq_data()
- .chip_info_read_irqsave()
- .chip()
- .irq_unmask(desc_inner_guard.irq_data());
- if let Err(e) = r {
- if e != SystemError::ENOSYS {
- error!(
- "Failed to unmask irq {} on irqchip {}, error {:?}",
- desc_inner_guard.irq_data().irq().data(),
- desc_inner_guard
- .irq_data()
- .chip_info_read_irqsave()
- .chip()
- .name(),
- e
- );
- }
- } else {
- desc_inner_guard
- .common_data()
- .clear_status(IrqStatus::IRQD_IRQ_MASKED);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- pub fn free_irq(&self, _irq: IrqNumber, _dev_id: Option<Arc<DeviceId>>) {
- warn!("Unimplemented free_irq");
- }
- }
- enum IrqStartupResult {
- Normal,
- Managed,
- Abort,
- }
- #[derive(Debug)]
- struct DefaultPrimaryIrqHandler;
- impl IrqHandler for DefaultPrimaryIrqHandler {
- fn handle(
- &self,
- _irq: IrqNumber,
- _static_data: Option<&dyn IrqHandlerData>,
- _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
- ) -> Result<IrqReturn, SystemError> {
- return Ok(IrqReturn::WakeThread);
- }
- }
- #[derive(Debug)]
- struct IrqNestedPrimaryHandler;
- impl IrqHandler for IrqNestedPrimaryHandler {
- fn handle(
- &self,
- irq: IrqNumber,
- _static_data: Option<&dyn IrqHandlerData>,
- _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
- ) -> Result<IrqReturn, SystemError> {
- warn!("Primary handler called for nested irq {}", irq.data());
- return Ok(IrqReturn::NotHandled);
- }
- }
|