diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 19:21:18 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 19:21:18 +0200 |
commit | d01e12dd3f4227f1be5d7c5bffa7b8240787bec1 (patch) | |
tree | 30a2d1684d8cfb4f5f3be3bf991c563f1559ab1c /drivers/thermal/qcom | |
parent | Merge tag 'mailbox-v4.19' of git://git.linaro.org/landing-teams/working/fujit... (diff) | |
parent | thermal: armada: fix copy-paste error in armada_thermal_probe() (diff) | |
download | linux-d01e12dd3f4227f1be5d7c5bffa7b8240787bec1.tar.xz linux-d01e12dd3f4227f1be5d7c5bffa7b8240787bec1.zip |
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal
Pull thermal management updates from Eduardo Valentin:
- rework tsens driver to add support for tsens-v2 (Amit Kucheria)
- rework armada thermal driver to use syscon and multichannel support
(Miquel Raynal)
- fixes to TI SoC, IMX, Exynos, RCar, and hwmon drivers
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (34 commits)
thermal: armada: fix copy-paste error in armada_thermal_probe()
thermal: rcar_thermal: avoid NULL dereference in absence of IRQ resources
thermal: samsung: Remove Exynos5440 clock handling left-overs
thermal: tsens: Fix negative temperature reporting
thermal: tsens: switch from of_iomap() to devm_ioremap_resource()
thermal: tsens: Rename variable
thermal: tsens: Add generic support for TSENS v2 IP
thermal: tsens: Rename tsens-8996 to tsens-v2 for reuse
thermal: tsens: Add support to split up register address space into two
dt: thermal: tsens: Document the fallback DT property for v2 of TSENS IP
thermal: tsens: Get rid of unused fields in structure
thermal_hwmon: Pass the originating device down to hwmon_device_register_with_info
thermal_hwmon: Sanitize attribute name passed to hwmon
dt-bindings: thermal: armada: add reference to new bindings
dt-bindings: cp110: add the thermal node in the syscon file
dt-bindings: cp110: update documentation since DT de-duplication
dt-bindings: ap806: add the thermal node in the syscon file
dt-bindings: cp110: prepare the syscon file to list other syscons nodes
dt-bindings: ap806: prepare the syscon file to list other syscons nodes
dt-bindings: cp110: rename cp110 syscon file
...
Diffstat (limited to 'drivers/thermal/qcom')
-rw-r--r-- | drivers/thermal/qcom/Makefile | 2 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens-8996.c | 84 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens-common.c | 29 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens-v2.c | 77 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens.c | 3 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens.h | 8 |
6 files changed, 107 insertions, 96 deletions
diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile index 2cc2193637e7..a821929ede0b 100644 --- a/drivers/thermal/qcom/Makefile +++ b/drivers/thermal/qcom/Makefile @@ -1,2 +1,2 @@ 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-v2.o diff --git a/drivers/thermal/qcom/tsens-8996.c b/drivers/thermal/qcom/tsens-8996.c deleted file mode 100644 index e1f77818d8fa..000000000000 --- a/drivers/thermal/qcom/tsens-8996.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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/regmap.h> -#include "tsens.h" - -#define STATUS_OFFSET 0x10a0 -#define LAST_TEMP_MASK 0xfff -#define STATUS_VALID_BIT BIT(21) -#define CODE_SIGN_BIT BIT(11) - -static int get_temp_8996(struct tsens_device *tmdev, int id, int *temp) -{ - struct tsens_sensor *s = &tmdev->sensor[id]; - u32 code; - unsigned int sensor_addr; - int last_temp = 0, last_temp2 = 0, last_temp3 = 0, ret; - - sensor_addr = STATUS_OFFSET + s->hw_id * 4; - ret = regmap_read(tmdev->map, sensor_addr, &code); - if (ret) - return ret; - last_temp = code & LAST_TEMP_MASK; - if (code & STATUS_VALID_BIT) - goto done; - - /* Try a second time */ - ret = regmap_read(tmdev->map, sensor_addr, &code); - if (ret) - return ret; - if (code & STATUS_VALID_BIT) { - last_temp = code & LAST_TEMP_MASK; - goto done; - } else { - last_temp2 = code & LAST_TEMP_MASK; - } - - /* Try a third/last time */ - ret = regmap_read(tmdev->map, sensor_addr, &code); - if (ret) - return ret; - if (code & STATUS_VALID_BIT) { - last_temp = code & LAST_TEMP_MASK; - goto done; - } else { - last_temp3 = code & LAST_TEMP_MASK; - } - - if (last_temp == last_temp2) - last_temp = last_temp2; - else if (last_temp2 == last_temp3) - last_temp = last_temp3; -done: - /* Code sign bit is the sign extension for a negative value */ - if (last_temp & CODE_SIGN_BIT) - last_temp |= ~CODE_SIGN_BIT; - - /* Temperatures are in deciCelicius */ - *temp = last_temp * 100; - - return 0; -} - -static const struct tsens_ops ops_8996 = { - .init = init_common, - .get_temp = get_temp_8996, -}; - -const struct tsens_data data_8996 = { - .num_sensors = 13, - .ops = &ops_8996, -}; diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c index b1449ad67fc0..6207d8d92351 100644 --- a/drivers/thermal/qcom/tsens-common.c +++ b/drivers/thermal/qcom/tsens-common.c @@ -16,6 +16,7 @@ #include <linux/io.h> #include <linux/nvmem-consumer.h> #include <linux/of_address.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/regmap.h> #include "tsens.h" @@ -103,11 +104,11 @@ int get_temp_common(struct tsens_device *tmdev, int id, int *temp) { struct tsens_sensor *s = &tmdev->sensor[id]; u32 code; - unsigned int sensor_addr; + unsigned int status_reg; int last_temp = 0, ret; - sensor_addr = S0_ST_ADDR + s->hw_id * SN_ADDR_OFFSET; - ret = regmap_read(tmdev->map, sensor_addr, &code); + status_reg = S0_ST_ADDR + s->hw_id * SN_ADDR_OFFSET; + ret = regmap_read(tmdev->map, status_reg, &code); if (ret) return ret; last_temp = code & SN_ST_TEMP_MASK; @@ -126,16 +127,28 @@ static const struct regmap_config tsens_config = { int __init init_common(struct tsens_device *tmdev) { void __iomem *base; + struct resource *res; + struct platform_device *op = of_find_device_by_node(tmdev->dev->of_node); - base = of_iomap(tmdev->dev->of_node, 0); - if (!base) + if (!op) return -EINVAL; + /* The driver only uses the TM register address space for now */ + if (op->num_resources > 1) { + tmdev->tm_offset = 0; + } else { + /* old DTs where SROT and TM were in a contiguous 2K block */ + tmdev->tm_offset = 0x1000; + } + + res = platform_get_resource(op, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&op->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + tmdev->map = devm_regmap_init_mmio(tmdev->dev, base, &tsens_config); - if (IS_ERR(tmdev->map)) { - iounmap(base); + if (IS_ERR(tmdev->map)) return PTR_ERR(tmdev->map); - } return 0; } diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c new file mode 100644 index 000000000000..44da02f594ac --- /dev/null +++ b/drivers/thermal/qcom/tsens-v2.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2018, Linaro Limited + */ + +#include <linux/regmap.h> +#include <linux/bitops.h> +#include "tsens.h" + +#define STATUS_OFFSET 0xa0 +#define LAST_TEMP_MASK 0xfff +#define STATUS_VALID_BIT BIT(21) + +static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp) +{ + struct tsens_sensor *s = &tmdev->sensor[id]; + u32 code; + unsigned int status_reg; + u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0; + int ret; + + status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4; + ret = regmap_read(tmdev->map, status_reg, &code); + if (ret) + return ret; + last_temp = code & LAST_TEMP_MASK; + if (code & STATUS_VALID_BIT) + goto done; + + /* Try a second time */ + ret = regmap_read(tmdev->map, status_reg, &code); + if (ret) + return ret; + if (code & STATUS_VALID_BIT) { + last_temp = code & LAST_TEMP_MASK; + goto done; + } else { + last_temp2 = code & LAST_TEMP_MASK; + } + + /* Try a third/last time */ + ret = regmap_read(tmdev->map, status_reg, &code); + if (ret) + return ret; + if (code & STATUS_VALID_BIT) { + last_temp = code & LAST_TEMP_MASK; + goto done; + } else { + last_temp3 = code & LAST_TEMP_MASK; + } + + if (last_temp == last_temp2) + last_temp = last_temp2; + else if (last_temp2 == last_temp3) + last_temp = last_temp3; +done: + /* Convert temperature from deciCelsius to milliCelsius */ + *temp = sign_extend32(last_temp, fls(LAST_TEMP_MASK) - 1) * 100; + + return 0; +} + +static const struct tsens_ops ops_generic_v2 = { + .init = init_common, + .get_temp = get_temp_tsens_v2, +}; + +const struct tsens_data data_tsens_v2 = { + .ops = &ops_generic_v2, +}; + +/* Kept around for backward compatibility with old msm8996.dtsi */ +const struct tsens_data data_8996 = { + .num_sensors = 13, + .ops = &ops_generic_v2, +}; diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 3440166c2ae9..a2c9bfae3d86 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,tsens-v2", + .data = &data_tsens_v2, }, {} }; diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index 911c1978892b..14331eb45a86 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -77,9 +77,8 @@ struct tsens_device { struct device *dev; u32 num_sensors; struct regmap *map; - struct regmap_field *status_field; + u32 tm_offset; struct tsens_context ctx; - bool trdy; const struct tsens_ops *ops; struct tsens_sensor sensor[0]; }; @@ -89,6 +88,9 @@ 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; +/* TSENS v1 targets */ +extern const struct tsens_data data_8916, data_8974, data_8960; +/* TSENS v2 targets */ +extern const struct tsens_data data_8996, data_tsens_v2; #endif /* __QCOM_TSENS_H__ */ |