Commit 3dd85514 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-battery', 'acpi-video', 'acpi-fan' and 'acpi-drivers'

* acpi-battery:
  ACPI / battery: Deal better with neither design nor full capacity not being reported
  ACPI / battery: Use design-cap for capacity calculations if full-cap is not available
  ACPI / battery: Deal with design or full capacity being reported as -1

* acpi-video:
  ACPI: video: Do not export a non working backlight interface on MSI MS-7721 boards
  ACPI: video: Use native backlight on Lenovo E41-25/45
  ACPI: video: fix typo in comment

* acpi-fan:
  ACPI: fan: Expose fan performance state information

* acpi-drivers:
  thermal: int340x_thermal: Add Tiger Lake ACPI device IDs
  platform/x86: intel-hid: Add Tiger Lake ACPI device ID
  ACPI: fan: Add Tiger Lake ACPI device ID
  ACPI: DPTF: Add Tiger Lake ACPI device IDs
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

===========================
ACPI Fan Performance States
===========================

When the optional _FPS object is present under an ACPI device representing a
fan (for example, PNP0C0B or INT3404), the ACPI fan driver creates additional
"state*" attributes in the sysfs directory of the ACPI device in question.
These attributes list properties of fan performance states.

For more information on _FPS refer to the ACPI specification at:

http://uefi.org/specifications

For instance, the contents of the INT3404 ACPI device sysfs directory
may look as follows::

 $ ls -l /sys/bus/acpi/devices/INT3404:00/
 total 0
...
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state0
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state1
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state10
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state11
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state2
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state3
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state4
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state5
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state6
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state7
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state8
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state9
 -r--r--r-- 1 root root 4096 Dec 13 01:00 status
 ...

where each of the "state*" files represents one performance state of the fan
and contains a colon-separated list of 5 integer numbers (fields) with the
following interpretation::

control_percent:trip_point_index:speed_rpm:noise_level_mdb:power_mw

* ``control_percent``: The percent value to be used to set the fan speed to a
  specific level using the _FSL object (0-100).

* ``trip_point_index``: The active cooling trip point number that corresponds
  to this performance state (0-9).

* ``speed_rpm``: Speed of the fan in rotations per minute.

* ``noise_level_mdb``: Audible noise emitted by the fan in this state in
  millidecibels.

* ``power_mw``: Power draw of the fan in this state in milliwatts.

For example::

 $cat /sys/bus/acpi/devices/INT3404:00/state1
 25:0:3200:12500:1250

When a given field is not populated or its value provided by the platform
firmware is invalid, the "not-defined" string is shown instead of the value.
+1 −0
Original line number Diff line number Diff line
@@ -12,3 +12,4 @@ the Linux ACPI support.
   dsdt-override
   ssdt-overlays
   cppc_sysfs
   fan_performance_states
+1 −1
Original line number Diff line number Diff line
@@ -2187,7 +2187,7 @@ int acpi_video_register(void)
	if (register_count) {
		/*
		 * if the function of acpi_video_register is already called,
		 * don't register the acpi_vide_bus again and return no error.
		 * don't register the acpi_video_bus again and return no error.
		 */
		goto leave;
	}
+56 −19
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
#define PREFIX "ACPI: "

#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
#define ACPI_BATTERY_CAPACITY_VALID(capacity) \
	((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN)

#define ACPI_BATTERY_DEVICE_NAME	"Battery"

@@ -192,7 +194,8 @@ static int acpi_battery_is_charged(struct acpi_battery *battery)

static bool acpi_battery_is_degraded(struct acpi_battery *battery)
{
	return battery->full_charge_capacity && battery->design_capacity &&
	return ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
		ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity) &&
		battery->full_charge_capacity < battery->design_capacity;
}

@@ -214,7 +217,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
				     enum power_supply_property psp,
				     union power_supply_propval *val)
{
	int ret = 0;
	int full_capacity = ACPI_BATTERY_VALUE_UNKNOWN, ret = 0;
	struct acpi_battery *battery = to_acpi_battery(psy);

	if (acpi_battery_present(battery)) {
@@ -263,14 +266,14 @@ static int acpi_battery_get_property(struct power_supply *psy,
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
		if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
		if (!ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
			ret = -ENODEV;
		else
			val->intval = battery->design_capacity * 1000;
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL:
	case POWER_SUPPLY_PROP_ENERGY_FULL:
		if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
		if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
			ret = -ENODEV;
		else
			val->intval = battery->full_charge_capacity * 1000;
@@ -283,11 +286,17 @@ static int acpi_battery_get_property(struct power_supply *psy,
			val->intval = battery->capacity_now * 1000;
		break;
	case POWER_SUPPLY_PROP_CAPACITY:
		if (battery->capacity_now && battery->full_charge_capacity)
			val->intval = battery->capacity_now * 100/
					battery->full_charge_capacity;
		if (ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
			full_capacity = battery->full_charge_capacity;
		else if (ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
			full_capacity = battery->design_capacity;

		if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
		    full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
			ret = -ENODEV;
		else
			val->intval = 0;
			val->intval = battery->capacity_now * 100/
					full_capacity;
		break;
	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
		if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
@@ -333,6 +342,20 @@ static enum power_supply_property charge_battery_props[] = {
	POWER_SUPPLY_PROP_SERIAL_NUMBER,
};

static enum power_supply_property charge_battery_full_cap_broken_props[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_TECHNOLOGY,
	POWER_SUPPLY_PROP_CYCLE_COUNT,
	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
	POWER_SUPPLY_PROP_CURRENT_NOW,
	POWER_SUPPLY_PROP_CHARGE_NOW,
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_MANUFACTURER,
	POWER_SUPPLY_PROP_SERIAL_NUMBER,
};

static enum power_supply_property energy_battery_props[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_PRESENT,
@@ -794,12 +817,25 @@ static void __exit battery_hook_exit(void)
static int sysfs_add_battery(struct acpi_battery *battery)
{
	struct power_supply_config psy_cfg = { .drv_data = battery, };
	bool full_cap_broken = false;

	if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
	    !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
		full_cap_broken = true;

	if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
		if (full_cap_broken) {
			battery->bat_desc.properties =
			    charge_battery_full_cap_broken_props;
			battery->bat_desc.num_properties =
			    ARRAY_SIZE(charge_battery_full_cap_broken_props);
		} else {
			battery->bat_desc.properties = charge_battery_props;
			battery->bat_desc.num_properties =
			    ARRAY_SIZE(charge_battery_props);
	} else if (battery->full_charge_capacity == 0) {
		}
	} else {
		if (full_cap_broken) {
			battery->bat_desc.properties =
			    energy_battery_full_cap_broken_props;
			battery->bat_desc.num_properties =
@@ -809,6 +845,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
			battery->bat_desc.num_properties =
			    ARRAY_SIZE(energy_battery_props);
		}
	}

	battery->bat_desc.name = acpi_device_bid(battery->device);
	battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
+1 −0
Original line number Diff line number Diff line
@@ -1321,6 +1321,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
	 */
	static const struct acpi_device_id special_pm_ids[] = {
		{"PNP0C0B", }, /* Generic ACPI fan */
		{"INT1044", }, /* Fan for Tiger Lake generation */
		{"INT3404", }, /* Fan */
		{}
	};
Loading