diff --git a/data/com.system76.PowerDaemon.xml b/data/com.system76.PowerDaemon.xml
index b691a0c2..557a91ca 100644
--- a/data/com.system76.PowerDaemon.xml
+++ b/data/com.system76.PowerDaemon.xml
@@ -28,30 +28,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/args.rs b/src/args.rs
index d663fa76..ade9c886 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -4,34 +4,6 @@
use clap::{builder::PossibleValuesParser, Parser};
-#[derive(Parser)]
-#[clap(
- about = "Query or set the graphics mode",
- long_about = "Query or set the graphics mode.\n\n - If an argument is not provided, the \
- graphics profile will be queried\n - Otherwise, that profile will be set, if it \
- is a valid profile\n\nA reboot is required after switching modes."
-)]
-pub enum GraphicsArgs {
- #[clap(about = "Like integrated, but the dGPU is available for compute")]
- Compute,
- #[clap(about = "Set the graphics mode to Hybrid (PRIME)")]
- Hybrid,
- #[clap(about = "Set the graphics mode to integrated")]
- Integrated,
- #[clap(about = "Set the graphics mode to NVIDIA")]
- Nvidia,
- #[clap(about = "Determines if the system has switchable graphics")]
- Switchable,
- #[clap(about = "Query or set the discrete graphics power state")]
- Power {
- #[clap(help = "Set whether discrete graphics should be on or off")]
- #[arg(
- value_parser = PossibleValuesParser::new(["auto", "off", "on"])
- )]
- state: Option,
- },
-}
-
#[derive(Parser)]
#[clap(
name = "system76-power",
@@ -78,10 +50,6 @@ pub enum Args {
)]
profile: Option,
},
- Graphics {
- #[clap(subcommand)]
- cmd: Option,
- },
#[clap(
about = "Set thresholds for battery charging",
// Autogenerated usage seemed to have issues
diff --git a/src/client.rs b/src/client.rs
index 48f393e6..63da5cd1 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: GPL-3.0-only
-use crate::args::{Args, GraphicsArgs};
+use crate::args::Args;
use anyhow::Context;
use intel_pstate::PState;
use std::io;
@@ -75,53 +75,6 @@ Battery power profile is not supported on desktop computers.
Some("performance") => client.performance().await.map_err(zbus_error),
_ => profile(&mut client).await.context("failed to get power profile"),
},
- Args::Graphics { cmd } => {
- if !client.get_switchable().await? {
- return Err(anyhow::anyhow!(
- r#"
-Graphics switching is not supported on this device, because
-this device is either a desktop or doesn't have both an iGPU and dGPU.
-"#,
- ));
- }
-
- match cmd.as_ref() {
- Some(GraphicsArgs::Compute) => {
- client.set_graphics("compute").await.map_err(zbus_error)
- }
- Some(GraphicsArgs::Hybrid) => {
- client.set_graphics("hybrid").await.map_err(zbus_error)
- }
- Some(GraphicsArgs::Integrated) => {
- client.set_graphics("integrated").await.map_err(zbus_error)
- }
- Some(GraphicsArgs::Nvidia) => {
- client.set_graphics("nvidia").await.map_err(zbus_error)
- }
- Some(GraphicsArgs::Switchable) => client
- .get_switchable()
- .await
- .map_err(zbus_error)
- .map(|b| println!("{}", if b { "switchable" } else { "not switchable" })),
- Some(GraphicsArgs::Power { state }) => match state.as_deref() {
- Some("auto") => client.auto_graphics_power().await.map_err(zbus_error),
- Some("off") => client.set_graphics_power(false).await.map_err(zbus_error),
- Some("on") => client.set_graphics_power(true).await.map_err(zbus_error),
- _ => {
- if client.get_graphics_power().await.map_err(zbus_error)? {
- println!("on (discrete)");
- } else {
- println!("off (discrete)");
- }
- Ok(())
- }
- },
- None => {
- println!("{}", client.get_graphics().await.map_err(zbus_error)?);
- Ok(())
- }
- }
- }
Args::ChargeThresholds { profile, list_profiles, thresholds } => {
if client.get_desktop().await.map_err(zbus_error)? {
return Err(anyhow::anyhow!(
diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs
index 6cfed39e..2a90f233 100644
--- a/src/daemon/mod.rs
+++ b/src/daemon/mod.rs
@@ -25,7 +25,7 @@ use crate::{
charge_thresholds::{get_charge_profiles, get_charge_thresholds, set_charge_thresholds},
errors::ProfileError,
fan::FanDaemon,
- graphics::{Graphics, GraphicsMode},
+ graphics::Graphics,
hid_backlight,
hotplug::{mux, Detect, HotPlugDetect},
kernel_parameters::{KernelParameter, NmiWatchdog},
@@ -238,60 +238,11 @@ impl System76Power {
.map_err(zbus_error_from_display)
}
- #[dbus_interface(out_args("vendor"))]
- async fn get_default_graphics(&self) -> zbus::fdo::Result {
- self.0
- .lock()
- .await
- .graphics
- .get_default_graphics()
- .map_err(zbus_error_from_display)
- .map(|mode| <&'static str>::from(mode).to_owned())
- }
-
- #[dbus_interface(out_args("vendor"))]
- async fn get_graphics(&self) -> zbus::fdo::Result {
- self.0
- .lock()
- .await
- .graphics
- .get_vendor()
- .map_err(zbus_error_from_display)
- .map(|mode| <&'static str>::from(mode).to_owned())
- }
-
- async fn set_graphics(&mut self, vendor: &str) -> zbus::fdo::Result<()> {
- self.0
- .lock()
- .await
- .graphics
- .set_vendor(GraphicsMode::from(vendor))
- .map_err(zbus_error_from_display)
- }
-
#[dbus_interface(out_args("desktop"))]
async fn get_desktop(&mut self) -> zbus::fdo::Result {
Ok(self.0.lock().await.graphics.is_desktop())
}
- #[dbus_interface(out_args("switchable"))]
- async fn get_switchable(&mut self) -> zbus::fdo::Result {
- Ok(self.0.lock().await.graphics.can_switch())
- }
-
- #[dbus_interface(out_args("power"))]
- async fn get_graphics_power(&mut self) -> zbus::fdo::Result {
- self.0.lock().await.graphics.get_power().map_err(zbus_error_from_display)
- }
-
- async fn set_graphics_power(&mut self, power: bool) -> zbus::fdo::Result<()> {
- self.0.lock().await.graphics.set_power(power).map_err(zbus_error_from_display)
- }
-
- async fn auto_graphics_power(&mut self) -> zbus::fdo::Result<()> {
- self.0.lock().await.graphics.auto_power().map_err(zbus_error_from_display)
- }
-
#[dbus_interface(out_args("start", "end"))]
async fn get_charge_thresholds(&mut self) -> zbus::fdo::Result<(u8, u8)> {
get_charge_thresholds().map_err(zbus_error_from_display)
@@ -532,13 +483,6 @@ pub async fn daemon() -> anyhow::Result<()> {
let daemon = Arc::new(Mutex::new(daemon));
let mut system76_daemon = System76Power(daemon.clone());
- match system76_daemon.auto_graphics_power().await {
- Ok(()) => (),
- Err(err) => {
- log::warn!("Failed to set automatic graphics power: {}", err);
- }
- }
-
let vendor = fs::read_to_string("/sys/class/dmi/id/sys_vendor")?;
let model = fs::read_to_string("/sys/class/dmi/id/product_version")?;
match runtime_pm_quirks(&vendor, &model) {
diff --git a/src/graphics.rs b/src/graphics.rs
index b473fcfd..b631c3da 100644
--- a/src/graphics.rs
+++ b/src/graphics.rs
@@ -2,76 +2,11 @@
//
// SPDX-License-Identifier: GPL-3.0-only
-use crate::{module::Module, pci::PciBus};
+use crate::pci::PciBus;
use serde::{Deserialize, Serialize};
-use std::{
- fs,
- io::{self, Write},
- path,
- process::{self, ExitStatus},
-};
+use std::{fs, io, process::ExitStatus};
use sysfs_class::{PciDevice, SysClass};
-const MODPROBE_PATH: &str = "/etc/modprobe.d/system76-power.conf";
-
-static MODPROBE_NVIDIA: &[u8] = br"# Automatically generated by system76-power
-options nvidia-drm modeset=1
-";
-
-static MODPROBE_HYBRID: &[u8] = br"# Automatically generated by system76-power
-blacklist i2c_nvidia_gpu
-alias i2c_nvidia_gpu off
-options nvidia-drm modeset=1
-";
-
-static MODPROBE_COMPUTE: &[u8] = br"# Automatically generated by system76-power
-blacklist i2c_nvidia_gpu
-blacklist nvidia-drm
-blacklist nvidia-modeset
-alias i2c_nvidia_gpu off
-alias nvidia-drm off
-alias nvidia-modeset off
-";
-
-static MODPROBE_INTEGRATED: &[u8] = br"# Automatically generated by system76-power
-blacklist i2c_nvidia_gpu
-blacklist nouveau
-blacklist nvidia
-blacklist nvidia-drm
-blacklist nvidia-modeset
-alias i2c_nvidia_gpu off
-alias nouveau off
-alias nvidia off
-alias nvidia-drm off
-alias nvidia-modeset off
-";
-
-// Systems that cannot use other sleep options
-static SYSTEM_SLEEP_EMPTY: &[u8] = b"";
-
-// Systems using S0ix must enable S0ix-based power management.
-static SYSTEM_SLEEP_S0IX: &[u8] = br"# Preserve video memory through suspend
-options nvidia NVreg_EnableS0ixPowerManagement=1
-";
-
-// Systems using S3 had suspend issues with WebRender.
-static SYSTEM_SLEEP_S3: &[u8] = br"# Preserve video memory through suspend
-options nvidia NVreg_PreserveVideoMemoryAllocations=1
-";
-
-// The use of hybrid or discrete is determined by the "PrimaryGPU" option.
-static XORG_CONF_DISCRETE: &[u8] = br#"# Automatically generated by system76-power
-Section "OutputClass"
- Identifier "NVIDIA"
- MatchDriver "nvidia-drm"
- Driver "nvidia"
- Option "PrimaryGPU" "Yes"
- ModulePath "/lib/x86_64-linux-gnu/nvidia/xorg"
-EndSection
-"#;
-
-const PRIME_DISCRETE_PATH: &str = "/etc/prime-discrete";
-
const EXTERNAL_DISPLAY_REQUIRES_NVIDIA: &[&str] = &[
"addw1",
"addw2",
@@ -105,8 +40,6 @@ const EXTERNAL_DISPLAY_REQUIRES_NVIDIA: &[&str] = &[
"serw14",
];
-const SYSTEMCTL_CMD: &str = "systemctl";
-
#[derive(Debug, thiserror::Error)]
pub enum GraphicsDeviceError {
#[error("failed to execute {} command: {}", cmd, why)]
@@ -115,20 +48,12 @@ pub enum GraphicsDeviceError {
DeviceInUse { func: String, driver: String },
#[error("failed to probe driver features: {}", _0)]
Json(io::Error),
- #[error("failed to open system76-power modprobe file: {}", _0)]
- ModprobeFileOpen(io::Error),
- #[error("failed to write to system76-power modprobe file: {}", _0)]
- ModprobeFileWrite(io::Error),
#[error("failed to fetch list of active kernel modules: {}", _0)]
ModulesFetch(io::Error),
#[error("does not have switchable graphics")]
NotSwitchable,
#[error("PCI driver error on {}: {}", device, why)]
PciDriver { device: String, why: io::Error },
- #[error("failed to get PRIME value: {}", _0)]
- PrimeModeRead(io::Error),
- #[error("failed to set PRIME value: {}", _0)]
- PrimeModeWrite(io::Error),
#[error("failed to remove PCI device {}: {}", device, why)]
Remove { device: String, why: io::Error },
#[error("failed to rescan PCI bus: {}", _0)]
@@ -241,36 +166,6 @@ struct SupportedGpus {
chips: Vec,
}
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum GraphicsMode {
- Integrated,
- Compute,
- Hybrid,
- Discrete,
-}
-
-impl From for &'static str {
- fn from(mode: GraphicsMode) -> &'static str {
- match mode {
- GraphicsMode::Integrated => "integrated",
- GraphicsMode::Compute => "compute",
- GraphicsMode::Hybrid => "hybrid",
- GraphicsMode::Discrete => "nvidia",
- }
- }
-}
-
-impl From<&str> for GraphicsMode {
- fn from(vendor: &str) -> Self {
- match vendor {
- "nvidia" => GraphicsMode::Discrete,
- "hybrid" => GraphicsMode::Hybrid,
- "compute" => GraphicsMode::Compute,
- _ => GraphicsMode::Integrated,
- }
- }
-}
-
pub struct Graphics {
pub bus: PciBus,
pub amd: Vec,
@@ -373,306 +268,6 @@ impl Graphics {
Ok(EXTERNAL_DISPLAY_REQUIRES_NVIDIA.contains(&model.trim()))
}
- fn get_nvidia_device(id: u16) -> Result {
- let supported_gpus: Vec = fs::read_dir("/usr/share/doc")
- .map_err(|e| {
- GraphicsDeviceError::Json(io::Error::new(io::ErrorKind::InvalidData, e.to_string()))
- })?
- .filter_map(Result::ok)
- .map(|f| f.path())
- .filter(|f| f.to_str().unwrap_or_default().contains("nvidia-driver-"))
- .map(|f| f.join("supported-gpus.json"))
- .filter(|f| f.exists())
- .collect();
-
- // There should be only 1 driver version installed.
- if supported_gpus.len() != 1 {
- return Err(GraphicsDeviceError::Json(io::Error::new(
- io::ErrorKind::InvalidData,
- "NVIDIA drivers misconfigured",
- )));
- }
-
- let raw = fs::read_to_string(&supported_gpus[0]).map_err(GraphicsDeviceError::Json)?;
- let gpus: SupportedGpus = serde_json::from_str(&raw).map_err(|e| {
- GraphicsDeviceError::Json(io::Error::new(io::ErrorKind::InvalidData, e.to_string()))
- })?;
-
- // There may be multiple entries that share the same device ID.
- for dev in gpus.chips {
- let did = dev.devid.trim_start_matches("0x").trim();
- let did = u16::from_str_radix(did, 16).unwrap_or_default();
- if did == id {
- return Ok(dev);
- }
- }
-
- Err(GraphicsDeviceError::Json(io::Error::new(
- io::ErrorKind::NotFound,
- "GPU device not found",
- )))
- }
-
- fn gpu_supports_runtimepm(&self) -> Result {
- if self.nvidia.is_empty() {
- Ok(false)
- } else {
- let id = self.nvidia[0].device();
- let dev = Self::get_nvidia_device(id)?;
- log::info!("Device 0x{:04} features: {:?}", id, dev.features);
- Ok(dev.features.contains(&"runtimepm".to_string()))
- }
- }
-
- pub fn get_default_graphics(&self) -> Result {
- // Models that should default to discrete graphics only
- const DEFAULT_DISCRETE: &[&str] = &["bonw16"];
-
- self.switchable_or_fail()?;
-
- let vendor = fs::read_to_string("/sys/class/dmi/id/sys_vendor")
- .map_err(GraphicsDeviceError::SysFs)
- .map(|s| s.trim().to_string())?;
-
- let product = fs::read_to_string("/sys/class/dmi/id/product_version")
- .map_err(GraphicsDeviceError::SysFs)
- .map(|s| s.trim().to_string())?;
-
- let runtimepm = match self.gpu_supports_runtimepm() {
- Ok(ok) => ok,
- Err(err) => {
- log::warn!("could not determine GPU runtimepm support: {}", err);
- false
- }
- };
-
- // Only default to hybrid on System76 models
- if vendor != "System76" || DEFAULT_DISCRETE.contains(&product.as_str()) {
- Ok(GraphicsMode::Discrete)
- } else if runtimepm {
- Ok(GraphicsMode::Hybrid)
- } else {
- Ok(GraphicsMode::Integrated)
- }
- }
-
- fn get_prime_discrete() -> Result {
- fs::read_to_string(PRIME_DISCRETE_PATH)
- .map_err(GraphicsDeviceError::PrimeModeRead)
- .map(|mode| mode.trim().to_owned())
- }
-
- fn set_prime_discrete(mode: &str) -> Result<(), GraphicsDeviceError> {
- fs::write(PRIME_DISCRETE_PATH, mode).map_err(GraphicsDeviceError::PrimeModeWrite)
- }
-
- pub fn get_vendor(&self) -> Result {
- let modules = Module::all().map_err(GraphicsDeviceError::ModulesFetch)?;
- let vendor =
- if modules.iter().any(|module| module.name == "nouveau" || module.name == "nvidia") {
- let mode = match Self::get_prime_discrete() {
- Ok(m) => m,
- Err(_) => "nvidia".to_string(),
- };
-
- if mode == "on-demand" {
- GraphicsMode::Hybrid
- } else if mode == "off" {
- GraphicsMode::Compute
- } else {
- GraphicsMode::Discrete
- }
- } else {
- GraphicsMode::Integrated
- };
-
- Ok(vendor)
- }
-
- pub fn set_vendor(&self, vendor: GraphicsMode) -> Result<(), GraphicsDeviceError> {
- self.switchable_or_fail()?;
-
- let mode = match vendor {
- GraphicsMode::Hybrid => "on-demand\n",
- GraphicsMode::Discrete => "on\n",
- _ => "off\n",
- };
-
- let bonw15_hack = {
- let dmi_vendor = fs::read_to_string("/sys/class/dmi/id/sys_vendor").unwrap_or_default();
- let dmi_model =
- fs::read_to_string("/sys/class/dmi/id/product_version").unwrap_or_default();
- match (dmi_vendor.trim(), dmi_model.trim()) {
- ("System76", "bonw15") => true,
- ("System76", "bonw15-b") => true,
- _ => false,
- }
- };
-
- // Configure X server
- if vendor == GraphicsMode::Discrete {
- let mut file = fs::OpenOptions::new()
- .create(true)
- .truncate(true)
- .write(true)
- .open(get_xorg_conf_path())
- .map_err(GraphicsDeviceError::XserverConf)?;
-
- file.write_all(XORG_CONF_DISCRETE)
- .and_then(|()| file.sync_all())
- .map_err(GraphicsDeviceError::XserverConf)?;
- } else if path::Path::new(get_xorg_conf_path()).exists() {
- fs::remove_file(get_xorg_conf_path()).map_err(GraphicsDeviceError::XserverConf)?;
- }
-
- {
- log::info!("Creating {}", MODPROBE_PATH);
-
- let mut file = fs::OpenOptions::new()
- .create(true)
- .truncate(true)
- .write(true)
- .open(MODPROBE_PATH)
- .map_err(GraphicsDeviceError::ModprobeFileOpen)?;
-
- let text = match vendor {
- GraphicsMode::Integrated => MODPROBE_INTEGRATED,
- GraphicsMode::Compute => MODPROBE_COMPUTE,
- GraphicsMode::Hybrid => MODPROBE_HYBRID,
- GraphicsMode::Discrete => MODPROBE_NVIDIA,
- };
-
- file.write_all(text)
- .and_then(|()| file.sync_all())
- .map_err(GraphicsDeviceError::ModprobeFileWrite)?;
-
- // Power management must be configured depending on if the system
- // uses S0ix or S3 for suspend.
- if vendor != GraphicsMode::Integrated {
- // XXX: Better way to check?
- let s0ix = fs::read_to_string("/sys/power/mem_sleep")
- .unwrap_or_default()
- .contains("[s2idle]");
-
- let (sleep, action) = if bonw15_hack {
- (SYSTEM_SLEEP_EMPTY, "disable")
- } else if s0ix {
- (SYSTEM_SLEEP_S0IX, "enable")
- } else {
- (SYSTEM_SLEEP_S3, "enable")
- };
-
- // We should also check if the GPU supports Video Memory Self
- // Refresh, but that requires already being in hybrid or nvidia
- // graphics mode. In compute mode, it just reports '?'.
-
- file.write_all(sleep)
- .and_then(|()| file.sync_all())
- .map_err(GraphicsDeviceError::ModprobeFileWrite)?;
-
- for service in
- &["nvidia-hibernate.service", "nvidia-resume.service", "nvidia-suspend.service"]
- {
- let status = process::Command::new(SYSTEMCTL_CMD)
- .arg(action)
- .arg(service)
- .status()
- .map_err(|why| GraphicsDeviceError::Command { cmd: SYSTEMCTL_CMD, why })?;
-
- if !status.success() {
- // Error is ignored in case this service is removed
- log::warn!(
- "systemctl {} {}: failed with {} (not an error if service does not \
- exist!)",
- action,
- service,
- status
- );
- }
- }
- }
- }
-
- log::info!("Setting {} to {}", PRIME_DISCRETE_PATH, mode);
- Self::set_prime_discrete(mode)?;
-
- let action = if vendor == GraphicsMode::Discrete {
- log::info!("Enabling nvidia-fallback.service");
- "enable"
- } else {
- log::info!("Disabling nvidia-fallback.service");
- "disable"
- };
-
- let status = process::Command::new(SYSTEMCTL_CMD)
- .arg(action)
- .arg("nvidia-fallback.service")
- .status()
- .map_err(|why| GraphicsDeviceError::Command { cmd: SYSTEMCTL_CMD, why })?;
-
- if !status.success() {
- // Error is ignored in case this service is removed
- log::warn!(
- "systemctl: failed with {} (not an error if service does not exist!)",
- status
- );
- }
-
- log::info!("Updating initramfs");
- let (cmd, arg) = update_initramfs_cmd();
- let status = process::Command::new(cmd)
- .arg(arg)
- .status()
- .map_err(|why| GraphicsDeviceError::Command { cmd, why })?;
-
- if !status.success() {
- return Err(GraphicsDeviceError::UpdateInitramfs(status));
- }
-
- Ok(())
- }
-
- pub fn get_power(&self) -> Result {
- self.switchable_or_fail()?;
- Ok(self.nvidia.iter().any(GraphicsDevice::exists))
- }
-
- pub fn set_power(&self, power: bool) -> Result<(), GraphicsDeviceError> {
- self.switchable_or_fail()?;
-
- if power {
- log::info!("Enabling graphics power");
- self.bus.rescan().map_err(GraphicsDeviceError::Rescan)?;
-
- sysfs_power_control(self.nvidia[0].id.clone(), self.get_vendor()?);
- } else {
- log::info!("Disabling graphics power");
-
- // TODO: Don't allow turning off power if nvidia_drm modeset is enabled
-
- unsafe {
- // Unbind NVIDIA graphics devices and their functions
- let unbinds = self.nvidia.iter().map(|dev| dev.unbind());
-
- // Remove NVIDIA graphics devices and their functions
- let removes = self.nvidia.iter().map(|dev| dev.remove());
-
- unbinds.chain(removes).collect::>()?;
- }
- }
-
- Ok(())
- }
-
- pub fn auto_power(&self) -> Result<(), GraphicsDeviceError> {
- // Only disable power if in integrated mode and the device does not
- // support runtime power management.
- let vendor = self.get_vendor()?;
- let power = vendor != GraphicsMode::Integrated || self.gpu_supports_runtimepm()?;
-
- self.set_power(power)
- }
-
fn switchable_or_fail(&self) -> Result<(), GraphicsDeviceError> {
if self.can_switch() {
Ok(())
@@ -681,45 +276,3 @@ impl Graphics {
}
}
}
-
-fn update_initramfs_cmd() -> (&'static str, &'static str) {
- if path::Path::new("/usr/bin/dracut").exists() {
- ("dracut", "--force")
- } else {
- ("update-initramfs", "-u")
- }
-}
-
-fn get_xorg_conf_path() -> &'static str {
- if path::Path::new("/etc/X11/xorg.conf.d").exists() {
- "/etc/X11/xorg.conf.d/11-nvidia-discrete.conf"
- } else {
- "/usr/share/X11/xorg.conf.d/11-nvidia-discrete.conf"
- }
-}
-
-// HACK
-// Normally, power/control would be set to "auto" by a udev rule in nvidia-drivers, but because
-// of a bug we cannot enable automatic power management too early after turning on the GPU.
-// Otherwise it will turn off before the NVIDIA driver finishes initializing, leaving the
-// system in an invalid state that will eventually lock up. So defer setting power management
-// using a thread.
-//
-// Ref: pop-os/nvidia-graphics-drivers@f9815ed603bd
-// Ref: system76/firmware-open#160
-fn sysfs_power_control(pciid: String, mode: GraphicsMode) {
- std::thread::spawn(move || {
- std::thread::sleep(std::time::Duration::from_millis(5000));
-
- let pm = if mode == GraphicsMode::Discrete { "on\n" } else { "auto\n" };
- log::info!("Setting power management to {}", pm);
-
- let control = format!("/sys/bus/pci/devices/{}/power/control", pciid);
- let file = fs::OpenOptions::new().create(false).truncate(false).write(true).open(control);
-
- #[allow(unused_must_use)]
- if let Ok(mut file) = file {
- file.write_all(pm.as_bytes()).and_then(|()| file.sync_all());
- }
- });
-}
diff --git a/src/lib.rs b/src/lib.rs
index 13b5624a..815bd652 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -26,7 +26,6 @@ pub mod hotplug;
pub mod kernel_parameters;
pub mod logging;
pub mod modprobe;
-pub mod module;
pub mod pci;
pub mod radeon;
pub mod runtime_pm;
diff --git a/src/module.rs b/src/module.rs
deleted file mode 100644
index c0a27061..00000000
--- a/src/module.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018-2021 System76
-//
-// SPDX-License-Identifier: GPL-3.0-only
-
-use std::{fs::read_to_string, io};
-
-pub struct Module {
- pub name: String,
-}
-
-impl Module {
- pub fn all() -> io::Result> {
- read_to_string("/proc/modules")?.lines().map(parse).collect()
- }
-}
-
-fn parse(line: &str) -> io::Result {
- let name = line
- .split(' ')
- .next()
- .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "module name not found"))?
- .to_string();
-
- Ok(Module { name })
-}