Backported support for power_supply class

(add-power-supply-class-support patch)
- Added support for POWER_NOW readings
  (power-supply-add-power-now-support patch)
  Resolves: rhbz#796068
This commit is contained in:
Jaroslav Škarvada 2012-02-24 15:05:04 +01:00
parent 5650fd5d1c
commit 9a7a54913e
3 changed files with 417 additions and 1 deletions

View File

@ -0,0 +1,336 @@
commit a1c28f69847480cc54f36046e96e93a02a2c661d
Author: John Mathew <johnx.mathew@intel.com>
Date: Thu Jun 30 09:58:26 2011 +0300
measurement: add support for universal power supply monitor
This patch enables powertop to display power estimates on devices that
implement power_supply class and donot have acpi battery interface.
First the acpi/battery interface is checked and if it is not accesible
the sysfs/power_class interface is used
diff --git a/Makefile b/Makefile
index b0b6cb7..f0ebf21 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ OBJS += perf/perf.o perf/perf_bundle.o
OBJS += process/process.o process/do_process.o process/interrupt.o process/timer.o process/work.o process/powerconsumer.o process/device.o
DEVS += devices/device.o devices/backlight.o devices/usb.o devices/ahci.o devices/alsa.o devices/rfkill.o devices/i915-gpu.o devices/thinkpad-fan.o devices/network.o devices/thinkpad-light.o
DEVS += devices/runtime_pm.o
-DEVS += measurement/measurement.o measurement/acpi.o measurement/extech.o
+DEVS += measurement/measurement.o measurement/acpi.o measurement/extech.o measurement/power_supply.o
OBJS += $(DEVS)
OBJS += parameters/parameters.o parameters/learn.o parameters/persistent.o
OBJS += calibrate/calibrate.o
diff --git a/measurement/measurement.cpp b/measurement/measurement.cpp
index 3dbaab9..0d679f7 100644
--- a/measurement/measurement.cpp
+++ b/measurement/measurement.cpp
@@ -25,11 +25,14 @@
#include "measurement.h"
#include "acpi.h"
#include "extech.h"
+#include "power_supply.h"
#include "../parameters/parameters.h"
#include "../lib.h"
#include <sys/types.h>
#include <dirent.h>
+#include <stdio.h>
+#include <fstream>
double min_power = 50000.0;
@@ -111,16 +114,45 @@ void power_meters_callback(const char *d_name)
power_meters.push_back(meter);
}
+void power_supply_callback(const char *d_name)
+{
+ char filename[4096];
+ char line[4096];
+ ifstream file;
+ bool discharging = false;
+
+ sprintf(filename, "/sys/class/power_supply/%s/uevent", d_name);
+ file.open(filename, ios::in);
+ if (!file)
+ return;
+
+ while (file) {
+ file.getline(line, 4096);
+
+ if (strstr(line, "POWER_SUPPLY_STATUS") && strstr(line, "POWER_SUPPLY_STATUS"))
+ discharging = true;
+ }
+ file.close();
+
+ if (!discharging)
+ return;
+
+ class power_supply *power;
+ power = new(std::nothrow) class power_supply(d_name);
+ if (power)
+ power_meters.push_back(power);
+}
+
void detect_power_meters(void)
{
- process_directory("/proc/acpi/battery", power_meters_callback);
+ if (access("/sys/class/power_supply", R_OK ) == 0)
+ process_directory("/sys/class/power_supply", power_supply_callback);
+ else if (access("/proc/acpi/battery", R_OK ) == 0)
+ process_directory("/proc/acpi/battery", power_meters_callback);
}
void extech_power_meter(const char *devnode)
{
- DIR *dir;
- struct dirent *entry;
-
class extech_power_meter *meter;
meter = new class extech_power_meter(devnode);
diff --git a/measurement/power_supply.cpp b/measurement/power_supply.cpp
new file mode 100755
index 0000000..b4fe3af
--- /dev/null
+++ b/measurement/power_supply.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2011, Intel Corporation
+ *
+ * This file is part of PowerTOP
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc,
+ * 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ * or just google for it.
+ *
+ * Authors:
+ * John Mathew <johnx.mathew@intel.com>
+ */
+#include "measurement.h"
+#include "power_supply.h"
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace std;
+
+power_supply::power_supply(const char *supply_name)
+{
+ rate = 0.0;
+ capacity = 0.0;
+ voltage = 0.0;
+ strncpy(battery_name, supply_name, sizeof(battery_name));
+}
+
+/*
+POWER_SUPPLY_NAME=msic-battery
+POWER_SUPPLY_STATUS=Discharging
+POWER_SUPPLY_HEALTH=Cold
+POWER_SUPPLY_PRESENT=1
+POWER_SUPPLY_TECHNOLOGY=Li-ion
+POWER_SUPPLY_VOLTAGE_MAX_DESIGN=4200000
+POWER_SUPPLY_VOLTAGE_NOW=4119000
+POWER_SUPPLY_CURRENT_NOW=-290000
+POWER_SUPPLY_CHARGE_NOW=1503000
+POWER_SUPPLY_CHARGE_COUNTER=-254923
+POWER_SUPPLY_CHARGE_FULL_DESIGN=1500000
+POWER_SUPPLY_CHARGE_FULL=1500000
+POWER_SUPPLY_CHARGE_AVG=32762000
+POWER_SUPPLY_ENERGY_FULL=6300000
+POWER_SUPPLY_ENERGY_NOW=6235000
+POWER_SUPPLY_CAPACITY_LEVEL=Full
+POWER_SUPPLY_CAPACITY=100
+POWER_SUPPLY_TEMP=-340
+POWER_SUPPLY_MODEL_NAME=CDK0
+POWER_SUPPLY_MANUFACTURER=IN
+
+Quoting include/linux/power_supply.h:
+
+All voltages, currents, charges, energies, time and temperatures in µV,
+µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise
+stated. It's driver's job to convert its raw values to units in which
+this class operates.
+*/
+
+void power_supply::measure(void)
+{
+ char filename[4096];
+ char line[4096];
+ ifstream file;
+
+ double _rate = 0;
+ double _capacity = 0;
+ double _voltage = 0;
+
+ char rate_units[16];
+ char capacity_units[16];
+ char voltage_units[16];
+
+ rate_units[0] = 0;
+ capacity_units[0] = 0;
+ voltage_units[0] = 0;
+
+ rate = 0;
+ voltage = 0;
+ capacity = 0;
+
+ sprintf(filename, "/sys/class/power_supply/%s/uevent", battery_name);
+
+ file.open(filename, ios::in);
+ if (!file)
+ return;
+
+ while (file) {
+ char *c;
+ file.getline(line, 4096);
+
+ if (strstr(line, "PRESENT")) {
+ c = strchr(line, '=');
+ c++;
+ if(*c == '0'){
+ printf ("Battery not present");
+ return;
+ }
+ }
+ if (strstr(line, "CURRENT_NOW")) {
+ c = strchr(line, '=');
+ c++;
+ if(*c == '-') c++; // ignoring the negative sign
+ _rate = strtoull(c, NULL, 10);
+ if (c) {
+ //printf ("CURRENT: %f. \n",_rate);
+ } else {
+ _rate = 0;
+ }
+ }
+ if (strstr(line, "CAPACITY=")) {
+ c = strchr(line, '=');
+ c++;
+ _capacity = strtoull(c, NULL, 10);
+ if (c) {
+ //printf ("CAPACITY: %f. \n",_capacity);
+ } else {
+ _capacity = 0;
+ }
+ }
+ if (strstr(line, "VOLTAGE_NOW")) {
+ c = strchr(line, '=');
+ c++;
+ while (*c == ' ') c++;
+ _voltage = strtoull(c, NULL, 10);
+ if (c) {
+ //printf ("VOLTAGE_NOW: %f. \n",_voltage);
+ } else {
+ _voltage = 0;
+ }
+ }
+ }
+ file.close();
+
+ if(_voltage) {
+ _voltage = _voltage / 1000.0;
+ voltage = _voltage;
+ } else {
+ voltage = 0.0;
+ }
+
+ if(_rate) {
+ _rate = _rate / 1000.0;
+ _rate = _rate * _voltage;
+ rate = _rate;
+ } else {
+ rate = 0.0;
+ }
+
+ if(_capacity)
+ capacity = _capacity;
+ else
+ capacity = 0.0;
+}
+
+
+void power_supply::end_measurement(void)
+{
+ measure();
+}
+
+void power_supply::start_measurement(void)
+{
+ /* ACPI battery state is a lagging indication, lets only measure at the end */
+}
+
+
+double power_supply::joules_consumed(void)
+{
+ return rate;
+}
diff --git a/measurement/power_supply.h b/measurement/power_supply.h
new file mode 100755
index 0000000..5ad776e
--- /dev/null
+++ b/measurement/power_supply.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011, Intel Corporation
+ *
+ * This file is part of PowerTOP
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc,
+ * 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ * or just google for it.
+ *
+ * Authors:
+ * John Mathew <johnx.mathew@intel.com>
+ */
+#ifndef __INCLUDE_GUARD_POWER_SUPPLY_H
+#define __INCLUDE_GUARD_POWER_SUPPLY_H
+
+#include "measurement.h"
+
+class power_supply:public power_meter {
+ char battery_name[256];
+
+ double capacity;
+ double rate;
+ double voltage;
+ void measure(void);
+public:
+ power_supply(const char *_battery_name);
+ virtual void start_measurement(void);
+ virtual void end_measurement(void);
+
+ virtual double joules_consumed(void);
+ virtual double dev_capacity(void) { return capacity; };
+};
+
+#endif

View File

@ -0,0 +1,69 @@
From 0dce3803eff9c3919c025ba5534bacdfda471182 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
Date: Fri, 24 Feb 2012 13:55:44 +0100
Subject: [PATCH] power_supply: Add support for POWER_NOW readings
---
measurement/power_supply.cpp | 30 ++++++++++++++++++++++--------
1 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/measurement/power_supply.cpp b/measurement/power_supply.cpp
index b4fe3af..13d8d34 100755
--- a/measurement/power_supply.cpp
+++ b/measurement/power_supply.cpp
@@ -76,7 +76,8 @@ void power_supply::measure(void)
char line[4096];
ifstream file;
- double _rate = 0;
+ double _power_rate = 0;
+ double _current_rate = 0;
double _capacity = 0;
double _voltage = 0;
@@ -114,11 +115,21 @@ void power_supply::measure(void)
c = strchr(line, '=');
c++;
if(*c == '-') c++; // ignoring the negative sign
- _rate = strtoull(c, NULL, 10);
+ _current_rate = strtoull(c, NULL, 10);
if (c) {
- //printf ("CURRENT: %f. \n",_rate);
+ //printf ("CURRENT: %f. \n",_current_rate);
} else {
- _rate = 0;
+ _current_rate = 0;
+ }
+ }
+ if (strstr(line, "POWER_NOW")) {
+ c = strchr(line, '=');
+ c++;
+ _power_rate = strtoull(c, NULL, 10);
+ if (c) {
+ //printf ("POWER: %f. \n",_power_rate);
+ } else {
+ _power_rate = 0;
}
}
if (strstr(line, "CAPACITY=")) {
@@ -152,10 +163,13 @@ void power_supply::measure(void)
voltage = 0.0;
}
- if(_rate) {
- _rate = _rate / 1000.0;
- _rate = _rate * _voltage;
- rate = _rate;
+ if(_power_rate)
+ {
+ rate = _power_rate / 1000000.0;
+ }
+ else if(_current_rate) {
+ _current_rate = _current_rate / 1000.0;
+ rate = _current_rate * _voltage;
} else {
rate = 0.0;
}
--
1.7.7.6

View File

@ -1,6 +1,6 @@
Name: powertop
Version: 1.98
Release: 3%{?dist}
Release: 4%{?dist}
Summary: Power consumption monitor
Group: Applications/System
@ -11,6 +11,8 @@ Source0: http://www.kernel.org/pub/linux/status/powertop/%{name}-%{version
Patch0: powertop-1.98-always-create-params.patch
Patch1: powertop-1.98-unknown-readings-fix.patch
Patch2: powertop-1.98-compile-fix.patch
Patch3: powertop-1.98-add-power-supply-class-support.patch
Patch4: powertop-1.98-power-supply-add-power-now-support.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: gettext, ncurses-devel, pciutils-devel, zlib-devel, libnl-devel
@ -23,6 +25,8 @@ computer use more power than necessary while it is idle.
%patch0 -p1 -b .always-create-params
%patch1 -p1 -b .unknown-readings-fix
%patch2 -p1 -b .compile-fix
%patch3 -p1 -b .add-power-supply-class-support.patch
%patch4 -p1 -b .power-supply-add-power-now-support
%build
make %{?_smp_mflags} CFLAGS="$RPM_OPT_FLAGS"
@ -55,6 +59,13 @@ rm -rf %{buildroot}
#%{_mandir}/man8/powertop.8*
%changelog
* Fri Feb 24 2012 Jaroslav Škarvada <jskarvad@redhat.com> - 1.98-4
- Backported support for power_supply class
(add-power-supply-class-support patch)
- Added support for POWER_NOW readings
(power-supply-add-power-now-support patch)
Resolves: rhbz#796068
* Tue Jan 10 2012 Jaroslav Škarvada <jskarvad@redhat.com> - 1.98-3
- Fixed 'unknown' readings from ACPI meters
Resolves: rhbz#770289