1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
// SPDX-License-Identifier: GPL-2.0
//! Nova Core GPU Driver
use kernel::{
debugfs,
driver::Registration,
pci,
prelude::*,
InPlaceModule, //
};
#[macro_use]
mod bitfield;
mod driver;
mod falcon;
mod fb;
mod firmware;
mod gfw;
mod gpu;
mod gsp;
#[macro_use]
mod num;
mod regs;
mod sbuffer;
mod vbios;
pub(crate) const MODULE_NAME: &core::ffi::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
// TODO: Move this into per-module data once that exists.
static mut DEBUGFS_ROOT: Option<debugfs::Dir> = None;
/// Guard that clears `DEBUGFS_ROOT` when dropped.
struct DebugfsRootGuard;
impl Drop for DebugfsRootGuard {
fn drop(&mut self) {
// SAFETY: This guard is dropped after `_driver` (due to field order),
// so the driver is unregistered and no probe() can be running.
unsafe { DEBUGFS_ROOT = None };
}
}
#[pin_data]
struct NovaCoreModule {
// Fields are dropped in declaration order, so `_driver` is dropped first,
// then `_debugfs_guard` clears `DEBUGFS_ROOT`.
#[pin]
_driver: Registration<pci::Adapter<driver::NovaCore>>,
_debugfs_guard: DebugfsRootGuard,
}
impl InPlaceModule for NovaCoreModule {
fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
let dir = debugfs::Dir::new(kernel::c_str!("nova_core"));
// SAFETY: We are the only driver code running during init, so there
// cannot be any concurrent access to `DEBUGFS_ROOT`.
unsafe { DEBUGFS_ROOT = Some(dir) };
try_pin_init!(Self {
_driver <- Registration::new(MODULE_NAME, module),
_debugfs_guard: DebugfsRootGuard,
})
}
}
module! {
type: NovaCoreModule,
name: "NovaCore",
authors: ["Danilo Krummrich"],
description: "Nova Core GPU driver",
license: "GPL v2",
firmware: [],
}
kernel::module_firmware!(firmware::ModInfoBuilder);
|