Path: blob/main/devices/src/usb/xhci/intr_resample_handler.rs
5394 views
// Copyright 2019 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34use std::sync::Arc;56use anyhow::Context;7use base::debug;8use base::error;9use base::Event;10use base::EventType;11use sync::Mutex;1213use super::interrupter::Interrupter;14use crate::utils::EventHandler;15use crate::utils::EventLoop;1617/// Interrupt Resample handler handles resample event. It will reassert interrupt if needed.18pub struct IntrResampleHandler {19interrupter: Arc<Mutex<Interrupter>>,20resample_evt: Event,21}2223impl IntrResampleHandler {24/// Start resample handler.25pub fn start(26event_loop: &EventLoop,27interrupter: Arc<Mutex<Interrupter>>,28resample_evt: Event,29) -> Option<Arc<IntrResampleHandler>> {30let handler = Arc::new(IntrResampleHandler {31interrupter,32resample_evt,33});34let tmp_handler: Arc<dyn EventHandler> = handler.clone();35if let Err(e) = event_loop.add_event(36&handler.resample_evt,37EventType::Read,38Arc::downgrade(&tmp_handler),39) {40error!("cannot add intr resample handler to event loop: {}", e);41return None;42}43Some(handler)44}45}4647impl EventHandler for IntrResampleHandler {48fn on_event(&self) -> anyhow::Result<()> {49self.resample_evt50.wait()51.context("cannot read resample evt")?;52let mut interrupter = self.interrupter.lock();53if !interrupter.event_ring_is_empty() {54debug!("irq resample re-assert irq event");55// There could be a race condition. When we get resample_evt and other56// component is sending interrupt at the same time.57// This might result in one more interrupt than we want. It's handled by58// kernel correctly.59interrupter.interrupt().context("cannot send interrupt")?;60}61Ok(())62}63}646566