ipq806x: add ipq806x specific tsens driver
Current upstream driver doesnt fully support ipq806x devices ipq806x has 11 sensors, the upstream one doesn't allow to check sensors 0-4, only 5-10. A specific driver for ipq806x has been found in Qualcomm SDK repo. https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-msm/commit/?h=release/endive_preview_cc&id=c089e464cd7ce652419a0dc44d7959ce4d24b8a5 https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-msm/commit/?h=release/endive_preview_cc&id=c23d94b702c4182862e7f5051a2b7d00bb922a29 https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-msm/commit/?h=release/endive_preview_cc&id=742f3684b62a6b9f082cb49404b1a92dc0b16bf5 https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-msm/commit/?h=release/endive_preview_cc&id=c0a9b2e2a382c152fa128f5b864c800dd6dfb311 Merging it into LEDE with this commit. Signed-off-by: Pavel Kubelun <be.dissent@gmail.com>
This commit is contained in:
parent
02fe942337
commit
dc32d0a53c
5 changed files with 1449 additions and 110 deletions
|
@ -78,86 +78,354 @@
|
|||
};
|
||||
|
||||
thermal-zones {
|
||||
cpu-thermal0 {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
thermal-sensors = <&gcc 5>;
|
||||
coefficients = <1132 0>;
|
||||
tsens_tz_sensor0 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 0>;
|
||||
|
||||
trips {
|
||||
cpu_alert0: trip0 {
|
||||
temperature = <75000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
cpu_crit0: trip1 {
|
||||
temperature = <110000>;
|
||||
hysteresis = <2000>;
|
||||
type = "critical";
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cpu-thermal1 {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
thermal-sensors = <&gcc 6>;
|
||||
coefficients = <1132 0>;
|
||||
tsens_tz_sensor1 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 1>;
|
||||
|
||||
trips {
|
||||
cpu_alert1: trip0 {
|
||||
temperature = <75000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
cpu_crit1: trip1 {
|
||||
temperature = <110000>;
|
||||
hysteresis = <2000>;
|
||||
type = "critical";
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cpu-thermal2 {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
thermal-sensors = <&gcc 7>;
|
||||
coefficients = <1199 0>;
|
||||
tsens_tz_sensor2 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 2>;
|
||||
|
||||
trips {
|
||||
cpu_alert2: trip0 {
|
||||
temperature = <75000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
cpu_crit2: trip1 {
|
||||
temperature = <110000>;
|
||||
hysteresis = <2000>;
|
||||
type = "critical";
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cpu-thermal3 {
|
||||
polling-delay-passive = <250>;
|
||||
polling-delay = <1000>;
|
||||
|
||||
thermal-sensors = <&gcc 8>;
|
||||
coefficients = <1132 0>;
|
||||
tsens_tz_sensor3 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 3>;
|
||||
|
||||
trips {
|
||||
cpu_alert3: trip0 {
|
||||
temperature = <75000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
cpu_crit3: trip1 {
|
||||
temperature = <110000>;
|
||||
hysteresis = <2000>;
|
||||
type = "critical";
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tsens_tz_sensor4 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 4>;
|
||||
|
||||
trips {
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tsens_tz_sensor5 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 5>;
|
||||
|
||||
trips {
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tsens_tz_sensor6 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 6>;
|
||||
|
||||
trips {
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tsens_tz_sensor7 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 7>;
|
||||
|
||||
trips {
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tsens_tz_sensor8 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 8>;
|
||||
|
||||
trips {
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tsens_tz_sensor9 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 9>;
|
||||
|
||||
trips {
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tsens_tz_sensor10 {
|
||||
polling-delay-passive = <0>;
|
||||
polling-delay = <0>;
|
||||
thermal-sensors = <&tsens 10>;
|
||||
|
||||
trips {
|
||||
cpu-critical-hi {
|
||||
temperature = <125>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_high";
|
||||
};
|
||||
|
||||
cpu-config-hi {
|
||||
temperature = <105>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_hi";
|
||||
};
|
||||
|
||||
cpu-config-lo {
|
||||
temperature = <95>;
|
||||
hysteresis = <2>;
|
||||
type = "configurable_lo";
|
||||
};
|
||||
|
||||
cpu-critical-low {
|
||||
temperature = <0>;
|
||||
hysteresis = <2>;
|
||||
type = "critical_low";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -273,15 +541,14 @@
|
|||
|
||||
qfprom: qfprom@700000 {
|
||||
compatible = "qcom,qfprom", "syscon";
|
||||
reg = <0x00700000 0x1000>;
|
||||
reg = <0x700000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
tsens_calib: calib {
|
||||
status = "okay";
|
||||
tsens_calib: calib@400 {
|
||||
reg = <0x400 0x10>;
|
||||
};
|
||||
tsens_backup: backup_calib {
|
||||
tsens_backup: backup@410 {
|
||||
reg = <0x410 0x10>;
|
||||
};
|
||||
};
|
||||
|
@ -620,11 +887,17 @@
|
|||
gcc: clock-controller@900000 {
|
||||
compatible = "qcom,gcc-ipq8064";
|
||||
reg = <0x00900000 0x4000>;
|
||||
nvmem-cells = <&tsens_calib>, <&tsens_backup>;
|
||||
nvmem-cell-names = "calib", "calib_backup";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
tsens: thermal-sensor@900000 {
|
||||
compatible = "qcom,ipq8064-tsens";
|
||||
reg = <0x900000 0x3680>;
|
||||
nvmem-cells = <&tsens_calib>, <&tsens_backup>;
|
||||
nvmem-cell-names = "calib", "calib_backup";
|
||||
interrupts = <0 178 0>;
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
|||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
++ .flags = CLK_IGNORE_UNUSED,
|
||||
+ .flags = CLK_IGNORE_UNUSED,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,638 @@
|
|||
From 3302e1e1a3cfa4e67fda2a61d6f0c42205d40932 Mon Sep 17 00:00:00 2001
|
||||
From: Rajith Cherian <rajith@codeaurora.org>
|
||||
Date: Tue, 14 Feb 2017 18:30:43 +0530
|
||||
Subject: [PATCH] ipq8064: tsens: Base tsens driver for IPQ8064
|
||||
|
||||
Add TSENS driver template to support IPQ8064.
|
||||
This is a base file copied from tsens-8960.c
|
||||
|
||||
Change-Id: I47c573fdfa2d898243c6a6ba952d1632f91391f7
|
||||
Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
|
||||
|
||||
ipq8064: tsens: TSENS driver support for IPQ8064
|
||||
|
||||
Support for IPQ8064 tsens driver. The driver works
|
||||
with the thermal framework. The driver overrides the
|
||||
following fucntionalities:
|
||||
|
||||
1. Get current temperature.
|
||||
2. Get/Set trip temperatures.
|
||||
3. Enabled/Disable trip points.
|
||||
4. ISR for threshold generated interrupt.
|
||||
5. Notify userspace when trip points are hit.
|
||||
|
||||
Change-Id: I8bc7204fd627d10875ab13fc1de8cb6c2ed7a918
|
||||
Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
|
||||
---
|
||||
.../devicetree/bindings/thermal/qcom-tsens.txt | 1 +
|
||||
drivers/thermal/qcom/Makefile | 3 +-
|
||||
drivers/thermal/qcom/tsens-ipq8064.c | 551 +++++++++++++++++++++
|
||||
drivers/thermal/qcom/tsens.c | 3 +
|
||||
drivers/thermal/qcom/tsens.h | 2 +-
|
||||
5 files changed, 558 insertions(+), 2 deletions(-)
|
||||
create mode 100644 drivers/thermal/qcom/tsens-ipq8064.c
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
|
||||
index 292ed89..f4a76f6 100644
|
||||
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
|
||||
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
|
||||
@@ -5,6 +5,7 @@ Required properties:
|
||||
- "qcom,msm8916-tsens" : For 8916 Family of SoCs
|
||||
- "qcom,msm8974-tsens" : For 8974 Family of SoCs
|
||||
- "qcom,msm8996-tsens" : For 8996 Family of SoCs
|
||||
+ - "qcom,ipq8064-tsens" : For IPQ8064
|
||||
|
||||
- reg: Address range of the thermal registers
|
||||
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
|
||||
diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
|
||||
index 2cc2193..cc07cf4 100644
|
||||
--- a/drivers/thermal/qcom/Makefile
|
||||
+++ b/drivers/thermal/qcom/Makefile
|
||||
@@ -1,2 +1,3 @@
|
||||
obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
|
||||
-qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-8996.o
|
||||
+qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-8996.o \
|
||||
+ tsens-ipq8064.o
|
||||
diff --git a/drivers/thermal/qcom/tsens-ipq8064.c b/drivers/thermal/qcom/tsens-ipq8064.c
|
||||
new file mode 100644
|
||||
index 0000000..c52888f
|
||||
--- /dev/null
|
||||
+++ b/drivers/thermal/qcom/tsens-ipq8064.c
|
||||
@@ -0,0 +1,551 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 and
|
||||
+ * only version 2 as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/thermal.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include "tsens.h"
|
||||
+
|
||||
+#define CAL_MDEGC 30000
|
||||
+
|
||||
+#define CONFIG_ADDR 0x3640
|
||||
+/* CONFIG_ADDR bitmasks */
|
||||
+#define CONFIG 0x9b
|
||||
+#define CONFIG_MASK 0xf
|
||||
+#define CONFIG_SHIFT 0
|
||||
+
|
||||
+#define STATUS_CNTL_8064 0x3660
|
||||
+#define CNTL_ADDR 0x3620
|
||||
+/* CNTL_ADDR bitmasks */
|
||||
+#define EN BIT(0)
|
||||
+#define SW_RST BIT(1)
|
||||
+#define SENSOR0_EN BIT(3)
|
||||
+#define SLP_CLK_ENA BIT(26)
|
||||
+#define MEASURE_PERIOD 1
|
||||
+#define SENSOR0_SHIFT 3
|
||||
+
|
||||
+/* INT_STATUS_ADDR bitmasks */
|
||||
+#define MIN_STATUS_MASK BIT(0)
|
||||
+#define LOWER_STATUS_CLR BIT(1)
|
||||
+#define UPPER_STATUS_CLR BIT(2)
|
||||
+#define MAX_STATUS_MASK BIT(3)
|
||||
+
|
||||
+#define THRESHOLD_ADDR 0x3624
|
||||
+/* THRESHOLD_ADDR bitmasks */
|
||||
+#define THRESHOLD_MAX_CODE 0xff
|
||||
+#define THRESHOLD_MIN_CODE 0
|
||||
+#define THRESHOLD_MAX_LIMIT_SHIFT 24
|
||||
+#define THRESHOLD_MIN_LIMIT_SHIFT 16
|
||||
+#define THRESHOLD_UPPER_LIMIT_SHIFT 8
|
||||
+#define THRESHOLD_LOWER_LIMIT_SHIFT 0
|
||||
+#define THRESHOLD_MAX_LIMIT_MASK (THRESHOLD_MAX_CODE << \
|
||||
+ THRESHOLD_MAX_LIMIT_SHIFT)
|
||||
+#define THRESHOLD_MIN_LIMIT_MASK (THRESHOLD_MAX_CODE << \
|
||||
+ THRESHOLD_MIN_LIMIT_SHIFT)
|
||||
+#define THRESHOLD_UPPER_LIMIT_MASK (THRESHOLD_MAX_CODE << \
|
||||
+ THRESHOLD_UPPER_LIMIT_SHIFT)
|
||||
+#define THRESHOLD_LOWER_LIMIT_MASK (THRESHOLD_MAX_CODE << \
|
||||
+ THRESHOLD_LOWER_LIMIT_SHIFT)
|
||||
+
|
||||
+/* Initial temperature threshold values */
|
||||
+#define LOWER_LIMIT_TH 0x9d /* 95C */
|
||||
+#define UPPER_LIMIT_TH 0xa6 /* 105C */
|
||||
+#define MIN_LIMIT_TH 0x0
|
||||
+#define MAX_LIMIT_TH 0xff
|
||||
+
|
||||
+#define S0_STATUS_ADDR 0x3628
|
||||
+#define STATUS_ADDR_OFFSET 2
|
||||
+#define SENSOR_STATUS_SIZE 4
|
||||
+#define INT_STATUS_ADDR 0x363c
|
||||
+#define TRDY_MASK BIT(7)
|
||||
+#define TIMEOUT_US 100
|
||||
+
|
||||
+#define TSENS_EN BIT(0)
|
||||
+#define TSENS_SW_RST BIT(1)
|
||||
+#define TSENS_ADC_CLK_SEL BIT(2)
|
||||
+#define SENSOR0_EN BIT(3)
|
||||
+#define SENSOR1_EN BIT(4)
|
||||
+#define SENSOR2_EN BIT(5)
|
||||
+#define SENSOR3_EN BIT(6)
|
||||
+#define SENSOR4_EN BIT(7)
|
||||
+#define SENSORS_EN (SENSOR0_EN | SENSOR1_EN | \
|
||||
+ SENSOR2_EN | SENSOR3_EN | SENSOR4_EN)
|
||||
+#define TSENS_8064_SENSOR5_EN BIT(8)
|
||||
+#define TSENS_8064_SENSOR6_EN BIT(9)
|
||||
+#define TSENS_8064_SENSOR7_EN BIT(10)
|
||||
+#define TSENS_8064_SENSOR8_EN BIT(11)
|
||||
+#define TSENS_8064_SENSOR9_EN BIT(12)
|
||||
+#define TSENS_8064_SENSOR10_EN BIT(13)
|
||||
+#define TSENS_8064_SENSORS_EN (SENSORS_EN | \
|
||||
+ TSENS_8064_SENSOR5_EN | \
|
||||
+ TSENS_8064_SENSOR6_EN | \
|
||||
+ TSENS_8064_SENSOR7_EN | \
|
||||
+ TSENS_8064_SENSOR8_EN | \
|
||||
+ TSENS_8064_SENSOR9_EN | \
|
||||
+ TSENS_8064_SENSOR10_EN)
|
||||
+
|
||||
+#define TSENS_8064_SEQ_SENSORS 5
|
||||
+#define TSENS_8064_S4_S5_OFFSET 40
|
||||
+#define TSENS_FACTOR 1000
|
||||
+
|
||||
+/* Trips: from very hot to very cold */
|
||||
+enum tsens_trip_type {
|
||||
+ TSENS_TRIP_STAGE3 = 0,
|
||||
+ TSENS_TRIP_STAGE2,
|
||||
+ TSENS_TRIP_STAGE1,
|
||||
+ TSENS_TRIP_STAGE0,
|
||||
+ TSENS_TRIP_NUM,
|
||||
+};
|
||||
+
|
||||
+u32 tsens_8064_slope[] = {
|
||||
+ 1176, 1176, 1154, 1176,
|
||||
+ 1111, 1132, 1132, 1199,
|
||||
+ 1132, 1199, 1132
|
||||
+ };
|
||||
+
|
||||
+/* Temperature on y axis and ADC-code on x-axis */
|
||||
+static inline int code_to_degC(u32 adc_code, const struct tsens_sensor *s)
|
||||
+{
|
||||
+ int degcbeforefactor, degc;
|
||||
+
|
||||
+ degcbeforefactor = (adc_code * s->slope) + s->offset;
|
||||
+
|
||||
+ if (degcbeforefactor == 0)
|
||||
+ degc = degcbeforefactor;
|
||||
+ else if (degcbeforefactor > 0)
|
||||
+ degc = (degcbeforefactor + TSENS_FACTOR/2)
|
||||
+ / TSENS_FACTOR;
|
||||
+ else
|
||||
+ degc = (degcbeforefactor - TSENS_FACTOR/2)
|
||||
+ / TSENS_FACTOR;
|
||||
+
|
||||
+ return degc;
|
||||
+}
|
||||
+
|
||||
+static int degC_to_code(int degC, const struct tsens_sensor *s)
|
||||
+{
|
||||
+ int code = ((degC * TSENS_FACTOR - s->offset) + (s->slope/2))
|
||||
+ / s->slope;
|
||||
+
|
||||
+ if (code > THRESHOLD_MAX_CODE)
|
||||
+ code = THRESHOLD_MAX_CODE;
|
||||
+ else if (code < THRESHOLD_MIN_CODE)
|
||||
+ code = THRESHOLD_MIN_CODE;
|
||||
+ return code;
|
||||
+}
|
||||
+
|
||||
+static int suspend_ipq8064(struct tsens_device *tmdev)
|
||||
+{
|
||||
+ int ret;
|
||||
+ unsigned int mask;
|
||||
+ struct regmap *map = tmdev->map;
|
||||
+
|
||||
+ ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_read(map, CNTL_ADDR, &tmdev->ctx.control);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ mask = SLP_CLK_ENA | EN;
|
||||
+
|
||||
+ ret = regmap_update_bits(map, CNTL_ADDR, mask, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int resume_ipq8064(struct tsens_device *tmdev)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct regmap *map = tmdev->map;
|
||||
+
|
||||
+ ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(map, THRESHOLD_ADDR, tmdev->ctx.threshold);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(map, CNTL_ADDR, tmdev->ctx.control);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void notify_uspace_tsens_fn(struct work_struct *work)
|
||||
+{
|
||||
+ struct tsens_sensor *s = container_of(work, struct tsens_sensor,
|
||||
+ notify_work);
|
||||
+
|
||||
+ sysfs_notify(&s->tzd->device.kobj, NULL, "type");
|
||||
+}
|
||||
+
|
||||
+static void tsens_scheduler_fn(struct work_struct *work)
|
||||
+{
|
||||
+ struct tsens_device *tmdev = container_of(work, struct tsens_device,
|
||||
+ tsens_work);
|
||||
+ unsigned int threshold, threshold_low, code, reg, sensor, mask;
|
||||
+ unsigned int sensor_addr;
|
||||
+ bool upper_th_x, lower_th_x;
|
||||
+ int adc_code, ret;
|
||||
+
|
||||
+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, ®);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+ reg = reg | LOWER_STATUS_CLR | UPPER_STATUS_CLR;
|
||||
+ ret = regmap_write(tmdev->map, STATUS_CNTL_8064, reg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ mask = ~(LOWER_STATUS_CLR | UPPER_STATUS_CLR);
|
||||
+ ret = regmap_read(tmdev->map, THRESHOLD_ADDR, &threshold);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+ threshold_low = (threshold & THRESHOLD_LOWER_LIMIT_MASK)
|
||||
+ >> THRESHOLD_LOWER_LIMIT_SHIFT;
|
||||
+ threshold = (threshold & THRESHOLD_UPPER_LIMIT_MASK)
|
||||
+ >> THRESHOLD_UPPER_LIMIT_SHIFT;
|
||||
+
|
||||
+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, ®);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ ret = regmap_read(tmdev->map, CNTL_ADDR, &sensor);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+ sensor &= (uint32_t) TSENS_8064_SENSORS_EN;
|
||||
+ sensor >>= SENSOR0_SHIFT;
|
||||
+
|
||||
+ /* Constraint: There is only 1 interrupt control register for all
|
||||
+ * 11 temperature sensor. So monitoring more than 1 sensor based
|
||||
+ * on interrupts will yield inconsistent result. To overcome this
|
||||
+ * issue we will monitor only sensor 0 which is the master sensor.
|
||||
+ */
|
||||
+
|
||||
+ /* Skip if the sensor is disabled */
|
||||
+ if (sensor & 1) {
|
||||
+ ret = regmap_read(tmdev->map, tmdev->sensor[0].status, &code);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+ upper_th_x = code >= threshold;
|
||||
+ lower_th_x = code <= threshold_low;
|
||||
+ if (upper_th_x)
|
||||
+ mask |= UPPER_STATUS_CLR;
|
||||
+ if (lower_th_x)
|
||||
+ mask |= LOWER_STATUS_CLR;
|
||||
+ if (upper_th_x || lower_th_x) {
|
||||
+ /* Notify user space */
|
||||
+ schedule_work(&tmdev->sensor[0].notify_work);
|
||||
+ regmap_read(tmdev->map, sensor_addr, &adc_code);
|
||||
+ pr_debug("Trigger (%d degrees) for sensor %d\n",
|
||||
+ code_to_degC(adc_code, &tmdev->sensor[0]), 0);
|
||||
+ }
|
||||
+ }
|
||||
+ regmap_write(tmdev->map, STATUS_CNTL_8064, reg & mask);
|
||||
+
|
||||
+ /* force memory to sync */
|
||||
+ mb();
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t tsens_isr(int irq, void *data)
|
||||
+{
|
||||
+ struct tsens_device *tmdev = data;
|
||||
+
|
||||
+ schedule_work(&tmdev->tsens_work);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void hw_init(struct tsens_device *tmdev)
|
||||
+{
|
||||
+ int ret;
|
||||
+ unsigned int reg_cntl = 0, reg_cfg = 0, reg_thr = 0;
|
||||
+ unsigned int reg_status_cntl = 0;
|
||||
+
|
||||
+ regmap_read(tmdev->map, CNTL_ADDR, ®_cntl);
|
||||
+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl | TSENS_SW_RST);
|
||||
+
|
||||
+ reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18)
|
||||
+ | (((1 << tmdev->num_sensors) - 1) << SENSOR0_SHIFT);
|
||||
+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
|
||||
+ regmap_read(tmdev->map, STATUS_CNTL_8064, ®_status_cntl);
|
||||
+ reg_status_cntl |= LOWER_STATUS_CLR | UPPER_STATUS_CLR
|
||||
+ | MIN_STATUS_MASK | MAX_STATUS_MASK;
|
||||
+ regmap_write(tmdev->map, STATUS_CNTL_8064, reg_status_cntl);
|
||||
+ reg_cntl |= TSENS_EN;
|
||||
+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
|
||||
+
|
||||
+ regmap_read(tmdev->map, CONFIG_ADDR, ®_cfg);
|
||||
+ reg_cfg = (reg_cfg & ~CONFIG_MASK) | (CONFIG << CONFIG_SHIFT);
|
||||
+ regmap_write(tmdev->map, CONFIG_ADDR, reg_cfg);
|
||||
+
|
||||
+ reg_thr |= (LOWER_LIMIT_TH << THRESHOLD_LOWER_LIMIT_SHIFT)
|
||||
+ | (UPPER_LIMIT_TH << THRESHOLD_UPPER_LIMIT_SHIFT)
|
||||
+ | (MIN_LIMIT_TH << THRESHOLD_MIN_LIMIT_SHIFT)
|
||||
+ | (MAX_LIMIT_TH << THRESHOLD_MAX_LIMIT_SHIFT);
|
||||
+
|
||||
+ regmap_write(tmdev->map, THRESHOLD_ADDR, reg_thr);
|
||||
+
|
||||
+ ret = devm_request_irq(tmdev->dev, tmdev->tsens_irq, tsens_isr,
|
||||
+ IRQF_TRIGGER_RISING, "tsens_interrupt", tmdev);
|
||||
+ if (ret < 0) {
|
||||
+ pr_err("%s: request_irq FAIL: %d\n", __func__, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ INIT_WORK(&tmdev->tsens_work, tsens_scheduler_fn);
|
||||
+}
|
||||
+
|
||||
+static int init_ipq8064(struct tsens_device *tmdev)
|
||||
+{
|
||||
+ int ret, i;
|
||||
+ u32 reg_cntl, offset = 0;
|
||||
+
|
||||
+ init_common(tmdev);
|
||||
+ if (!tmdev->map)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ /*
|
||||
+ * The status registers for each sensor are discontiguous
|
||||
+ * because some SoCs have 5 sensors while others have more
|
||||
+ * but the control registers stay in the same place, i.e
|
||||
+ * directly after the first 5 status registers.
|
||||
+ */
|
||||
+ for (i = 0; i < tmdev->num_sensors; i++) {
|
||||
+ if (i >= TSENS_8064_SEQ_SENSORS)
|
||||
+ offset = TSENS_8064_S4_S5_OFFSET;
|
||||
+
|
||||
+ tmdev->sensor[i].status = S0_STATUS_ADDR + offset
|
||||
+ + (i << STATUS_ADDR_OFFSET);
|
||||
+ tmdev->sensor[i].slope = tsens_8064_slope[i];
|
||||
+ INIT_WORK(&tmdev->sensor[i].notify_work,
|
||||
+ notify_uspace_tsens_fn);
|
||||
+ }
|
||||
+
|
||||
+ reg_cntl = SW_RST;
|
||||
+ ret = regmap_update_bits(tmdev->map, CNTL_ADDR, SW_RST, reg_cntl);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
|
||||
+ reg_cntl &= ~SW_RST;
|
||||
+ ret = regmap_update_bits(tmdev->map, CONFIG_ADDR,
|
||||
+ CONFIG_MASK, CONFIG);
|
||||
+
|
||||
+ reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT;
|
||||
+ ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ reg_cntl |= EN;
|
||||
+ ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int calibrate_ipq8064(struct tsens_device *tmdev)
|
||||
+{
|
||||
+ int i;
|
||||
+ char *data, *data_backup;
|
||||
+
|
||||
+ ssize_t num_read = tmdev->num_sensors;
|
||||
+ struct tsens_sensor *s = tmdev->sensor;
|
||||
+
|
||||
+ data = qfprom_read(tmdev->dev, "calib");
|
||||
+ if (IS_ERR(data)) {
|
||||
+ pr_err("Calibration not found.\n");
|
||||
+ return PTR_ERR(data);
|
||||
+ }
|
||||
+
|
||||
+ data_backup = qfprom_read(tmdev->dev, "calib_backup");
|
||||
+ if (IS_ERR(data_backup)) {
|
||||
+ pr_err("Backup calibration not found.\n");
|
||||
+ return PTR_ERR(data_backup);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < num_read; i++) {
|
||||
+ s[i].calib_data = readb_relaxed(data + i);
|
||||
+ s[i].calib_data_backup = readb_relaxed(data_backup + i);
|
||||
+
|
||||
+ if (s[i].calib_data_backup)
|
||||
+ s[i].calib_data = s[i].calib_data_backup;
|
||||
+ if (!s[i].calib_data) {
|
||||
+ pr_err("QFPROM TSENS calibration data not present\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ s[i].slope = tsens_8064_slope[i];
|
||||
+ s[i].offset = CAL_MDEGC - (s[i].calib_data * s[i].slope);
|
||||
+ }
|
||||
+
|
||||
+ hw_init(tmdev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int get_temp_ipq8064(struct tsens_device *tmdev, int id, int *temp)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u32 code, trdy;
|
||||
+ const struct tsens_sensor *s = &tmdev->sensor[id];
|
||||
+ unsigned long timeout;
|
||||
+
|
||||
+ timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
|
||||
+ do {
|
||||
+ ret = regmap_read(tmdev->map, INT_STATUS_ADDR, &trdy);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (!(trdy & TRDY_MASK))
|
||||
+ continue;
|
||||
+ ret = regmap_read(tmdev->map, s->status, &code);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ *temp = code_to_degC(code, s);
|
||||
+ return 0;
|
||||
+ } while (time_before(jiffies, timeout));
|
||||
+
|
||||
+ return -ETIMEDOUT;
|
||||
+}
|
||||
+
|
||||
+static int set_trip_temp_ipq8064(void *data, int trip, int temp)
|
||||
+{
|
||||
+ unsigned int reg_th, reg_cntl;
|
||||
+ int ret, code, code_chk, hi_code, lo_code;
|
||||
+ const struct tsens_sensor *s = data;
|
||||
+ struct tsens_device *tmdev = s->tmdev;
|
||||
+
|
||||
+ code_chk = code = degC_to_code(temp, s);
|
||||
+
|
||||
+ if (code < THRESHOLD_MIN_CODE || code > THRESHOLD_MAX_CODE)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, ®_cntl);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_read(tmdev->map, THRESHOLD_ADDR, ®_th);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ hi_code = (reg_th & THRESHOLD_UPPER_LIMIT_MASK)
|
||||
+ >> THRESHOLD_UPPER_LIMIT_SHIFT;
|
||||
+ lo_code = (reg_th & THRESHOLD_LOWER_LIMIT_MASK)
|
||||
+ >> THRESHOLD_LOWER_LIMIT_SHIFT;
|
||||
+
|
||||
+ switch (trip) {
|
||||
+ case TSENS_TRIP_STAGE3:
|
||||
+ code <<= THRESHOLD_MAX_LIMIT_SHIFT;
|
||||
+ reg_th &= ~THRESHOLD_MAX_LIMIT_MASK;
|
||||
+ break;
|
||||
+ case TSENS_TRIP_STAGE2:
|
||||
+ if (code_chk <= lo_code)
|
||||
+ return -EINVAL;
|
||||
+ code <<= THRESHOLD_UPPER_LIMIT_SHIFT;
|
||||
+ reg_th &= ~THRESHOLD_UPPER_LIMIT_MASK;
|
||||
+ break;
|
||||
+ case TSENS_TRIP_STAGE1:
|
||||
+ if (code_chk >= hi_code)
|
||||
+ return -EINVAL;
|
||||
+ code <<= THRESHOLD_LOWER_LIMIT_SHIFT;
|
||||
+ reg_th &= ~THRESHOLD_LOWER_LIMIT_MASK;
|
||||
+ break;
|
||||
+ case TSENS_TRIP_STAGE0:
|
||||
+ code <<= THRESHOLD_MIN_LIMIT_SHIFT;
|
||||
+ reg_th &= ~THRESHOLD_MIN_LIMIT_MASK;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = regmap_write(tmdev->map, THRESHOLD_ADDR, reg_th | code);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_trip_activate_ipq8064(void *data, int trip,
|
||||
+ enum thermal_trip_activation_mode mode)
|
||||
+{
|
||||
+ unsigned int reg_cntl, mask, val;
|
||||
+ const struct tsens_sensor *s = data;
|
||||
+ struct tsens_device *tmdev = s->tmdev;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!tmdev || trip < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, ®_cntl);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ switch (trip) {
|
||||
+ case TSENS_TRIP_STAGE3:
|
||||
+ mask = MAX_STATUS_MASK;
|
||||
+ break;
|
||||
+ case TSENS_TRIP_STAGE2:
|
||||
+ mask = UPPER_STATUS_CLR;
|
||||
+ break;
|
||||
+ case TSENS_TRIP_STAGE1:
|
||||
+ mask = LOWER_STATUS_CLR;
|
||||
+ break;
|
||||
+ case TSENS_TRIP_STAGE0:
|
||||
+ mask = MIN_STATUS_MASK;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
|
||||
+ val = reg_cntl | mask;
|
||||
+ else
|
||||
+ val = reg_cntl & ~mask;
|
||||
+
|
||||
+ ret = regmap_write(tmdev->map, STATUS_CNTL_8064, val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* force memory to sync */
|
||||
+ mb();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+const struct tsens_ops ops_ipq8064 = {
|
||||
+ .init = init_ipq8064,
|
||||
+ .calibrate = calibrate_ipq8064,
|
||||
+ .get_temp = get_temp_ipq8064,
|
||||
+ .suspend = suspend_ipq8064,
|
||||
+ .resume = resume_ipq8064,
|
||||
+ .set_trip_temp = set_trip_temp_ipq8064,
|
||||
+ .set_trip_activate = set_trip_activate_ipq8064,
|
||||
+};
|
||||
+
|
||||
+const struct tsens_data data_ipq8064 = {
|
||||
+ .num_sensors = 11,
|
||||
+ .ops = &ops_ipq8064,
|
||||
+};
|
||||
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
|
||||
index 3f9fe6a..2d25593 100644
|
||||
--- a/drivers/thermal/qcom/tsens.c
|
||||
+++ b/drivers/thermal/qcom/tsens.c
|
||||
@@ -72,6 +72,9 @@ static const struct of_device_id tsens_table[] = {
|
||||
}, {
|
||||
.compatible = "qcom,msm8996-tsens",
|
||||
.data = &data_8996,
|
||||
+ }, {
|
||||
+ .compatible = "qcom,ipq8064-tsens",
|
||||
+ .data = &data_ipq8064,
|
||||
},
|
||||
{}
|
||||
};
|
||||
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
|
||||
index 911c197..31279a2 100644
|
||||
--- a/drivers/thermal/qcom/tsens.h
|
||||
+++ b/drivers/thermal/qcom/tsens.h
|
||||
@@ -89,6 +89,6 @@ void compute_intercept_slope(struct tsens_device *, u32 *, u32 *, u32);
|
||||
int init_common(struct tsens_device *);
|
||||
int get_temp_common(struct tsens_device *, int, int *);
|
||||
|
||||
-extern const struct tsens_data data_8916, data_8974, data_8960, data_8996;
|
||||
+extern const struct tsens_data data_8916, data_8974, data_8960, data_8996, data_ipq8064;
|
||||
|
||||
#endif /* __QCOM_TSENS_H__ */
|
|
@ -0,0 +1,474 @@
|
|||
From 4e87400732c77765afae2ea89ed43837457aa604 Mon Sep 17 00:00:00 2001
|
||||
From: Rajith Cherian <rajith@codeaurora.org>
|
||||
Date: Wed, 1 Feb 2017 19:00:26 +0530
|
||||
Subject: [PATCH] ipq8064: tsens: Support for configurable interrupts
|
||||
|
||||
Provide support for adding configurable high and
|
||||
configurable low trip temperatures. An interrupts is
|
||||
also triggerred when these trip points are hit. The
|
||||
interrupts can be activated or deactivated from sysfs.
|
||||
This functionality is made available only if
|
||||
CONFIG_THERMAL_WRITABLE_TRIPS is defined.
|
||||
|
||||
Change-Id: Ib73f3f9459de4fffce7bb985a0312a88291f4934
|
||||
Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
|
||||
---
|
||||
.../devicetree/bindings/thermal/qcom-tsens.txt | 4 ++
|
||||
drivers/thermal/of-thermal.c | 63 ++++++++++++++++++----
|
||||
drivers/thermal/qcom/tsens.c | 43 ++++++++++++---
|
||||
drivers/thermal/qcom/tsens.h | 11 ++++
|
||||
drivers/thermal/thermal_core.c | 44 ++++++++++++++-
|
||||
include/linux/thermal.h | 14 +++++
|
||||
6 files changed, 162 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
|
||||
index f4a76f6..7c0a6a7 100644
|
||||
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
|
||||
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
|
||||
@@ -12,11 +12,15 @@ Required properties:
|
||||
- Refer to Documentation/devicetree/bindings/nvmem/nvmem.txt to know how to specify
|
||||
nvmem cells
|
||||
|
||||
+Optional properties:
|
||||
+- interrupts: Interrupt which gets triggered when threshold is hit
|
||||
+
|
||||
Example:
|
||||
tsens: thermal-sensor@900000 {
|
||||
compatible = "qcom,msm8916-tsens";
|
||||
reg = <0x4a8000 0x2000>;
|
||||
nvmem-cells = <&tsens_caldata>, <&tsens_calsel>;
|
||||
nvmem-cell-names = "caldata", "calsel";
|
||||
+ interrupts = <0 178 0>;
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
|
||||
index d04ec3b..d83697e 100644
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -95,7 +95,7 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (!data->ops->get_temp)
|
||||
+ if (!data->ops->get_temp || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
return -EINVAL;
|
||||
|
||||
return data->ops->get_temp(data->sensor_data, temp);
|
||||
@@ -106,7 +106,8 @@ static int of_thermal_set_trips(struct thermal_zone_device *tz,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (!data->ops || !data->ops->set_trips)
|
||||
+ if (!data->ops || !data->ops->set_trips
|
||||
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
return -EINVAL;
|
||||
|
||||
return data->ops->set_trips(data->sensor_data, low, high);
|
||||
@@ -192,6 +193,9 @@ static int of_thermal_set_emul_temp(struct thermal_zone_device *tz,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
+ if (data->mode == THERMAL_DEVICE_DISABLED)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
return data->ops->set_emul_temp(data->sensor_data, temp);
|
||||
}
|
||||
|
||||
@@ -200,7 +204,7 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (!data->ops->get_trend)
|
||||
+ if (!data->ops->get_trend || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
return -EINVAL;
|
||||
|
||||
return data->ops->get_trend(data->sensor_data, trip, trend);
|
||||
@@ -286,7 +290,9 @@ static int of_thermal_set_mode(struct thermal_zone_device *tz,
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
data->mode = mode;
|
||||
- thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
|
||||
+
|
||||
+ if (mode == THERMAL_DEVICE_ENABLED)
|
||||
+ thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -296,7 +302,8 @@ static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (trip >= data->ntrips || trip < 0)
|
||||
+ if (trip >= data->ntrips || trip < 0
|
||||
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
return -EDOM;
|
||||
|
||||
*type = data->trips[trip].type;
|
||||
@@ -304,12 +311,39 @@ static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int of_thermal_activate_trip_type(struct thermal_zone_device *tz,
|
||||
+ int trip, enum thermal_trip_activation_mode mode)
|
||||
+{
|
||||
+ struct __thermal_zone *data = tz->devdata;
|
||||
+
|
||||
+ if (trip >= data->ntrips || trip < 0
|
||||
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
+ return -EDOM;
|
||||
+
|
||||
+ /*
|
||||
+ * The configurable_hi and configurable_lo trip points can be
|
||||
+ * activated and deactivated.
|
||||
+ */
|
||||
+
|
||||
+ if (data->ops->set_trip_activate) {
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = data->ops->set_trip_activate(data->sensor_data,
|
||||
+ trip, mode);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
int *temp)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (trip >= data->ntrips || trip < 0)
|
||||
+ if (trip >= data->ntrips || trip < 0
|
||||
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
return -EDOM;
|
||||
|
||||
*temp = data->trips[trip].temperature;
|
||||
@@ -322,7 +356,8 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (trip >= data->ntrips || trip < 0)
|
||||
+ if (trip >= data->ntrips || trip < 0
|
||||
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
return -EDOM;
|
||||
|
||||
if (data->ops->set_trip_temp) {
|
||||
@@ -344,7 +379,8 @@ static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (trip >= data->ntrips || trip < 0)
|
||||
+ if (trip >= data->ntrips || trip < 0
|
||||
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
return -EDOM;
|
||||
|
||||
*hyst = data->trips[trip].hysteresis;
|
||||
@@ -357,7 +393,8 @@ static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (trip >= data->ntrips || trip < 0)
|
||||
+ if (trip >= data->ntrips || trip < 0
|
||||
+ || (data->mode == THERMAL_DEVICE_DISABLED))
|
||||
return -EDOM;
|
||||
|
||||
/* thermal framework should take care of data->mask & (1 << trip) */
|
||||
@@ -432,6 +469,9 @@ thermal_zone_of_add_sensor(struct device_node *zone,
|
||||
if (ops->set_emul_temp)
|
||||
tzd->ops->set_emul_temp = of_thermal_set_emul_temp;
|
||||
|
||||
+ if (ops->set_trip_activate)
|
||||
+ tzd->ops->set_trip_activate = of_thermal_activate_trip_type;
|
||||
+
|
||||
mutex_unlock(&tzd->lock);
|
||||
|
||||
return tzd;
|
||||
@@ -726,7 +766,10 @@ static const char * const trip_types[] = {
|
||||
[THERMAL_TRIP_ACTIVE] = "active",
|
||||
[THERMAL_TRIP_PASSIVE] = "passive",
|
||||
[THERMAL_TRIP_HOT] = "hot",
|
||||
- [THERMAL_TRIP_CRITICAL] = "critical",
|
||||
+ [THERMAL_TRIP_CRITICAL] = "critical_high",
|
||||
+ [THERMAL_TRIP_CONFIGURABLE_HI] = "configurable_hi",
|
||||
+ [THERMAL_TRIP_CONFIGURABLE_LOW] = "configurable_lo",
|
||||
+ [THERMAL_TRIP_CRITICAL_LOW] = "critical_low",
|
||||
};
|
||||
|
||||
/**
|
||||
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
|
||||
index 2d25593..ac68af3 100644
|
||||
--- a/drivers/thermal/qcom/tsens.c
|
||||
+++ b/drivers/thermal/qcom/tsens.c
|
||||
@@ -31,7 +31,7 @@ static int tsens_get_temp(void *data, int *temp)
|
||||
|
||||
static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
|
||||
{
|
||||
- const struct tsens_sensor *s = p;
|
||||
+ struct tsens_sensor *s = p;
|
||||
struct tsens_device *tmdev = s->tmdev;
|
||||
|
||||
if (tmdev->ops->get_trend)
|
||||
@@ -40,9 +40,10 @@ static int tsens_get_trend(void *p, int trip, enum thermal_trend *trend)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
-static int __maybe_unused tsens_suspend(struct device *dev)
|
||||
+static int __maybe_unused tsens_suspend(void *data)
|
||||
{
|
||||
- struct tsens_device *tmdev = dev_get_drvdata(dev);
|
||||
+ struct tsens_sensor *s = data;
|
||||
+ struct tsens_device *tmdev = s->tmdev;
|
||||
|
||||
if (tmdev->ops && tmdev->ops->suspend)
|
||||
return tmdev->ops->suspend(tmdev);
|
||||
@@ -50,9 +51,10 @@ static int __maybe_unused tsens_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int __maybe_unused tsens_resume(struct device *dev)
|
||||
+static int __maybe_unused tsens_resume(void *data)
|
||||
{
|
||||
- struct tsens_device *tmdev = dev_get_drvdata(dev);
|
||||
+ struct tsens_sensor *s = data;
|
||||
+ struct tsens_device *tmdev = s->tmdev;
|
||||
|
||||
if (tmdev->ops && tmdev->ops->resume)
|
||||
return tmdev->ops->resume(tmdev);
|
||||
@@ -60,6 +62,30 @@ static int __maybe_unused tsens_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int __maybe_unused tsens_set_trip_temp(void *data, int trip, int temp)
|
||||
+{
|
||||
+ struct tsens_sensor *s = data;
|
||||
+ struct tsens_device *tmdev = s->tmdev;
|
||||
+
|
||||
+ if (tmdev->ops && tmdev->ops->set_trip_temp)
|
||||
+ return tmdev->ops->set_trip_temp(s, trip, temp);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused tsens_activate_trip_type(void *data, int trip,
|
||||
+ enum thermal_trip_activation_mode mode)
|
||||
+{
|
||||
+ struct tsens_sensor *s = data;
|
||||
+ struct tsens_device *tmdev = s->tmdev;
|
||||
+
|
||||
+ if (tmdev->ops && tmdev->ops->set_trip_activate)
|
||||
+ return tmdev->ops->set_trip_activate(s, trip, mode);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
|
||||
|
||||
static const struct of_device_id tsens_table[] = {
|
||||
@@ -83,6 +109,8 @@ MODULE_DEVICE_TABLE(of, tsens_table);
|
||||
static const struct thermal_zone_of_device_ops tsens_of_ops = {
|
||||
.get_temp = tsens_get_temp,
|
||||
.get_trend = tsens_get_trend,
|
||||
+ .set_trip_temp = tsens_set_trip_temp,
|
||||
+ .set_trip_activate = tsens_activate_trip_type,
|
||||
};
|
||||
|
||||
static int tsens_register(struct tsens_device *tmdev)
|
||||
@@ -131,7 +159,7 @@ static int tsens_probe(struct platform_device *pdev)
|
||||
if (id)
|
||||
data = id->data;
|
||||
else
|
||||
- data = &data_8960;
|
||||
+ return -EINVAL;
|
||||
|
||||
if (data->num_sensors <= 0) {
|
||||
dev_err(dev, "invalid number of sensors\n");
|
||||
@@ -146,6 +174,9 @@ static int tsens_probe(struct platform_device *pdev)
|
||||
tmdev->dev = dev;
|
||||
tmdev->num_sensors = data->num_sensors;
|
||||
tmdev->ops = data->ops;
|
||||
+
|
||||
+ tmdev->tsens_irq = platform_get_irq(pdev, 0);
|
||||
+
|
||||
for (i = 0; i < tmdev->num_sensors; i++) {
|
||||
if (data->hw_ids)
|
||||
tmdev->sensor[i].hw_id = data->hw_ids[i];
|
||||
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
|
||||
index 31279a2..54bbdc0 100644
|
||||
--- a/drivers/thermal/qcom/tsens.h
|
||||
+++ b/drivers/thermal/qcom/tsens.h
|
||||
@@ -24,9 +24,12 @@ struct tsens_device;
|
||||
struct tsens_sensor {
|
||||
struct tsens_device *tmdev;
|
||||
struct thermal_zone_device *tzd;
|
||||
+ struct work_struct notify_work;
|
||||
int offset;
|
||||
int id;
|
||||
int hw_id;
|
||||
+ int calib_data;
|
||||
+ int calib_data_backup;
|
||||
int slope;
|
||||
u32 status;
|
||||
};
|
||||
@@ -41,6 +44,9 @@ struct tsens_sensor {
|
||||
* @suspend: Function to suspend the tsens device
|
||||
* @resume: Function to resume the tsens device
|
||||
* @get_trend: Function to get the thermal/temp trend
|
||||
+ * @set_trip_temp: Function to set trip temp
|
||||
+ * @get_trip_temp: Function to get trip temp
|
||||
+ * @set_trip_activate: Function to activate trip points
|
||||
*/
|
||||
struct tsens_ops {
|
||||
/* mandatory callbacks */
|
||||
@@ -53,6 +59,9 @@ struct tsens_ops {
|
||||
int (*suspend)(struct tsens_device *);
|
||||
int (*resume)(struct tsens_device *);
|
||||
int (*get_trend)(struct tsens_device *, int, enum thermal_trend *);
|
||||
+ int (*set_trip_temp)(void *, int, int);
|
||||
+ int (*set_trip_activate)(void *, int,
|
||||
+ enum thermal_trip_activation_mode);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -76,11 +85,13 @@ struct tsens_context {
|
||||
struct tsens_device {
|
||||
struct device *dev;
|
||||
u32 num_sensors;
|
||||
+ u32 tsens_irq;
|
||||
struct regmap *map;
|
||||
struct regmap_field *status_field;
|
||||
struct tsens_context ctx;
|
||||
bool trdy;
|
||||
const struct tsens_ops *ops;
|
||||
+ struct work_struct tsens_work;
|
||||
struct tsens_sensor sensor[0];
|
||||
};
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 226b0b4..20bd624 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -732,12 +732,48 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
|
||||
return sprintf(buf, "passive\n");
|
||||
case THERMAL_TRIP_ACTIVE:
|
||||
return sprintf(buf, "active\n");
|
||||
+ case THERMAL_TRIP_CONFIGURABLE_HI:
|
||||
+ return sprintf(buf, "configurable_hi\n");
|
||||
+ case THERMAL_TRIP_CONFIGURABLE_LOW:
|
||||
+ return sprintf(buf, "configurable_low\n");
|
||||
+ case THERMAL_TRIP_CRITICAL_LOW:
|
||||
+ return sprintf(buf, "critical_low\n");
|
||||
default:
|
||||
return sprintf(buf, "unknown\n");
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
+trip_point_type_activate(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||
+ int trip, ret;
|
||||
+ char *enabled = "enabled";
|
||||
+ char *disabled = "disabled";
|
||||
+
|
||||
+ if (!tz->ops->set_trip_activate)
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!strncmp(buf, enabled, strlen(enabled)))
|
||||
+ ret = tz->ops->set_trip_activate(tz, trip,
|
||||
+ THERMAL_TRIP_ACTIVATION_ENABLED);
|
||||
+ else if (!strncmp(buf, disabled, strlen(disabled)))
|
||||
+ ret = tz->ops->set_trip_activate(tz, trip,
|
||||
+ THERMAL_TRIP_ACTIVATION_DISABLED);
|
||||
+ else
|
||||
+ ret = -EINVAL;
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static ssize_t
|
||||
trip_point_temp_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
@@ -1321,7 +1357,7 @@ thermal_cooling_device_weight_store(struct device *dev,
|
||||
*/
|
||||
int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
|
||||
int trip,
|
||||
- struct thermal_cooling_device *cdev,
|
||||
+ struct thermal_cooling_device *cdev,
|
||||
unsigned long upper, unsigned long lower,
|
||||
unsigned int weight)
|
||||
{
|
||||
@@ -1772,6 +1808,12 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
||||
tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO;
|
||||
tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
|
||||
|
||||
+ if (IS_ENABLED(CONFIG_THERMAL_WRITABLE_TRIPS)) {
|
||||
+ tz->trip_type_attrs[indx].attr.store
|
||||
+ = trip_point_type_activate;
|
||||
+ tz->trip_type_attrs[indx].attr.attr.mode |= S_IWUSR;
|
||||
+ }
|
||||
+
|
||||
device_create_file(&tz->device,
|
||||
&tz->trip_type_attrs[indx].attr);
|
||||
|
||||
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
|
||||
index 511182a..510a087 100644
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -77,11 +77,19 @@ enum thermal_device_mode {
|
||||
THERMAL_DEVICE_ENABLED,
|
||||
};
|
||||
|
||||
+enum thermal_trip_activation_mode {
|
||||
+ THERMAL_TRIP_ACTIVATION_DISABLED = 0,
|
||||
+ THERMAL_TRIP_ACTIVATION_ENABLED,
|
||||
+};
|
||||
+
|
||||
enum thermal_trip_type {
|
||||
THERMAL_TRIP_ACTIVE = 0,
|
||||
THERMAL_TRIP_PASSIVE,
|
||||
THERMAL_TRIP_HOT,
|
||||
THERMAL_TRIP_CRITICAL,
|
||||
+ THERMAL_TRIP_CONFIGURABLE_HI,
|
||||
+ THERMAL_TRIP_CONFIGURABLE_LOW,
|
||||
+ THERMAL_TRIP_CRITICAL_LOW,
|
||||
};
|
||||
|
||||
enum thermal_trend {
|
||||
@@ -118,6 +126,8 @@ struct thermal_zone_device_ops {
|
||||
enum thermal_trip_type *);
|
||||
int (*get_trip_temp) (struct thermal_zone_device *, int, int *);
|
||||
int (*set_trip_temp) (struct thermal_zone_device *, int, int);
|
||||
+ int (*set_trip_activate) (struct thermal_zone_device *, int,
|
||||
+ enum thermal_trip_activation_mode);
|
||||
int (*get_trip_hyst) (struct thermal_zone_device *, int, int *);
|
||||
int (*set_trip_hyst) (struct thermal_zone_device *, int, int);
|
||||
int (*get_crit_temp) (struct thermal_zone_device *, int *);
|
||||
@@ -360,6 +370,8 @@ struct thermal_genl_event {
|
||||
* temperature.
|
||||
* @set_trip_temp: a pointer to a function that sets the trip temperature on
|
||||
* hardware.
|
||||
+ * @activate_trip_type: a pointer to a function to enable/disable trip
|
||||
+ * temperature interrupts
|
||||
*/
|
||||
struct thermal_zone_of_device_ops {
|
||||
int (*get_temp)(void *, int *);
|
||||
@@ -367,6 +379,8 @@ struct thermal_zone_of_device_ops {
|
||||
int (*set_trips)(void *, int, int);
|
||||
int (*set_emul_temp)(void *, int);
|
||||
int (*set_trip_temp)(void *, int, int);
|
||||
+ int (*set_trip_activate)(void *, int,
|
||||
+ enum thermal_trip_activation_mode);
|
||||
};
|
||||
|
||||
/**
|
|
@ -1,46 +0,0 @@
|
|||
From 3064376aa3e8dae03dc2c5c3c064e2283c4337d8 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Kubelun <be.dissent@gmail.com>
|
||||
Date: Tue, 22 Nov 2016 17:37:56 +0300
|
||||
Subject: [PATCH 63/69] ipq806x: clk: gcc: add tsens child node
|
||||
|
||||
Thermal sensors in ipq806x are inside a Global clock controller.
|
||||
Add a child node into it to be used by the TSENS driver.
|
||||
|
||||
Signed-off-by: Pavel Kubelun <be.dissent@gmail.com>
|
||||
---
|
||||
drivers/clk/qcom/gcc-ipq806x.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/clk/qcom/gcc-ipq806x.c
|
||||
+++ b/drivers/clk/qcom/gcc-ipq806x.c
|
||||
@@ -970,7 +970,7 @@ static struct clk_branch gsbi1_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi1_h_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
-+ .flags = CLK_IGNORE_UNUSED,
|
||||
+ .flags = CLK_IGNORE_UNUSED,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -3073,6 +3073,7 @@ MODULE_DEVICE_TABLE(of, gcc_ipq806x_matc
|
||||
static int gcc_ipq806x_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
+ struct platform_device *tsens;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
@@ -3102,6 +3103,13 @@ static int gcc_ipq806x_probe(struct plat
|
||||
regmap_write(regmap, 0x3cf8, 8);
|
||||
regmap_write(regmap, 0x3d18, 8);
|
||||
|
||||
+ tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1,
|
||||
+ NULL, 0);
|
||||
+ if (IS_ERR(tsens))
|
||||
+ return PTR_ERR(tsens);
|
||||
+
|
||||
+ platform_set_drvdata(pdev, tsens);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in a new issue