mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
linux: update to linux-4.4.4
This commit is contained in:
parent
6178cfd69f
commit
523c7e0f62
@ -40,7 +40,7 @@ case "$LINUX" in
|
||||
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET imx6-status-led imx6-soc-fan"
|
||||
;;
|
||||
*)
|
||||
PKG_VERSION="4.4.3"
|
||||
PKG_VERSION="4.4.4"
|
||||
PKG_URL="http://www.kernel.org/pub/linux/kernel/v4.x/$PKG_NAME-$PKG_VERSION.tar.xz"
|
||||
;;
|
||||
esac
|
||||
|
@ -1,140 +0,0 @@
|
||||
From 41656d1702a45bd60a2efde06df3fe74a914235f Mon Sep 17 00:00:00 2001
|
||||
From: Chen Yu <yu.c.chen@intel.com>
|
||||
Date: Tue, 20 Oct 2015 21:37:59 +0800
|
||||
Subject: [PATCH 1/3] Thermal: initialize thermal zone device correctly
|
||||
|
||||
After thermal zone device registered, as we have not read any
|
||||
temperature before, thus tz->temperature should not be 0,
|
||||
which actually means 0C, and thermal trend is not available.
|
||||
In this case, we need specially handling for the first
|
||||
thermal_zone_device_update().
|
||||
|
||||
Both thermal core framework and step_wise governor is
|
||||
enhanced to handle this. And since the step_wise governor
|
||||
is the only one that uses trends, so it's the only thermal
|
||||
governor that needs to be updated.
|
||||
|
||||
CC: <stable@vger.kernel.org> #3.18+
|
||||
Tested-by: Manuel Krause <manuelkrause@netscape.net>
|
||||
Tested-by: szegad <szegadlo@poczta.onet.pl>
|
||||
Tested-by: prash <prash.n.rao@gmail.com>
|
||||
Tested-by: amish <ammdispose-arch@yahoo.com>
|
||||
Tested-by: Matthias <morpheusxyz123@yahoo.de>
|
||||
Reviewed-by: Javi Merino <javi.merino@arm.com>
|
||||
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
|
||||
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
|
||||
---
|
||||
drivers/thermal/step_wise.c | 17 +++++++++++++++--
|
||||
drivers/thermal/thermal_core.c | 19 +++++++++++++++++--
|
||||
drivers/thermal/thermal_core.h | 1 +
|
||||
include/linux/thermal.h | 3 +++
|
||||
4 files changed, 36 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
|
||||
index 2f9f708..ea9366a 100644
|
||||
--- a/drivers/thermal/step_wise.c
|
||||
+++ b/drivers/thermal/step_wise.c
|
||||
@@ -63,6 +63,19 @@ static unsigned long get_target_state(struct thermal_instance *instance,
|
||||
next_target = instance->target;
|
||||
dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
|
||||
|
||||
+ if (!instance->initialized) {
|
||||
+ if (throttle) {
|
||||
+ next_target = (cur_state + 1) >= instance->upper ?
|
||||
+ instance->upper :
|
||||
+ ((cur_state + 1) < instance->lower ?
|
||||
+ instance->lower : (cur_state + 1));
|
||||
+ } else {
|
||||
+ next_target = THERMAL_NO_TARGET;
|
||||
+ }
|
||||
+
|
||||
+ return next_target;
|
||||
+ }
|
||||
+
|
||||
switch (trend) {
|
||||
case THERMAL_TREND_RAISING:
|
||||
if (throttle) {
|
||||
@@ -149,7 +162,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
|
||||
old_target, (int)instance->target);
|
||||
|
||||
- if (old_target == instance->target)
|
||||
+ if (instance->initialized && old_target == instance->target)
|
||||
continue;
|
||||
|
||||
/* Activate a passive thermal instance */
|
||||
@@ -161,7 +174,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
|
||||
instance->target == THERMAL_NO_TARGET)
|
||||
update_passive_instance(tz, trip_type, -1);
|
||||
|
||||
-
|
||||
+ instance->initialized = true;
|
||||
instance->cdev->updated = false; /* cdev needs update */
|
||||
}
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index d9e525c..682bc1e 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -532,8 +532,22 @@ static void update_temperature(struct thermal_zone_device *tz)
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
trace_thermal_temperature(tz);
|
||||
- dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
|
||||
- tz->last_temperature, tz->temperature);
|
||||
+ if (tz->last_temperature == THERMAL_TEMP_INVALID)
|
||||
+ dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
|
||||
+ tz->temperature);
|
||||
+ else
|
||||
+ dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
|
||||
+ tz->last_temperature, tz->temperature);
|
||||
+}
|
||||
+
|
||||
+static void thermal_zone_device_reset(struct thermal_zone_device *tz)
|
||||
+{
|
||||
+ struct thermal_instance *pos;
|
||||
+
|
||||
+ tz->temperature = THERMAL_TEMP_INVALID;
|
||||
+ tz->passive = 0;
|
||||
+ list_for_each_entry(pos, &tz->thermal_instances, tz_node)
|
||||
+ pos->initialized = false;
|
||||
}
|
||||
|
||||
void thermal_zone_device_update(struct thermal_zone_device *tz)
|
||||
@@ -1900,6 +1914,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
|
||||
|
||||
INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
|
||||
|
||||
+ thermal_zone_device_reset(tz);
|
||||
thermal_zone_device_update(tz);
|
||||
|
||||
return tz;
|
||||
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
|
||||
index d7ac1fc..749d41a 100644
|
||||
--- a/drivers/thermal/thermal_core.h
|
||||
+++ b/drivers/thermal/thermal_core.h
|
||||
@@ -41,6 +41,7 @@ struct thermal_instance {
|
||||
struct thermal_zone_device *tz;
|
||||
struct thermal_cooling_device *cdev;
|
||||
int trip;
|
||||
+ bool initialized;
|
||||
unsigned long upper; /* Highest cooling state for this trip point */
|
||||
unsigned long lower; /* Lowest cooling state for this trip point */
|
||||
unsigned long target; /* expected cooling state */
|
||||
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
|
||||
index 157d366..5bcabc7 100644
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -43,6 +43,9 @@
|
||||
/* Default weight of a bound cooling device */
|
||||
#define THERMAL_WEIGHT_DEFAULT 0
|
||||
|
||||
+/* use value, which < 0K, to indicate an invalid/uninitialized temperature */
|
||||
+#define THERMAL_TEMP_INVALID -274000
|
||||
+
|
||||
/* Unit conversion macros */
|
||||
#define DECI_KELVIN_TO_CELSIUS(t) ({ \
|
||||
long _t = (t); \
|
||||
--
|
||||
1.8.4.2
|
||||
|
@ -1,135 +0,0 @@
|
||||
From 263fad83855e3da9c768fec15f496a308953d05a Mon Sep 17 00:00:00 2001
|
||||
From: Chen Yu <yu.c.chen@intel.com>
|
||||
Date: Tue, 20 Oct 2015 21:56:39 +0800
|
||||
Subject: [PATCH 2/3] Thermal: handle thermal zone device properly during
|
||||
system sleep
|
||||
|
||||
Current thermal code does not handle system sleep well because
|
||||
1. the cooling device cooling state may be changed during suspend
|
||||
2. the previous temperature reading becomes invalid after resumed because
|
||||
it is got before system sleep
|
||||
3. updating thermal zone device during suspending/resuming
|
||||
is wrong because some devices may have already been suspended
|
||||
or may have not been resumed.
|
||||
|
||||
Thus, the proper way to do this is to cancel all thermal zone
|
||||
device update requirements during suspend/resume, and after all
|
||||
the devices have been resumed, reset and update every registered
|
||||
thermal zone devices.
|
||||
|
||||
This also fixes a regression introduced by:
|
||||
Commit 19593a1fb1f6 ("ACPI / fan: convert to platform driver")
|
||||
Because, with above commit applied, all the fan devices are attached
|
||||
to the acpi_general_pm_domain, and they are turned on by the pm_domain
|
||||
automatically after resume, without the awareness of thermal core.
|
||||
|
||||
CC: <stable@vger.kernel.org> #3.18+
|
||||
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=78201
|
||||
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=91411
|
||||
Tested-by: Manuel Krause <manuelkrause@netscape.net>
|
||||
Tested-by: szegad <szegadlo@poczta.onet.pl>
|
||||
Tested-by: prash <prash.n.rao@gmail.com>
|
||||
Tested-by: amish <ammdispose-arch@yahoo.com>
|
||||
Tested-by: Matthias <morpheusxyz123@yahoo.de>
|
||||
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
|
||||
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 45 +++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 44 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 682bc1e..abeb995 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
+#include <linux/suspend.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/thermal.h>
|
||||
@@ -59,6 +60,8 @@ static LIST_HEAD(thermal_governor_list);
|
||||
static DEFINE_MUTEX(thermal_list_lock);
|
||||
static DEFINE_MUTEX(thermal_governor_lock);
|
||||
|
||||
+static atomic_t in_suspend;
|
||||
+
|
||||
static struct thermal_governor *def_governor;
|
||||
|
||||
static struct thermal_governor *__find_governor(const char *name)
|
||||
@@ -554,6 +557,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
|
||||
{
|
||||
int count;
|
||||
|
||||
+ if (atomic_read(&in_suspend))
|
||||
+ return;
|
||||
+
|
||||
if (!tz->ops->get_temp)
|
||||
return;
|
||||
|
||||
@@ -2155,9 +2161,39 @@ static void thermal_unregister_governors(void)
|
||||
thermal_gov_power_allocator_unregister();
|
||||
}
|
||||
|
||||
+static int thermal_pm_notify(struct notifier_block *nb,
|
||||
+ unsigned long mode, void *_unused)
|
||||
+{
|
||||
+ struct thermal_zone_device *tz;
|
||||
+
|
||||
+ switch (mode) {
|
||||
+ case PM_HIBERNATION_PREPARE:
|
||||
+ case PM_RESTORE_PREPARE:
|
||||
+ case PM_SUSPEND_PREPARE:
|
||||
+ atomic_set(&in_suspend, 1);
|
||||
+ break;
|
||||
+ case PM_POST_HIBERNATION:
|
||||
+ case PM_POST_RESTORE:
|
||||
+ case PM_POST_SUSPEND:
|
||||
+ atomic_set(&in_suspend, 0);
|
||||
+ list_for_each_entry(tz, &thermal_tz_list, node) {
|
||||
+ thermal_zone_device_reset(tz);
|
||||
+ thermal_zone_device_update(tz);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct notifier_block thermal_pm_nb = {
|
||||
+ .notifier_call = thermal_pm_notify,
|
||||
+};
|
||||
+
|
||||
static int __init thermal_init(void)
|
||||
{
|
||||
- int result;
|
||||
+ int result, notifier_result;
|
||||
|
||||
result = thermal_register_governors();
|
||||
if (result)
|
||||
@@ -2175,6 +2211,12 @@ static int __init thermal_init(void)
|
||||
if (result)
|
||||
goto exit_netlink;
|
||||
|
||||
+ notifier_result = register_pm_notifier(&thermal_pm_nb);
|
||||
+ if (notifier_result)
|
||||
+ pr_err("Thermal: Can not register suspend notifier"
|
||||
+ "for thermal framework, return %d\n",
|
||||
+ notifier_result);
|
||||
+
|
||||
return 0;
|
||||
|
||||
exit_netlink:
|
||||
@@ -2194,6 +2236,7 @@ error:
|
||||
|
||||
static void __exit thermal_exit(void)
|
||||
{
|
||||
+ unregister_pm_notifier(&thermal_pm_nb);
|
||||
of_thermal_destroy_zones();
|
||||
genetlink_exit();
|
||||
class_unregister(&thermal_class);
|
||||
--
|
||||
1.8.4.2
|
||||
|
@ -1,96 +0,0 @@
|
||||
From cbf62adc95451bbbeb14387b3661635cf9cafbb3 Mon Sep 17 00:00:00 2001
|
||||
From: Chen Yu <yu.c.chen@intel.com>
|
||||
Date: Thu, 22 Oct 2015 15:47:15 +0800
|
||||
Subject: [PATCH 3/3] Thermal: do thermal zone update after a cooling device
|
||||
registered
|
||||
|
||||
When a new cooling device is registered, we need to update the
|
||||
thermal zone to set the new registered cooling device to a proper
|
||||
state.
|
||||
|
||||
This fixes a problem that the system is cool, while the fan devices
|
||||
are left running on full speed after boot, if fan device is registered
|
||||
after thermal zone device.
|
||||
|
||||
Here is the history of why current patch looks like this:
|
||||
https://patchwork.kernel.org/patch/7273041/
|
||||
|
||||
CC: <stable@vger.kernel.org> #3.18+
|
||||
Reference:https://bugzilla.kernel.org/show_bug.cgi?id=92431
|
||||
Tested-by: Manuel Krause <manuelkrause@netscape.net>
|
||||
Tested-by: szegad <szegadlo@poczta.onet.pl>
|
||||
Tested-by: prash <prash.n.rao@gmail.com>
|
||||
Tested-by: amish <ammdispose-arch@yahoo.com>
|
||||
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
|
||||
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 12 +++++++++++-
|
||||
include/linux/thermal.h | 1 +
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index abeb995..6702b9f 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -1341,6 +1341,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
||||
if (!result) {
|
||||
list_add_tail(&dev->tz_node, &tz->thermal_instances);
|
||||
list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
|
||||
+ atomic_set(&tz->need_update, 1);
|
||||
}
|
||||
mutex_unlock(&cdev->lock);
|
||||
mutex_unlock(&tz->lock);
|
||||
@@ -1450,6 +1451,7 @@ __thermal_cooling_device_register(struct device_node *np,
|
||||
const struct thermal_cooling_device_ops *ops)
|
||||
{
|
||||
struct thermal_cooling_device *cdev;
|
||||
+ struct thermal_zone_device *pos = NULL;
|
||||
int result;
|
||||
|
||||
if (type && strlen(type) >= THERMAL_NAME_LENGTH)
|
||||
@@ -1494,6 +1496,12 @@ __thermal_cooling_device_register(struct device_node *np,
|
||||
/* Update binding information for 'this' new cdev */
|
||||
bind_cdev(cdev);
|
||||
|
||||
+ mutex_lock(&thermal_list_lock);
|
||||
+ list_for_each_entry(pos, &thermal_tz_list, node)
|
||||
+ if (atomic_cmpxchg(&pos->need_update, 1, 0))
|
||||
+ thermal_zone_device_update(pos);
|
||||
+ mutex_unlock(&thermal_list_lock);
|
||||
+
|
||||
return cdev;
|
||||
}
|
||||
|
||||
@@ -1826,6 +1834,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
|
||||
tz->trips = trips;
|
||||
tz->passive_delay = passive_delay;
|
||||
tz->polling_delay = polling_delay;
|
||||
+ atomic_set(&tz->need_update, 0);
|
||||
|
||||
dev_set_name(&tz->device, "thermal_zone%d", tz->id);
|
||||
result = device_register(&tz->device);
|
||||
@@ -1921,7 +1930,8 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
|
||||
INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
|
||||
|
||||
thermal_zone_device_reset(tz);
|
||||
- thermal_zone_device_update(tz);
|
||||
+ if (atomic_cmpxchg(&tz->need_update, 1, 0))
|
||||
+ thermal_zone_device_update(tz);
|
||||
|
||||
return tz;
|
||||
|
||||
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
|
||||
index 5bcabc7..4298418 100644
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -195,6 +195,7 @@ struct thermal_zone_device {
|
||||
int emul_temperature;
|
||||
int passive;
|
||||
unsigned int forced_passive;
|
||||
+ atomic_t need_update;
|
||||
struct thermal_zone_device_ops *ops;
|
||||
struct thermal_zone_params *tzp;
|
||||
struct thermal_governor *governor;
|
||||
--
|
||||
1.8.4.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user