Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8960f5f authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power_supply: Register cooling device outside of probe"

parents f3b571fa 1a4e929c
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -55,7 +55,8 @@ of heat dissipation). For example a fan's cooling states correspond to
the different fan speeds possible. Cooling states are referred to by
single unsigned integers, where larger numbers mean greater heat
dissipation. The precise set of cooling states associated with a device
should be defined in a particular device's binding.
(as referred to by the cooling-min-level and cooling-max-level
properties) should be defined in a particular device's binding.
For more examples of cooling devices, refer to the example sections below.

Required properties:
@@ -68,6 +69,15 @@ Required properties:
			See Cooling device maps section below for more details
			on how consumers refer to cooling devices.

Optional properties:
- cooling-min-level:	An integer indicating the smallest
  Type: unsigned	cooling state accepted. Typically 0.
  Size: one cell

- cooling-max-level:	An integer indicating the largest
  Type: unsigned	cooling state accepted.
  Size: one cell

* Trip points

The trip node is a node to describe a point in the temperature domain
@@ -216,6 +226,8 @@ cpus {
			396000  950000
			198000  850000
		>;
		cooling-min-level = <0>;
		cooling-max-level = <3>;
		#cooling-cells = <2>; /* min followed by max */
	};
	...
@@ -229,6 +241,8 @@ cpus {
	 */
	fan0: fan@48 {
		...
		cooling-max-level = <9>;
		cooling-min-level = <0>;
		#cooling-cells = <2>; /* min followed by max */
	};
};
+13 −9
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ void power_supply_changed(struct power_supply *psy)
}
EXPORT_SYMBOL_GPL(power_supply_changed);

static int psy_register_cooler(struct device *dev, struct power_supply *psy);
/*
 * Notify that power supply was registered after parent finished the probing.
 *
@@ -133,6 +134,8 @@ EXPORT_SYMBOL_GPL(power_supply_changed);
 * calling power_supply_changed() directly from power_supply_register()
 * would lead to execution of get_property() function provided by the driver
 * too early - before the probe ends.
 * Also, registering cooling device from the probe will execute the
 * get_property() function. So register the cooling device after the probe.
 *
 * Avoid that by waiting on parent's mutex.
 */
@@ -149,6 +152,7 @@ static void power_supply_deferred_register_work(struct work_struct *work)
		}
	}

	psy_register_cooler(psy->dev.parent, psy);
	power_supply_changed(psy);

	if (psy->dev.parent)
@@ -799,7 +803,7 @@ static const struct thermal_cooling_device_ops psy_tcd_ops = {
	.set_cur_state = ps_set_cur_charge_cntl_limit,
};

static int psy_register_cooler(struct power_supply *psy)
static int psy_register_cooler(struct device *dev, struct power_supply *psy)
{
	int i;

@@ -807,6 +811,12 @@ static int psy_register_cooler(struct power_supply *psy)
	for (i = 0; i < psy->desc->num_properties; i++) {
		if (psy->desc->properties[i] ==
				POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT) {
			if (dev)
				psy->tcd = thermal_of_cooling_device_register(
							dev_of_node(dev),
							(char *)psy->desc->name,
							psy, &psy_tcd_ops);
			else
				psy->tcd = thermal_cooling_device_register(
							(char *)psy->desc->name,
							psy, &psy_tcd_ops);
@@ -832,7 +842,7 @@ static void psy_unregister_thermal(struct power_supply *psy)
{
}

static int psy_register_cooler(struct power_supply *psy)
static int psy_register_cooler(struct device *dev, struct power_supply *psy)
{
	return 0;
}
@@ -914,10 +924,6 @@ __power_supply_register(struct device *parent,
	if (rc)
		goto register_thermal_failed;

	rc = psy_register_cooler(psy);
	if (rc)
		goto register_cooler_failed;

	rc = power_supply_create_triggers(psy);
	if (rc)
		goto create_triggers_failed;
@@ -941,8 +947,6 @@ __power_supply_register(struct device *parent,
	return psy;

create_triggers_failed:
	psy_unregister_cooler(psy);
register_cooler_failed:
	psy_unregister_thermal(psy);
register_thermal_failed:
	device_del(dev);
+10 −0
Original line number Diff line number Diff line
@@ -142,6 +142,16 @@ config THERMAL_GOV_USER_SPACE
	help
	  Enable this to let the user space manage the platform thermals.

config THERMAL_GOV_LOW_LIMITS
	bool "Low limits mitigation governor"
	help
	  Enable this to manage platform limits using low limits
	  governor.

	  Enable this governor to monitor and trigger floor mitigation.
	  This governor will monitor the limits going below a
	  trip threshold to trigger a floor mitigation.

config THERMAL_GOV_POWER_ALLOCATOR
	bool "Power allocator thermal governor"
	help
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o
thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG)	+= gov_bang_bang.o
thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE)	+= step_wise.o
thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE)	+= user_space.o
thermal_sys-$(CONFIG_THERMAL_GOV_LOW_LIMITS) += gov_low_limits.o
thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR)	+= power_allocator.o

# cpufreq cooling
@@ -54,7 +55,7 @@ obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
obj-$(CONFIG_INTEL_PCH_THERMAL)	+= intel_pch_thermal.o
obj-$(CONFIG_ST_THERMAL)	+= st/
obj-$(CONFIG_QCOM_TSENS)	+= qcom/
obj-$(CONFIG_ARCH_QCOM)		+= qcom/
obj-y				+= tegra/
obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
obj-$(CONFIG_MTK_THERMAL)	+= mtk_thermal.o
+130 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2012 Intel Corp
 * Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 */

#include <linux/thermal.h>
#include <trace/events/thermal.h>

#include "thermal_core.h"

static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
{
	int trip_temp, trip_hyst;
	enum thermal_trip_type trip_type;
	struct thermal_instance *instance;
	bool throttle;
	int old_target;

	tz->ops->get_trip_temp(tz, trip, &trip_temp);
	tz->ops->get_trip_type(tz, trip, &trip_type);
	if (tz->ops->get_trip_hyst) {
		tz->ops->get_trip_hyst(tz, trip, &trip_hyst);
		trip_hyst = trip_temp + trip_hyst;
	} else {
		trip_hyst = trip_temp;
	}

	mutex_lock(&tz->lock);

	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
		if (instance->trip != trip)
			continue;

		if ((tz->temperature <= trip_temp) ||
			(instance->target != THERMAL_NO_TARGET
				&& tz->temperature < trip_hyst))
			throttle = true;
		else
			throttle = false;

		dev_dbg(&tz->device,
			"Trip%d[type=%d,temp=%d,hyst=%d],throttle=%d\n",
			trip, trip_type, trip_temp, trip_hyst, throttle);

		old_target = instance->target;
		instance->target = (throttle) ? instance->upper
					: THERMAL_NO_TARGET;
		dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
					old_target, (int)instance->target);

		if (instance->initialized && old_target == instance->target)
			continue;

		if (!instance->initialized) {
			if (instance->target != THERMAL_NO_TARGET) {
				trace_thermal_zone_trip(tz, trip, trip_type,
							true);
				tz->passive += 1;
			}
		} else {
			if (old_target == THERMAL_NO_TARGET &&
				instance->target != THERMAL_NO_TARGET) {
				trace_thermal_zone_trip(tz, trip, trip_type,
							true);
				tz->passive += 1;
			} else if (old_target != THERMAL_NO_TARGET &&
				instance->target == THERMAL_NO_TARGET) {
				trace_thermal_zone_trip(tz, trip, trip_type,
							false);
				tz->passive -= 1;
			}
		}

		instance->initialized = true;
		instance->cdev->updated = false; /* cdev needs update */
	}

	mutex_unlock(&tz->lock);
}

/**
 * low_limits_throttle - throttles devices associated with the given zone
 * @tz - thermal_zone_device
 * @trip - the trip point
 *
 * Throttling Logic: If the sensor reading goes below a trip point, the
 * pre-defined mitigation will be applied for the cooling device.
 * If the sensor reading goes above the trip hysteresis, the
 * mitigation will be removed.
 */
static int low_limits_throttle(struct thermal_zone_device *tz, int trip)
{
	struct thermal_instance *instance;

	thermal_zone_trip_update(tz, trip);

	mutex_lock(&tz->lock);

	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
		thermal_cdev_update(instance->cdev);

	mutex_unlock(&tz->lock);

	return 0;
}

static struct thermal_governor thermal_gov_low_limits_floor = {
	.name		= "low_limits_floor",
	.throttle	= low_limits_throttle,
	.min_state_throttle = 1,
};

static struct thermal_governor thermal_gov_low_limits_cap = {
	.name		= "low_limits_cap",
	.throttle	= low_limits_throttle,
};

int thermal_gov_low_limits_register(void)
{
	thermal_register_governor(&thermal_gov_low_limits_cap);
	return thermal_register_governor(&thermal_gov_low_limits_floor);
}

void thermal_gov_low_limits_unregister(void)
{
	thermal_unregister_governor(&thermal_gov_low_limits_cap);
	thermal_unregister_governor(&thermal_gov_low_limits_floor);
}
Loading