linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] qcom: Add support for TSENS driver
@ 2015-07-08  9:47 Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 1/9] thermal: qcom: tsens: Add a skeletal TSENS drivers Rajendra Nayak
                   ` (9 more replies)
  0 siblings, 10 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

Changes since RFC:
* Added support for 8916 and 8084
* Based off the latest nvmem framework patches [1]
* Minor review fixes for comments mostly from Lina

** I have also added irq support using the hardware
trip point support series [2]. Will post that
out seperately.

This is an attempt to have a single TSENS driver for
the different versions of the TSENS IP that exist, on
different qcom msm/apq SoCs'
Support is added for msm8916, msm8960 and msm8974 families.
Based on top of the latest nvmem framework patches [2]

A lot of the work is based of original code from Stephen Boyd
and Siddartha Mohanadoss. I have also picked some of what
Narendran Rajan did in his attempt to upstream the support
for 8960 family. I could not keep the original authorship on
any of the patches because I ended up moving the code around
quite a bit in an effort to have a single driver for the
various devices. I would be glad to change the authorship
for any of the patches if needed.

[1] https://lkml.org/lkml/2015/6/22/609
[2] https://lkml.org/lkml/2015/5/20/472

Rajendra Nayak (8):
  thermal: qcom: tsens: Add a skeletal TSENS drivers
  thermal: qcom: tsens-8916: Add support for 8916 family of SoCs
  thermal: qcom: tsens-8974: Add support for 8974 family of SoCs
  thermal: qcom: tsens-8960: Add support for 8960 family of SoCs
  arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes
  arm: dts: apq8064: Add thermal zones, tsens and eeprom nodes
  arm: dts: apq8084: Add thermal zones, tsens and eeprom nodes
  arm64: dts: msm8916: Add thermal zones, tsens and eeprom nodes

Srinivas Kandagatla (1):
  clk: qcom: gcc-msm8960: add child devices support.

 .../devicetree/bindings/thermal/qcom-tsens.txt     |  37 +++
 arch/arm/boot/dts/qcom-apq8064.dtsi                | 108 ++++++++
 arch/arm/boot/dts/qcom-apq8084.dtsi                | 105 ++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi                | 105 ++++++++
 arch/arm64/boot/dts/qcom/msm8916.dtsi              |  66 +++++
 drivers/clk/qcom/gcc-msm8960.c                     |   4 +-
 drivers/thermal/Kconfig                            |   5 +
 drivers/thermal/Makefile                           |   1 +
 drivers/thermal/qcom/Kconfig                       |  10 +
 drivers/thermal/qcom/Makefile                      |   2 +
 drivers/thermal/qcom/tsens-8916.c                  | 107 ++++++++
 drivers/thermal/qcom/tsens-8960.c                  | 291 +++++++++++++++++++++
 drivers/thermal/qcom/tsens-8974.c                  | 239 +++++++++++++++++
 drivers/thermal/qcom/tsens-common.c                | 128 +++++++++
 drivers/thermal/qcom/tsens.c                       | 209 +++++++++++++++
 drivers/thermal/qcom/tsens.h                       |  69 +++++
 16 files changed, 1485 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
 create mode 100644 drivers/thermal/qcom/Kconfig
 create mode 100644 drivers/thermal/qcom/Makefile
 create mode 100644 drivers/thermal/qcom/tsens-8916.c
 create mode 100644 drivers/thermal/qcom/tsens-8960.c
 create mode 100644 drivers/thermal/qcom/tsens-8974.c
 create mode 100644 drivers/thermal/qcom/tsens-common.c
 create mode 100644 drivers/thermal/qcom/tsens.c
 create mode 100644 drivers/thermal/qcom/tsens.h

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 1/9] thermal: qcom: tsens: Add a skeletal TSENS drivers
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 2/9] thermal: qcom: tsens-8916: Add support for 8916 family of SoCs Rajendra Nayak
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

TSENS is Qualcomms' thermal temperature sensor device. It
supports reading temperatures from multiple thermal sensors
present on various QCOM SoCs.
Calibration data is generally read from a eeprom device.

Add a skeleton driver with all the necessary abstractions so
a variety of qcom device families which support TSENS can
add driver extensions.

Also add the required device tree bindings which can be used
to descibe the TSENS device in DT.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Reviewed-by: Lina Iyer <lina.iyer@linaro.org>
---
 .../devicetree/bindings/thermal/qcom-tsens.txt     |  37 ++++
 drivers/thermal/Kconfig                            |   5 +
 drivers/thermal/Makefile                           |   1 +
 drivers/thermal/qcom/Kconfig                       |  10 +
 drivers/thermal/qcom/Makefile                      |   2 +
 drivers/thermal/qcom/tsens.c                       | 207 +++++++++++++++++++++
 drivers/thermal/qcom/tsens.h                       |  58 ++++++
 7 files changed, 320 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
 create mode 100644 drivers/thermal/qcom/Kconfig
 create mode 100644 drivers/thermal/qcom/Makefile
 create mode 100644 drivers/thermal/qcom/tsens.c
 create mode 100644 drivers/thermal/qcom/tsens.h

diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
new file mode 100644
index 0000000..cfb79fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
@@ -0,0 +1,37 @@
+* QCOM SoC Temperature Sensor (TSENS)
+
+Required properties:
+- compatible :
+ - "qcom,msm8916-tsens" : For 8916 Family of SoCs
+ - "qcom,msm8974-tsens" : For 8974 Family of SoCs
+ - "qcom,msm8960-tsens" : For 8960 Family of SoCs
+
+- reg: Address range of the thermal registers
+- qcom,tsens-slopes : Must contain slope value for each of the sensors controlled
+			by this device
+- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
+- Refer to Documentation/devicetree/bindings/eeprom/eeprom.txt to know how to specify
+an eeprom cell
+
+Optional properties:
+- qcom,sensor-id: List of sensor instances used in a given SoC. A TSENS IP can
+		  have a fixed number of sensors (like 11) but a given SoC can
+		  use only 5 of these and they might not always the first 5. They
+		  could be sensors 0, 1, 4, 8 and 9. This property is used to
+		  describe the subset of the sensors used. If this property is
+		  missing they are assumed to be the first 'n' sensors numbered
+		  sequentially in which case the number of sensors defaults to
+		  the number of slope values.
+
+Example:
+tsens: thermal-sensor at 900000 {
+		compatible = "qcom,msm8916-tsens";
+		qcom,tsens-slopes = <1176 1176 1154 1176 1111
+				1132 1132 1199 1132 1199
+				1132>;
+		calib_data = <&tsens_caldata>;
+		calib_sel = <&tsens_calsel>;
+		qcom,tsens-slopes = <3200 3200 3200 3200 3200>;
+		qcom,sensor-id = <0 1 2 4 5>;
+		#thermal-sensor-cells = <1>;
+	};
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 118938e..8f47021 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -365,4 +365,9 @@ config QCOM_SPMI_TEMP_ALARM
 	  real time die temperature if an ADC is present or an estimate of the
 	  temperature based upon the over temperature stage value.
 
+menu "Qualcomm thermal drivers"
+depends on ARCH_QCOM && OF
+source "drivers/thermal/qcom/Kconfig"
+endmenu
+
 endif
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 535dfee..011fa57 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -42,5 +42,6 @@ obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)	+= intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)	+= ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
 obj-$(CONFIG_ST_THERMAL)	+= st/
+obj-$(CONFIG_QCOM_TSENS)	+= qcom/
 obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
 obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
diff --git a/drivers/thermal/qcom/Kconfig b/drivers/thermal/qcom/Kconfig
new file mode 100644
index 0000000..9bfde94e
--- /dev/null
+++ b/drivers/thermal/qcom/Kconfig
@@ -0,0 +1,10 @@
+config QCOM_TSENS
+	tristate "Qualcomm TSENS Temperature Alarm"
+	depends on THERMAL
+	depends on QCOM_QFPROM
+	help
+	  This enables the thermal sysfs driver for the Tsens device. It shows
+	  up in Sysfs as a thermal zone with multiple trip points. Disabling the
+	  thermal zone device via the mode file results in disabling the sensor.
+	  Also able to set threshold temperature for both hot and cold and update
+	  when a threshold is reached.
diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
new file mode 100644
index 0000000..401069b
--- /dev/null
+++ b/drivers/thermal/qcom/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_QCOM_TSENS)	+= qcom_tsens.o
+qcom_tsens-y			+= tsens.o
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
new file mode 100644
index 0000000..d32d278
--- /dev/null
+++ b/drivers/thermal/qcom/tsens.c
@@ -0,0 +1,207 @@
+/*
+ * 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/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+#include "tsens.h"
+
+static int tsens_get_temp(void *data, long *temp)
+{
+	const struct tsens_sensor *s = data;
+	struct tsens_device *tmdev = s->tmdev;
+
+	return tmdev->ops->get_temp(tmdev, s->id, temp);
+}
+
+static int tsens_get_trend(void *data, long *temp)
+{
+	const struct tsens_sensor *s = data;
+	struct tsens_device *tmdev = s->tmdev;
+
+	if (tmdev->ops->get_trend)
+		return tmdev->ops->get_trend(tmdev, s->id, temp);
+
+	return -ENOSYS;
+}
+
+#ifdef CONFIG_PM
+static int tsens_suspend(struct device *dev)
+{
+	struct tsens_device *tmdev = dev_get_drvdata(dev);
+
+	if (tmdev->ops && tmdev->ops->suspend)
+		return tmdev->ops->suspend(tmdev);
+
+	return 0;
+}
+
+static int tsens_resume(struct device *dev)
+{
+	struct tsens_device *tmdev = dev_get_drvdata(dev);
+
+	if (tmdev->ops && tmdev->ops->resume)
+		return tmdev->ops->resume(tmdev);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
+#define TSENS_PM_OPS   (&tsens_pm_ops)
+
+#else /* CONFIG_PM_SLEEP */
+#define TSENS_PM_OPS NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct of_device_id tsens_table[] = {
+	{
+		.compatible = "qcom,msm8960-tsens",
+	}, {
+		.compatible = "qcom,msm8916-tsens",
+		.data = &ops_8916,
+	}, {
+		.compatible = "qcom,msm8974-tsens",
+	},
+	{}
+};
+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,
+};
+
+static int tsens_register(struct tsens_device *tmdev)
+{
+	int i, ret;
+	struct thermal_zone_device *tzd;
+	u32 *hw_id, n = tmdev->num_sensors;
+	struct device_node *np = tmdev->dev->of_node;
+
+	hw_id = devm_kcalloc(tmdev->dev, n, sizeof(u32), GFP_KERNEL);
+	if (!hw_id)
+		return -ENOMEM;
+
+	ret = of_property_read_u32_array(np, "qcom,sensor-id", hw_id, n);
+	if (ret)
+		for (i = 0;  i < tmdev->num_sensors; i++)
+			tmdev->sensor[i].hw_id = i;
+	else
+		for (i = 0;  i < tmdev->num_sensors; i++)
+			tmdev->sensor[i].hw_id = hw_id[i];
+
+	for (i = 0;  i < tmdev->num_sensors; i++) {
+		tmdev->sensor[i].tmdev = tmdev;
+		tmdev->sensor[i].id = i;
+		tzd = thermal_zone_of_sensor_register(tmdev->dev, i,
+						      &tmdev->sensor[i],
+						      &tsens_of_ops);
+		if (IS_ERR(tzd))
+			continue;
+		tmdev->sensor[i].tzd = tzd;
+		if (tmdev->ops->enable)
+			tmdev->ops->enable(tmdev, i);
+	}
+	return 0;
+}
+
+static int tsens_probe(struct platform_device *pdev)
+{
+	int ret, i, num;
+	struct device_node *np = pdev->dev.of_node;
+	struct tsens_sensor *s;
+	struct tsens_device *tmdev;
+	const struct of_device_id *id;
+
+	num = of_property_count_u32_elems(np, "qcom,tsens-slopes");
+	if (num <= 0) {
+		dev_err(&pdev->dev, "invalid tsens slopes\n");
+		return -EINVAL;
+	}
+
+	tmdev = devm_kzalloc(&pdev->dev, sizeof(*tmdev) +
+			     num * sizeof(*s), GFP_KERNEL);
+	if (!tmdev)
+		return -ENOMEM;
+
+	tmdev->dev = &pdev->dev;
+	tmdev->num_sensors = num;
+
+	for (i = 0, s = tmdev->sensor; i < tmdev->num_sensors; i++, s++)
+		of_property_read_u32_index(np, "qcom,tsens-slopes", i,
+					   &s->slope);
+
+	id = of_match_node(tsens_table, np);
+	if (!id)
+		return -ENODEV;
+
+	tmdev->ops = id->data;
+	if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->calibrate ||
+	    !tmdev->ops->get_temp)
+		return -EINVAL;
+
+	ret = tmdev->ops->init(tmdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "tsens init failed\n");
+		return ret;
+	}
+
+	ret = tmdev->ops->calibrate(tmdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "tsens calibration failed\n");
+		return ret;
+	}
+
+	ret = tsens_register(tmdev);
+
+	platform_set_drvdata(pdev, tmdev);
+
+	return ret;
+}
+
+static int tsens_remove(struct platform_device *pdev)
+{
+	int i;
+	struct tsens_device *tmdev = platform_get_drvdata(pdev);
+	struct thermal_zone_device *tzd;
+
+	if (tmdev->ops->disable)
+		tmdev->ops->disable(tmdev);
+
+	for (i = 0; i < tmdev->num_sensors; i++) {
+		tzd = tmdev->sensor[i].tzd;
+		thermal_zone_of_sensor_unregister(&pdev->dev, tzd);
+	}
+
+	return 0;
+}
+
+static struct platform_driver tsens_driver = {
+	.probe = tsens_probe,
+	.remove = tsens_remove,
+	.driver = {
+		.name = "qcom-tsens",
+		.pm	= TSENS_PM_OPS,
+		.of_match_table = tsens_table,
+	},
+};
+module_platform_driver(tsens_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("QCOM Temperature Sensor driver");
+MODULE_ALIAS("platform:qcom-tsens");
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
new file mode 100644
index 0000000..9b274e1
--- /dev/null
+++ b/drivers/thermal/qcom/tsens.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+#ifndef __QCOM_TSENS_H__
+#define __QCOM_TSENS_H__
+
+struct tsens_device;
+
+struct tsens_sensor {
+	struct tsens_device		*tmdev;
+	struct thermal_zone_device	*tzd;
+	int				offset;
+	int				id;
+	int				hw_id;
+	u32				slope;
+	u32				status;
+};
+
+struct tsens_ops {
+	/* mandatory callbacks */
+	int (*init)(struct tsens_device *);
+	int (*calibrate)(struct tsens_device *);
+	int (*get_temp)(struct tsens_device *, int, long *);
+	/* optional callbacks */
+	int (*enable)(struct tsens_device *, int);
+	void (*disable)(struct tsens_device *);
+	int (*suspend)(struct tsens_device *);
+	int (*resume)(struct tsens_device *);
+	int (*get_trend)(struct tsens_device *, int, long *);
+};
+
+/* Registers to be saved/restored across a context loss */
+struct tsens_context {
+	int	threshold;
+	int	control;
+};
+
+struct tsens_device {
+	struct device			*dev;
+	u32				num_sensors;
+	struct regmap			*map;
+	struct regmap_field		*status_field;
+	struct tsens_context		ctx;
+	bool				trdy;
+	const struct tsens_ops		*ops;
+	struct tsens_sensor		sensor[0];
+};
+
+#endif /* __QCOM_TSENS_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 2/9] thermal: qcom: tsens-8916: Add support for 8916 family of SoCs
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 1/9] thermal: qcom: tsens: Add a skeletal TSENS drivers Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 3/9] thermal: qcom: tsens-8974: Add support for 8974 " Rajendra Nayak
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

Add support to calibrate sensors on 8916 family and also add common
functions to read temperature from sensors (This can be reused on
other SoCs having similar TSENS device)
The calibration data is read from eeprom using the generic eeprom
framework apis.

Based on the original code by Siddartha Mohanadoss and Stephen Boyd.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 drivers/thermal/qcom/Makefile       |   2 +-
 drivers/thermal/qcom/tsens-8916.c   | 107 ++++++++++++++++++++++++++++++
 drivers/thermal/qcom/tsens-common.c | 128 ++++++++++++++++++++++++++++++++++++
 drivers/thermal/qcom/tsens.h        |  11 ++++
 4 files changed, 247 insertions(+), 1 deletion(-)
 create mode 100644 drivers/thermal/qcom/tsens-8916.c
 create mode 100644 drivers/thermal/qcom/tsens-common.c

diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 401069b..05c98e4 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
+qcom_tsens-y			+= tsens.o tsens-common.o tsens-8916.o
diff --git a/drivers/thermal/qcom/tsens-8916.c b/drivers/thermal/qcom/tsens-8916.c
new file mode 100644
index 0000000..a69aea3
--- /dev/null
+++ b/drivers/thermal/qcom/tsens-8916.c
@@ -0,0 +1,107 @@
+/*
+ * 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 "tsens.h"
+
+/* eeprom layout data for 8916 */
+#define BASE0_MASK	0x0000007f
+#define BASE1_MASK	0xfe000000
+#define BASE0_SHIFT	0
+#define BASE1_SHIFT	25
+
+#define S0_P1_MASK	0x00000f80
+#define S1_P1_MASK	0x003e0000
+#define S2_P1_MASK	0xf8000000
+#define S3_P1_MASK	0x000003e0
+#define S4_P1_MASK	0x000f8000
+
+#define S0_P2_MASK	0x0001f000
+#define S1_P2_MASK	0x07c00000
+#define S2_P2_MASK	0x0000001f
+#define S3_P2_MASK	0x00007c00
+#define S4_P2_MASK	0x01f00000
+
+#define S0_P1_SHIFT	7
+#define S1_P1_SHIFT	17
+#define S2_P1_SHIFT	27
+#define S3_P1_SHIFT	5
+#define S4_P1_SHIFT	15
+
+#define S0_P2_SHIFT	12
+#define S1_P2_SHIFT	22
+#define S2_P2_SHIFT	0
+#define S3_P2_SHIFT	10
+#define S4_P2_SHIFT	20
+
+#define CAL_SEL_MASK	0xe0000000
+#define CAL_SEL_SHIFT	29
+
+static int calibrate_8916(struct tsens_device *tmdev)
+{
+	int base0 = 0, base1 = 0, i;
+	u32 p1[5], p2[5];
+	int mode = 0;
+	u32 *qfprom_cdata, *qfprom_csel;
+
+	qfprom_cdata = (u32 *)qfprom_read(tmdev->dev, "calib");
+	if (IS_ERR(qfprom_cdata))
+		return PTR_ERR(qfprom_cdata);
+
+	qfprom_csel = (u32 *)qfprom_read(tmdev->dev, "calib_sel");
+	if (IS_ERR(qfprom_csel))
+		return PTR_ERR(qfprom_csel);
+
+	mode = (qfprom_csel[0] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
+	dev_dbg(tmdev->dev, "calibration mode is %d\n", mode);
+
+	switch (mode) {
+	case TWO_PT_CALIB:
+		base1 = (qfprom_cdata[1] & BASE1_MASK) >> BASE1_SHIFT;
+		p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
+		p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
+		p2[2] = (qfprom_cdata[1] & S2_P2_MASK) >> S2_P2_SHIFT;
+		p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
+		p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
+		for (i = 0; i < tmdev->num_sensors; i++)
+			p2[i] = ((base1 + p2[i]) << 3);
+		/* Fall through */
+	case ONE_PT_CALIB2:
+		base0 = (qfprom_cdata[0] & BASE0_MASK);
+		p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
+		p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
+		p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
+		p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
+		p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
+		for (i = 0; i < tmdev->num_sensors; i++)
+			p1[i] = (((base0) + p1[i]) << 3);
+		break;
+	default:
+		for (i = 0; i < tmdev->num_sensors; i++) {
+			p1[i] = 500;
+			p2[i] = 780;
+		}
+		break;
+	}
+
+	compute_intercept_slope(tmdev, p1, p2, mode);
+
+	return 0;
+}
+
+const struct tsens_ops ops_8916 = {
+	.init		= init_common,
+	.calibrate	= calibrate_8916,
+	.get_temp	= get_temp_common,
+};
diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c
new file mode 100644
index 0000000..5fcabd1
--- /dev/null
+++ b/drivers/thermal/qcom/tsens-common.c
@@ -0,0 +1,128 @@
+/*
+ * 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/nvmem-consumer.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include "tsens.h"
+
+#define S0_ST_ADDR		0x1030
+#define SN_ADDR_OFFSET		0x4
+#define SN_ST_TEMP_MASK		0x3ff
+#define CAL_DEGC_PT1		30
+#define CAL_DEGC_PT2		120
+#define SLOPE_FACTOR		1000
+
+char *qfprom_read(struct device *dev, const char *cname)
+{
+	struct nvmem_cell *cell;
+	ssize_t data;
+	char *ret;
+
+	cell = nvmem_cell_get(dev, cname);
+	if (IS_ERR(cell))
+		return ERR_CAST(cell);
+
+	ret = nvmem_cell_read(cell, &data);
+	nvmem_cell_put(cell);
+	return ret;
+}
+
+void compute_intercept_slope(struct tsens_device *tmdev, u32 *p1,
+			     u32 *p2, u32 mode)
+{
+	int i;
+	int num, den;
+
+	for (i = 0; i < tmdev->num_sensors; i++) {
+		dev_dbg(tmdev->dev,
+			"sensor%d - data_point1:%#x data_point2:%#x\n",
+			i, p1[i], p2[i]);
+
+		if (mode == TWO_PT_CALIB) {
+			/* slope (m) = adc_code2 - adc_code1 (y2 - y1)/
+				temp_120_degc - temp_30_degc (x2 - x1) */
+			num = p2[i] - p1[i];
+			num *= SLOPE_FACTOR;
+			den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
+			tmdev->sensor[i].slope = num / den;
+		}
+
+		tmdev->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
+				(CAL_DEGC_PT1 *
+				tmdev->sensor[i].slope);
+		dev_dbg(tmdev->dev, "offset:%d\n", tmdev->sensor[i].offset);
+	}
+}
+
+static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
+{
+	int degc, num, den;
+
+	num = (adc_code * SLOPE_FACTOR) - s->offset;
+	den = s->slope;
+
+	if (num > 0)
+		degc = num + (den / 2);
+	else if (num < 0)
+		degc = num - (den / 2);
+	else
+		degc = num;
+
+	degc /= den;
+
+	return degc;
+}
+
+int get_temp_common(struct tsens_device *tmdev, int id, long *temp)
+{
+	struct tsens_sensor *s = &tmdev->sensor[id];
+	u32 code;
+	unsigned int sensor_addr;
+	int last_temp = 0, ret;
+
+	sensor_addr = S0_ST_ADDR + s->hw_id * SN_ADDR_OFFSET;
+	ret = regmap_read(tmdev->map, sensor_addr, &code);
+	if (ret)
+		return ret;
+	last_temp = code & SN_ST_TEMP_MASK;
+
+	*temp = code_to_degc(last_temp, s) * 1000;
+
+	return 0;
+}
+
+static const struct regmap_config tsens_config = {
+	.reg_bits	= 32,
+	.val_bits	= 32,
+	.reg_stride	= 4,
+};
+
+int init_common(struct tsens_device *tmdev)
+{
+	void __iomem *base;
+
+	base = of_iomap(tmdev->dev->of_node, 0);
+	if (IS_ERR(base))
+		return -EINVAL;
+
+	tmdev->map = devm_regmap_init_mmio(tmdev->dev, base, &tsens_config);
+	if (!tmdev->map)
+		return -ENODEV;
+
+	return 0;
+}
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 9b274e1..81c5efb 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -13,6 +13,10 @@
 #ifndef __QCOM_TSENS_H__
 #define __QCOM_TSENS_H__
 
+#define ONE_PT_CALIB		0x1
+#define ONE_PT_CALIB2		0x2
+#define TWO_PT_CALIB		0x3
+
 struct tsens_device;
 
 struct tsens_sensor {
@@ -55,4 +59,11 @@ struct tsens_device {
 	struct tsens_sensor		sensor[0];
 };
 
+char *qfprom_read(struct device *, const char *);
+void compute_intercept_slope(struct tsens_device *, u32 *, u32 *, u32);
+int init_common(struct tsens_device *);
+int get_temp_common(struct tsens_device *, int, long *);
+
+extern const struct tsens_ops ops_8916;
+
 #endif /* __QCOM_TSENS_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 3/9] thermal: qcom: tsens-8974: Add support for 8974 family of SoCs
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 1/9] thermal: qcom: tsens: Add a skeletal TSENS drivers Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 2/9] thermal: qcom: tsens-8916: Add support for 8916 family of SoCs Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 4/9] thermal: qcom: tsens-8960: Add support for 8960 " Rajendra Nayak
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

Add .calibrate support for 8974 family as part of tsens_ops.

Based on the original code by Siddartha Mohanadoss and Stephen Boyd.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 drivers/thermal/qcom/Makefile     |   2 +-
 drivers/thermal/qcom/tsens-8974.c | 239 ++++++++++++++++++++++++++++++++++++++
 drivers/thermal/qcom/tsens.c      |   1 +
 drivers/thermal/qcom/tsens.h      |   2 +-
 4 files changed, 242 insertions(+), 2 deletions(-)
 create mode 100644 drivers/thermal/qcom/tsens-8974.c

diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 05c98e4..a471100 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
+qcom_tsens-y			+= tsens.o tsens-common.o tsens-8916.o tsens-8974.o
diff --git a/drivers/thermal/qcom/tsens-8974.c b/drivers/thermal/qcom/tsens-8974.c
new file mode 100644
index 0000000..19d9258
--- /dev/null
+++ b/drivers/thermal/qcom/tsens-8974.c
@@ -0,0 +1,239 @@
+/*
+ * 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 "tsens.h"
+
+/* eeprom layout data for 8974 */
+#define BASE1_MASK		0xff
+#define S0_P1_MASK		0x3f00
+#define S1_P1_MASK		0xfc000
+#define S2_P1_MASK		0x3f00000
+#define S3_P1_MASK		0xfc000000
+#define S4_P1_MASK		0x3f
+#define S5_P1_MASK		0xfc0
+#define S6_P1_MASK		0x3f000
+#define S7_P1_MASK		0xfc0000
+#define S8_P1_MASK		0x3f000000
+#define S8_P1_MASK_BKP		0x3f
+#define S9_P1_MASK		0x3f
+#define S9_P1_MASK_BKP		0xfc0
+#define S10_P1_MASK		0xfc0
+#define S10_P1_MASK_BKP		0x3f000
+#define CAL_SEL_0_1		0xc0000000
+#define CAL_SEL_2		0x40000000
+#define CAL_SEL_SHIFT		30
+#define CAL_SEL_SHIFT_2		28
+
+#define S0_P1_SHIFT		8
+#define S1_P1_SHIFT		14
+#define S2_P1_SHIFT		20
+#define S3_P1_SHIFT		26
+#define S5_P1_SHIFT		6
+#define S6_P1_SHIFT		12
+#define S7_P1_SHIFT		18
+#define S8_P1_SHIFT		24
+#define S9_P1_BKP_SHIFT		6
+#define S10_P1_SHIFT		6
+#define S10_P1_BKP_SHIFT	12
+
+#define BASE2_SHIFT		12
+#define BASE2_BKP_SHIFT		18
+#define S0_P2_SHIFT		20
+#define S0_P2_BKP_SHIFT		26
+#define S1_P2_SHIFT		26
+#define S2_P2_BKP_SHIFT		6
+#define S3_P2_SHIFT		6
+#define S3_P2_BKP_SHIFT		12
+#define S4_P2_SHIFT		12
+#define S4_P2_BKP_SHIFT		18
+#define S5_P2_SHIFT		18
+#define S5_P2_BKP_SHIFT		24
+#define S6_P2_SHIFT		24
+#define S7_P2_BKP_SHIFT		6
+#define S8_P2_SHIFT		6
+#define S8_P2_BKP_SHIFT		12
+#define S9_P2_SHIFT		12
+#define S9_P2_BKP_SHIFT		18
+#define S10_P2_SHIFT		18
+#define S10_P2_BKP_SHIFT	24
+
+#define BASE2_MASK		0xff000
+#define BASE2_BKP_MASK		0xfc0000
+#define S0_P2_MASK		0x3f00000
+#define S0_P2_BKP_MASK		0xfc000000
+#define S1_P2_MASK		0xfc000000
+#define S1_P2_BKP_MASK		0x3f
+#define S2_P2_MASK		0x3f
+#define S2_P2_BKP_MASK		0xfc0
+#define S3_P2_MASK		0xfc0
+#define S3_P2_BKP_MASK		0x3f000
+#define S4_P2_MASK		0x3f000
+#define S4_P2_BKP_MASK		0xfc0000
+#define S5_P2_MASK		0xfc0000
+#define S5_P2_BKP_MASK		0x3f000000
+#define S6_P2_MASK		0x3f000000
+#define S6_P2_BKP_MASK		0x3f
+#define S7_P2_MASK		0x3f
+#define S7_P2_BKP_MASK		0xfc0
+#define S8_P2_MASK		0xfc0
+#define S8_P2_BKP_MASK		0x3f000
+#define S9_P2_MASK		0x3f000
+#define S9_P2_BKP_MASK		0xfc0000
+#define S10_P2_MASK		0xfc0000
+#define S10_P2_BKP_MASK		0x3f000000
+
+#define BKP_SEL			0x3
+#define BKP_REDUN_SEL		0xe0000000
+#define BKP_REDUN_SHIFT		29
+
+#define BIT_APPEND		0x3
+
+static int calibrate_8974(struct tsens_device *tmdev)
+{
+	int base1 = 0, base2 = 0, i;
+	u32 p1[11], p2[11];
+	int mode = 0;
+	u32 *calib, *bkp;
+	u32 calib_redun_sel;
+
+	calib = (u32 *)qfprom_read(tmdev->dev, "calib");
+	if (IS_ERR(calib))
+		return PTR_ERR(calib);
+
+	bkp = (u32 *)qfprom_read(tmdev->dev, "calib_backup");
+	if (IS_ERR(bkp))
+		return PTR_ERR(bkp);
+
+	calib_redun_sel =  bkp[1] & BKP_REDUN_SEL;
+	calib_redun_sel >>= BKP_REDUN_SHIFT;
+
+	if (calib_redun_sel == BKP_SEL) {
+		mode = (calib[4] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
+		mode |= (calib[5] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
+
+		switch (mode) {
+		case TWO_PT_CALIB:
+			base2 = (bkp[2] & BASE2_BKP_MASK) >> BASE2_BKP_SHIFT;
+			p2[0] = (bkp[2] & S0_P2_BKP_MASK) >> S0_P2_BKP_SHIFT;
+			p2[1] = (bkp[3] & S1_P2_BKP_MASK);
+			p2[2] = (bkp[3] & S2_P2_BKP_MASK) >> S2_P2_BKP_SHIFT;
+			p2[3] = (bkp[3] & S3_P2_BKP_MASK) >> S3_P2_BKP_SHIFT;
+			p2[4] = (bkp[3] & S4_P2_BKP_MASK) >> S4_P2_BKP_SHIFT;
+			p2[5] = (calib[4] & S5_P2_BKP_MASK) >> S5_P2_BKP_SHIFT;
+			p2[6] = (calib[5] & S6_P2_BKP_MASK);
+			p2[7] = (calib[5] & S7_P2_BKP_MASK) >> S7_P2_BKP_SHIFT;
+			p2[8] = (calib[5] & S8_P2_BKP_MASK) >> S8_P2_BKP_SHIFT;
+			p2[9] = (calib[5] & S9_P2_BKP_MASK) >> S9_P2_BKP_SHIFT;
+			p2[10] = (calib[5] & S10_P2_BKP_MASK) >> S10_P2_BKP_SHIFT;
+			/* Fall through */
+		case ONE_PT_CALIB:
+		case ONE_PT_CALIB2:
+			base1 = bkp[0] & BASE1_MASK;
+			p1[0] = (bkp[0] & S0_P1_MASK) >> S0_P1_SHIFT;
+			p1[1] = (bkp[0] & S1_P1_MASK) >> S1_P1_SHIFT;
+			p1[2] = (bkp[0] & S2_P1_MASK) >> S2_P1_SHIFT;
+			p1[3] = (bkp[0] & S3_P1_MASK) >> S3_P1_SHIFT;
+			p1[4] = (bkp[1] & S4_P1_MASK);
+			p1[5] = (bkp[1] & S5_P1_MASK) >> S5_P1_SHIFT;
+			p1[6] = (bkp[1] & S6_P1_MASK) >> S6_P1_SHIFT;
+			p1[7] = (bkp[1] & S7_P1_MASK) >> S7_P1_SHIFT;
+			p1[8] = (bkp[2] & S8_P1_MASK_BKP) >> S8_P1_SHIFT;
+			p1[9] = (bkp[2] & S9_P1_MASK_BKP) >> S9_P1_BKP_SHIFT;
+			p1[10] = (bkp[2] & S10_P1_MASK_BKP) >> S10_P1_BKP_SHIFT;
+			break;
+		}
+	} else {
+		mode = (calib[1] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
+		mode |= (calib[3] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
+
+		switch (mode) {
+		case TWO_PT_CALIB:
+			base2 = (calib[2] & BASE2_MASK) >> BASE2_SHIFT;
+			p2[0] = (calib[2] & S0_P2_MASK) >> S0_P2_SHIFT;
+			p2[1] = (calib[2] & S1_P2_MASK) >> S1_P2_SHIFT;
+			p2[2] = (calib[3] & S2_P2_MASK);
+			p2[3] = (calib[3] & S3_P2_MASK) >> S3_P2_SHIFT;
+			p2[4] = (calib[3] & S4_P2_MASK) >> S4_P2_SHIFT;
+			p2[5] = (calib[3] & S5_P2_MASK) >> S5_P2_SHIFT;
+			p2[6] = (calib[3] & S6_P2_MASK) >> S6_P2_SHIFT;
+			p2[7] = (calib[4] & S7_P2_MASK);
+			p2[8] = (calib[4] & S8_P2_MASK) >> S8_P2_SHIFT;
+			p2[9] = (calib[4] & S9_P2_MASK) >> S9_P2_SHIFT;
+			p2[10] = (calib[4] & S10_P2_MASK) >> S10_P2_SHIFT;
+			/* Fall through */
+		case ONE_PT_CALIB:
+		case ONE_PT_CALIB2:
+			base1 = calib[0] & BASE1_MASK;
+			p1[0] = (calib[0] & S0_P1_MASK) >> S0_P1_SHIFT;
+			p1[1] = (calib[0] & S1_P1_MASK) >> S1_P1_SHIFT;
+			p1[2] = (calib[0] & S2_P1_MASK) >> S2_P1_SHIFT;
+			p1[3] = (calib[0] & S3_P1_MASK) >> S3_P1_SHIFT;
+			p1[4] = (calib[1] & S4_P1_MASK);
+			p1[5] = (calib[1] & S5_P1_MASK) >> S5_P1_SHIFT;
+			p1[6] = (calib[1] & S6_P1_MASK) >> S6_P1_SHIFT;
+			p1[7] = (calib[1] & S7_P1_MASK) >> S7_P1_SHIFT;
+			p1[8] = (calib[1] & S8_P1_MASK) >> S8_P1_SHIFT;
+			p1[9] = (calib[2] & S9_P1_MASK);
+			p1[10] = (calib[2] & S10_P1_MASK) >> S10_P1_SHIFT;
+			break;
+		}
+	}
+
+	switch (mode) {
+	case ONE_PT_CALIB:
+		for (i = 0; i < tmdev->num_sensors; i++)
+			p1[i] += (base1 << 2) | BIT_APPEND;
+		break;
+	case TWO_PT_CALIB:
+		for (i = 0; i < tmdev->num_sensors; i++) {
+			p2[i] += base2;
+			p2[i] <<= 2;
+			p2[i] |= BIT_APPEND;
+		}
+		/* Fall through */
+	case ONE_PT_CALIB2:
+		for (i = 0; i < tmdev->num_sensors; i++) {
+			p1[i] += base1;
+			p1[i] <<= 2;
+			p1[i] |= BIT_APPEND;
+		}
+		break;
+	default:
+		for (i = 0; i < tmdev->num_sensors; i++)
+			p2[i] = 780;
+		p1[0] = 502;
+		p1[1] = 509;
+		p1[2] = 503;
+		p1[3] = 509;
+		p1[4] = 505;
+		p1[5] = 509;
+		p1[6] = 507;
+		p1[7] = 510;
+		p1[8] = 508;
+		p1[9] = 509;
+		p1[10] = 508;
+		break;
+	}
+
+	compute_intercept_slope(tmdev, p1, p2, mode);
+
+	return 0;
+}
+
+const struct tsens_ops ops_8974 = {
+	.init		= init_common,
+	.calibrate	= calibrate_8974,
+	.get_temp	= get_temp_common,
+};
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index d32d278..4d65a42 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -76,6 +76,7 @@ static const struct of_device_id tsens_table[] = {
 		.data = &ops_8916,
 	}, {
 		.compatible = "qcom,msm8974-tsens",
+		.data = &ops_8974,
 	},
 	{}
 };
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 81c5efb..9ee0319 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -64,6 +64,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, long *);
 
-extern const struct tsens_ops ops_8916;
+extern const struct tsens_ops ops_8916, ops_8974;
 
 #endif /* __QCOM_TSENS_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 4/9] thermal: qcom: tsens-8960: Add support for 8960 family of SoCs
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
                   ` (2 preceding siblings ...)
  2015-07-08  9:47 ` [PATCH 3/9] thermal: qcom: tsens-8974: Add support for 8974 " Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support Rajendra Nayak
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

8960 family of SoCs have the TSENS device as part of a domain
thats not always ON. Hence add .suspend and .resume hooks to
save and restore some of the inited register context.

8960 family has TSENS as part of GCC, hence reuse the GCC
regmap. Also 8960 family had some of the TSENS init sequence thats
required to be done by the HLOS driver (some later versions of TSENS
do not export these registers to non-secure world, and hence need
these initializations to be done by secure bootloaders)

8660 from the same family has just one sensor and hence some register
offset/layout differences which need special handling in the driver.

Based on the original code from Siddartha Mohanadoss, Stephen Boyd and
Narendran Rajan.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 drivers/thermal/qcom/Makefile     |   2 +-
 drivers/thermal/qcom/tsens-8960.c | 291 ++++++++++++++++++++++++++++++++++++++
 drivers/thermal/qcom/tsens.c      |   1 +
 drivers/thermal/qcom/tsens.h      |   2 +-
 4 files changed, 294 insertions(+), 2 deletions(-)
 create mode 100644 drivers/thermal/qcom/tsens-8960.c

diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index a471100..f3cefd1 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
+qcom_tsens-y			+= tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o
diff --git a/drivers/thermal/qcom/tsens-8960.c b/drivers/thermal/qcom/tsens-8960.c
new file mode 100644
index 0000000..1b98e22
--- /dev/null
+++ b/drivers/thermal/qcom/tsens-8960.c
@@ -0,0 +1,291 @@
+/*
+ * 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 "tsens.h"
+
+#define CAL_MDEGC		30000
+
+#define CONFIG_ADDR		0x3640
+#define CONFIG_ADDR_8660	0x3620
+/* CONFIG_ADDR bitmasks */
+#define CONFIG			0x9b
+#define CONFIG_MASK		0xf
+#define CONFIG_8660		1
+#define CONFIG_SHIFT_8660	28
+#define CONFIG_MASK_8660	(3 << CONFIG_SHIFT_8660)
+
+#define STATUS_CNTL_ADDR_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 SLP_CLK_ENA_8660	BIT(24)
+#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_LIMIT_SHIFT	24
+#define THRESHOLD_MIN_LIMIT_SHIFT	16
+#define THRESHOLD_UPPER_LIMIT_SHIFT	8
+#define THRESHOLD_LOWER_LIMIT_SHIFT	0
+
+/* Initial temperature threshold values */
+#define LOWER_LIMIT_TH		0x50
+#define UPPER_LIMIT_TH		0xdf
+#define MIN_LIMIT_TH		0x0
+#define MAX_LIMIT_TH		0xff
+
+#define S0_STATUS_ADDR		0x3628
+#define INT_STATUS_ADDR		0x363c
+#define TRDY_MASK		BIT(7)
+
+static int suspend_8960(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;
+
+	if (tmdev->num_sensors > 1)
+		mask = SLP_CLK_ENA | EN;
+	else
+		mask = SLP_CLK_ENA_8660 | EN;
+
+	ret = regmap_update_bits(map, CNTL_ADDR, mask, 0);
+	if (ret)
+		return ret;
+
+	tmdev->trdy = false;
+
+	return 0;
+}
+
+static int resume_8960(struct tsens_device *tmdev)
+{
+	int ret;
+	unsigned long reg_cntl;
+	struct regmap *map = tmdev->map;
+
+	ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
+	if (ret)
+		return ret;
+
+	/*
+	 * Separate CONFIG restore is not needed only for 8660 as
+	 * config is part of CTRL Addr and its restored as such
+	 */
+	if (tmdev->num_sensors > 1) {
+		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;
+
+	reg_cntl = tmdev->ctx.control;
+	reg_cntl >>= SENSOR0_SHIFT;
+
+	return 0;
+}
+
+static int enable_8960(struct tsens_device *tmdev, int id)
+{
+	int ret;
+	u32 reg, mask;
+
+	ret = regmap_read(tmdev->map, CNTL_ADDR, &reg);
+	if (ret)
+		return ret;
+
+	mask = BIT(id + SENSOR0_SHIFT);
+	ret = regmap_write(tmdev->map, CNTL_ADDR, reg | SW_RST);
+	if (ret)
+		return ret;
+
+	if (tmdev->num_sensors > 1)
+		reg |= mask | SLP_CLK_ENA | EN;
+	else
+		reg |= mask | SLP_CLK_ENA_8660 | EN;
+
+	tmdev->trdy = false;
+	ret = regmap_write(tmdev->map, CNTL_ADDR, reg);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void disable_8960(struct tsens_device *tmdev)
+{
+	int ret;
+	u32 reg_cntl;
+	u32 mask;
+
+	mask = GENMASK(tmdev->num_sensors - 1, 0);
+	mask <<= SENSOR0_SHIFT;
+	mask |= EN;
+
+	ret = regmap_read(tmdev->map, CNTL_ADDR, &reg_cntl);
+	if (ret)
+		return;
+
+	reg_cntl &= ~mask;
+
+	if (tmdev->num_sensors > 1)
+		reg_cntl &= ~SLP_CLK_ENA;
+	else
+		reg_cntl &= ~SLP_CLK_ENA_8660;
+
+	regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
+}
+
+static int init_8960(struct tsens_device *tmdev)
+{
+	int ret, i;
+	u32 reg_cntl;
+
+	tmdev->map = dev_get_regmap(tmdev->dev->parent, NULL);
+	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 >= 5)
+			tmdev->sensor[i].status = S0_STATUS_ADDR + 40;
+		tmdev->sensor[i].status += i * 4;
+	}
+
+	reg_cntl = SW_RST;
+	ret = regmap_update_bits(tmdev->map, CNTL_ADDR, SW_RST, reg_cntl);
+	if (ret)
+		return ret;
+
+	if (tmdev->num_sensors > 1) {
+		reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
+		reg_cntl &= ~SW_RST;
+		ret = regmap_update_bits(tmdev->map, CONFIG_ADDR,
+					 CONFIG_MASK, CONFIG);
+	} else {
+		reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
+		reg_cntl &= ~CONFIG_MASK_8660;
+		reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
+	}
+
+	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_8960(struct tsens_device *tmdev)
+{
+	int i;
+	char *data;
+
+	ssize_t num_read = tmdev->num_sensors;
+	struct tsens_sensor *s = tmdev->sensor;
+
+	data = qfprom_read(tmdev->dev, "calib");
+	if (IS_ERR(data))
+		data = qfprom_read(tmdev->dev, "calib_backup");
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	for (i = 0; i < num_read; i++, s++)
+		s->offset = CAL_MDEGC - s->slope * data[i];
+
+	return 0;
+}
+
+/* Temperature on y axis and ADC-code on x-axis */
+static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
+{
+	return adc_code * s->slope + s->offset;
+}
+
+static int get_temp_8960(struct tsens_device *tmdev, int id, long *temp)
+{
+	int ret;
+	u32 code, trdy;
+	const struct tsens_sensor *s = &tmdev->sensor[id];
+
+	if (!tmdev->trdy) {
+		ret = regmap_read(tmdev->map, INT_STATUS_ADDR, &trdy);
+		if (ret)
+			return ret;
+		while (!(trdy & TRDY_MASK)) {
+			usleep_range(1000, 1100);
+			regmap_read(tmdev->map, INT_STATUS_ADDR, &trdy);
+		}
+		tmdev->trdy = true;
+	}
+
+	ret = regmap_read(tmdev->map, s->status, &code);
+	if (ret)
+		return ret;
+
+	*temp = code_to_mdegC(code, s);
+
+	dev_dbg(tmdev->dev, "Sensor%d temp is: %ld", id, *temp);
+
+	return 0;
+}
+
+const struct tsens_ops ops_8960 = {
+	.init		= init_8960,
+	.calibrate	= calibrate_8960,
+	.get_temp	= get_temp_8960,
+	.enable		= enable_8960,
+	.disable	= disable_8960,
+	.suspend	= suspend_8960,
+	.resume		= resume_8960,
+};
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 4d65a42..8d938d4 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -71,6 +71,7 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
 static const struct of_device_id tsens_table[] = {
 	{
 		.compatible = "qcom,msm8960-tsens",
+		.data = &ops_8960,
 	}, {
 		.compatible = "qcom,msm8916-tsens",
 		.data = &ops_8916,
diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h
index 9ee0319..f659806 100644
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -64,6 +64,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, long *);
 
-extern const struct tsens_ops ops_8916, ops_8974;
+extern const struct tsens_ops ops_8960, ops_8916, ops_8974;
 
 #endif /* __QCOM_TSENS_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
                   ` (3 preceding siblings ...)
  2015-07-08  9:47 ` [PATCH 4/9] thermal: qcom: tsens-8960: Add support for 8960 " Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-08-11 22:49   ` Stephen Boyd
  2015-07-08  9:47 ` [PATCH 6/9] arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes Rajendra Nayak
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

This patch adds support to add child devices to gcc as some of the
registers mapped by gcc are used by things like thermal sensors.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/clk/qcom/gcc-msm8960.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
index eb6a4f9..2c80d03 100644
--- a/drivers/clk/qcom/gcc-msm8960.c
+++ b/drivers/clk/qcom/gcc-msm8960.c
@@ -15,6 +15,7 @@
 #include <linux/bitops.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
 
-	return qcom_cc_probe(pdev, match->data);
+	qcom_cc_probe(pdev, match->data);
+	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
 }
 
 static int gcc_msm8960_remove(struct platform_device *pdev)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 6/9] arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
                   ` (4 preceding siblings ...)
  2015-07-08  9:47 ` [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 7/9] arm: dts: apq8064: " Rajendra Nayak
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

Add thermal zones, tsens and eeprom nodes

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 105 ++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 37b47b5..30f3246 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -75,6 +75,88 @@
 		};
 	};
 
+	thermal-zones {
+		cpu-thermal0 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 5>;
+
+			trips {
+				cpu_alert0: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit0: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal1 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 6>;
+
+			trips {
+				cpu_alert1: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit1: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal2 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 7>;
+
+			trips {
+				cpu_alert2: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit2: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal3 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 8>;
+
+			trips {
+				cpu_alert3: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit3: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
+
 	cpu-pmu {
 		compatible = "qcom,krait-pmu";
 		interrupts = <1 7 0xf04>;
@@ -103,6 +185,29 @@
 			      <0xf9002000 0x1000>;
 		};
 
+		qfprom: qfprom at fc4bc000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "qcom,qfprom";
+			reg = <0xfc4bc000 0x1000>;
+			tsens_calib: calib at d0 {
+				reg = <0xd0 0x18>;
+			};
+			tsens_backup: backup at 440 {
+				reg = <0x440 0x10>;
+			};
+		};
+
+		tsens: thermal-sensor at fc4a8000 {
+			compatible = "qcom,msm8974-tsens";
+			reg = <0xfc4a8000 0x2000>;
+			nvmem-cell = <&tsens_calib>, <&tsens_backup>;
+			nvmem-cell-names = "calib", "calib_backup";
+			qcom,tsens-slopes = <3200 3200 3200 3200 3200 3200
+				3200 3200 3200 3200 3200>;
+			#thermal-sensor-cells = <1>;
+		};
+
 		timer at f9020000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 7/9] arm: dts: apq8064: Add thermal zones, tsens and eeprom nodes
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
                   ` (5 preceding siblings ...)
  2015-07-08  9:47 ` [PATCH 6/9] arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 8/9] arm: dts: apq8084: " Rajendra Nayak
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

Add thermal zones, tsens and eeprom nodes

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 arch/arm/boot/dts/qcom-apq8064.dtsi | 108 ++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index df2061e..c06e59f 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -76,6 +76,88 @@
 		};
 	};
 
+	thermal-zones {
+		cpu-thermal0 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 7>;
+
+			trips {
+				cpu_alert0: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit0: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal1 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 8>;
+
+			trips {
+				cpu_alert1: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit1: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal2 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 9>;
+
+			trips {
+				cpu_alert2: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit2: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal3 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 10>;
+
+			trips {
+				cpu_alert3: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit3: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
+
 	cpu-pmu {
 		compatible = "qcom,krait-pmu";
 		interrupts = <1 10 0x304>;
@@ -289,11 +371,37 @@
 			qcom,controller-type = "pmic-arbiter";
 		};
 
+		qfprom: qfprom at 00700000 {
+			compatible	= "qcom,qfprom";
+			reg		= <0x00700000 0x1000>;
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			ranges;
+			tsens_calib: calib {
+				reg = <0x404 0x10>;
+			};
+			tsens_backup: backup_calib {
+				reg = <0x414 0x10>;
+			};
+		};
+
 		gcc: clock-controller at 900000 {
 			compatible = "qcom,gcc-apq8064";
 			reg = <0x00900000 0x4000>;
 			#clock-cells = <1>;
 			#reset-cells = <1>;
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			ranges;
+
+			tsens: thermal-sensor at 900000 {
+				compatible = "qcom,msm8960-tsens";
+				nvmem-cell = <&tsens_calib>, <&tsens_backup>;
+				nvmem-cell-names = "calib", "calib_backup";
+				qcom,tsens-slopes = <1176 1176 1154 1176 1111
+					1132 1132 1199 1132 1199 1132>;
+				#thermal-sensor-cells = <1>;
+			};
 		};
 
 		lcc: clock-controller at 28000000 {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 8/9] arm: dts: apq8084: Add thermal zones, tsens and eeprom nodes
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
                   ` (6 preceding siblings ...)
  2015-07-08  9:47 ` [PATCH 7/9] arm: dts: apq8064: " Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-07-08  9:47 ` [PATCH 9/9] arm64: dts: msm8916: " Rajendra Nayak
  2015-08-11  8:26 ` [PATCH 0/9] qcom: Add support for TSENS driver Srinivas Kandagatla
  9 siblings, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

Add thermal zones, tsens and eeprom nodes

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 arch/arm/boot/dts/qcom-apq8084.dtsi | 105 ++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index 7084010..05e83ea 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -75,6 +75,88 @@
 		};
 	};
 
+	thermal-zones {
+		cpu-thermal0 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 5>;
+
+			trips {
+				cpu_alert0: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit0: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal1 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 6>;
+
+			trips {
+				cpu_alert1: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit1: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal2 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 7>;
+
+			trips {
+				cpu_alert2: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit2: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal3 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 8>;
+
+			trips {
+				cpu_alert3: trip at 0 {
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit3: trip at 1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
+
 	cpu-pmu {
 		compatible = "qcom,krait-pmu";
 		interrupts = <1 7 0xf04>;
@@ -103,6 +185,29 @@
 			      <0xf9002000 0x1000>;
 		};
 
+		qfprom: qfprom at fc4bc000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "qcom,qfprom";
+			reg = <0xfc4bc000 0x1000>;
+			tsens_calib: calib at d0 {
+				reg = <0xd0 0x18>;
+			};
+			tsens_backup: backup at 440 {
+				reg = <0x440 0x10>;
+			};
+		};
+
+		tsens: thermal-sensor at fc4a8000 {
+			compatible = "qcom,msm8974-tsens";
+			reg = <0xfc4a8000 0x2000>;
+			nvmem-cell = <&tsens_calib>, <&tsens_backup>;
+			nvmem-cell-names = "calib", "calib_backup";
+			qcom,tsens-slopes = <3200 3200 3200 3200 3200 3200
+				3200 3200 3200 3200 3200>;
+			#thermal-sensor-cells = <1>;
+		};
+
 		timer at f9020000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 9/9] arm64: dts: msm8916: Add thermal zones, tsens and eeprom nodes
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
                   ` (7 preceding siblings ...)
  2015-07-08  9:47 ` [PATCH 8/9] arm: dts: apq8084: " Rajendra Nayak
@ 2015-07-08  9:47 ` Rajendra Nayak
  2015-08-11  8:26 ` [PATCH 0/9] qcom: Add support for TSENS driver Srinivas Kandagatla
  9 siblings, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-07-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

Add thermal zones, tsens and eeprom nodes

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 66 +++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 0f49ebd..9ff9979 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -63,6 +63,49 @@
 		};
 	};
 
+	thermal-zones {
+		cpu-thermal0 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 4>;
+
+			trips {
+				cpu_alert0: trip at 0 {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit0: trip at 1 {
+					temperature = <125000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu-thermal1 {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens 3>;
+
+			trips {
+				cpu_alert1: trip at 0 {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit1: trip at 1 {
+					temperature = <125000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
@@ -215,5 +258,28 @@
 			interrupt-controller;
 			#interrupt-cells = <4>;
 		};
+
+		qfprom: qfprom at 5c000 {
+			compatible = "qcom,qfprom";
+			reg = <0x5c000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			tsens_caldata: caldata at d0 {
+				reg = <0xd0 0x8>;
+			};
+			tsens_calsel: calsel at ec {
+				reg = <0xec 0x4>;
+			};
+		};
+
+		tsens: thermal-sensor at 4a8000 {
+			compatible = "qcom,msm8916-tsens";
+			reg = <0x4a8000 0x2000>;
+			nvmem-cell = <&tsens_caldata>, <&tsens_calsel>;
+			nvmem-cell-names = "calib", "calib_sel";
+			qcom,tsens-slopes = <3200 3200 3200 3200 3200>;
+			qcom,sensor-id = <0 1 2 4 5>;
+			#thermal-sensor-cells = <1>;
+		};
 	};
 };
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 0/9] qcom: Add support for TSENS driver
  2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
                   ` (8 preceding siblings ...)
  2015-07-08  9:47 ` [PATCH 9/9] arm64: dts: msm8916: " Rajendra Nayak
@ 2015-08-11  8:26 ` Srinivas Kandagatla
  9 siblings, 0 replies; 27+ messages in thread
From: Srinivas Kandagatla @ 2015-08-11  8:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rajendra,

On 08/07/15 10:47, Rajendra Nayak wrote:
> Changes since RFC:
> * Added support for 8916 and 8084
> * Based off the latest nvmem framework patches [1]
> * Minor review fixes for comments mostly from Lina
>
> ** I have also added irq support using the hardware
> trip point support series [2]. Will post that
> out seperately.
>
> This is an attempt to have a single TSENS driver for
> the different versions of the TSENS IP that exist, on
> different qcom msm/apq SoCs'
> Support is added for msm8916, msm8960 and msm8974 families.
> Based on top of the latest nvmem framework patches [2]
>
> A lot of the work is based of original code from Stephen Boyd
> and Siddartha Mohanadoss. I have also picked some of what
> Narendran Rajan did in his attempt to upstream the support
> for 8960 family. I could not keep the original authorship on
> any of the patches because I ended up moving the code around
> quite a bit in an effort to have a single driver for the
> various devices. I would be glad to change the authorship
> for any of the patches if needed.
>
> [1] https://lkml.org/lkml/2015/6/22/609
> [2] https://lkml.org/lkml/2015/5/20/472
>
> Rajendra Nayak (8):
>    thermal: qcom: tsens: Add a skeletal TSENS drivers
>    thermal: qcom: tsens-8916: Add support for 8916 family of SoCs
>    thermal: qcom: tsens-8974: Add support for 8974 family of SoCs
>    thermal: qcom: tsens-8960: Add support for 8960 family of SoCs
>    arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes
>    arm: dts: apq8064: Add thermal zones, tsens and eeprom nodes
>    arm: dts: apq8084: Add thermal zones, tsens and eeprom nodes
>    arm64: dts: msm8916: Add thermal zones, tsens and eeprom nodes
>
> Srinivas Kandagatla (1):
>    clk: qcom: gcc-msm8960: add child devices support.
>
>   .../devicetree/bindings/thermal/qcom-tsens.txt     |  37 +++
>   arch/arm/boot/dts/qcom-apq8064.dtsi                | 108 ++++++++
>   arch/arm/boot/dts/qcom-apq8084.dtsi                | 105 ++++++++
>   arch/arm/boot/dts/qcom-msm8974.dtsi                | 105 ++++++++
>   arch/arm64/boot/dts/qcom/msm8916.dtsi              |  66 +++++
>   drivers/clk/qcom/gcc-msm8960.c                     |   4 +-
>   drivers/thermal/Kconfig                            |   5 +
>   drivers/thermal/Makefile                           |   1 +
>   drivers/thermal/qcom/Kconfig                       |  10 +
>   drivers/thermal/qcom/Makefile                      |   2 +
>   drivers/thermal/qcom/tsens-8916.c                  | 107 ++++++++
>   drivers/thermal/qcom/tsens-8960.c                  | 291 +++++++++++++++++++++
>   drivers/thermal/qcom/tsens-8974.c                  | 239 +++++++++++++++++
>   drivers/thermal/qcom/tsens-common.c                | 128 +++++++++
>   drivers/thermal/qcom/tsens.c                       | 209 +++++++++++++++
>   drivers/thermal/qcom/tsens.h                       |  69 +++++
>   16 files changed, 1485 insertions(+), 1 deletion(-)
>   create mode 100644 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
>   create mode 100644 drivers/thermal/qcom/Kconfig
>   create mode 100644 drivers/thermal/qcom/Makefile
>   create mode 100644 drivers/thermal/qcom/tsens-8916.c
>   create mode 100644 drivers/thermal/qcom/tsens-8960.c
>   create mode 100644 drivers/thermal/qcom/tsens-8974.c
>   create mode 100644 drivers/thermal/qcom/tsens-common.c
>   create mode 100644 drivers/thermal/qcom/tsens.c
>   create mode 100644 drivers/thermal/qcom/tsens.h
>


Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

NVMEM framework in now available in linux-next.

Do you think we can get this in v4.3?

--srini

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-07-08  9:47 ` [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support Rajendra Nayak
@ 2015-08-11 22:49   ` Stephen Boyd
  2015-08-12  9:00     ` Srinivas Kandagatla
  2015-08-12 20:18     ` Bjorn Andersson
  0 siblings, 2 replies; 27+ messages in thread
From: Stephen Boyd @ 2015-08-11 22:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/08, Rajendra Nayak wrote:
> diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
> index eb6a4f9..2c80d03 100644
> --- a/drivers/clk/qcom/gcc-msm8960.c
> +++ b/drivers/clk/qcom/gcc-msm8960.c
> @@ -15,6 +15,7 @@
>  #include <linux/bitops.h>
>  #include <linux/err.h>
>  #include <linux/platform_device.h>
> +#include <linux/of_platform.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
>  	if (IS_ERR(clk))
>  		return PTR_ERR(clk);
>  
> -	return qcom_cc_probe(pdev, match->data);
> +	qcom_cc_probe(pdev, match->data);
> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);

We just lost the error code from qcom_cc_probe()...

Also, I don't like having a subnode in DT. Why can't we use the
same node as the GCC node and create a virtual child device here
for tsens? We can assign the same of_node that this platform
device has so that DT keeps working correctly.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-11 22:49   ` Stephen Boyd
@ 2015-08-12  9:00     ` Srinivas Kandagatla
  2015-08-13  4:28       ` Rajendra Nayak
  2015-08-12 20:18     ` Bjorn Andersson
  1 sibling, 1 reply; 27+ messages in thread
From: Srinivas Kandagatla @ 2015-08-12  9:00 UTC (permalink / raw)
  To: linux-arm-kernel



On 11/08/15 23:49, Stephen Boyd wrote:
> On 07/08, Rajendra Nayak wrote:
>> diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
>> index eb6a4f9..2c80d03 100644
>> --- a/drivers/clk/qcom/gcc-msm8960.c
>> +++ b/drivers/clk/qcom/gcc-msm8960.c
>> @@ -15,6 +15,7 @@
>>   #include <linux/bitops.h>
>>   #include <linux/err.h>
>>   #include <linux/platform_device.h>
>> +#include <linux/of_platform.h>
>>   #include <linux/module.h>
>>   #include <linux/of.h>
>>   #include <linux/of_device.h>
>> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
>>   	if (IS_ERR(clk))
>>   		return PTR_ERR(clk);
>>
>> -	return qcom_cc_probe(pdev, match->data);
>> +	qcom_cc_probe(pdev, match->data);
>> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
>
> We just lost the error code from qcom_cc_probe()...
>
I think Rajendra picked up the wrong patch for this series, I did submit 
a v2 (https://patches.linaro.org/44033/) with the above fixed.

> Also, I don't like having a subnode in DT. Why can't we use the
> same node as the GCC node and create a virtual child device here
> for tsens? We can assign the same of_node that this platform
> device has so that DT keeps working correctly.

I don't mind either way, if that makes things moving :-)

--srini
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-11 22:49   ` Stephen Boyd
  2015-08-12  9:00     ` Srinivas Kandagatla
@ 2015-08-12 20:18     ` Bjorn Andersson
  2015-08-12 21:57       ` Stephen Boyd
  1 sibling, 1 reply; 27+ messages in thread
From: Bjorn Andersson @ 2015-08-12 20:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue 11 Aug 15:49 PDT 2015, Stephen Boyd wrote:

> On 07/08, Rajendra Nayak wrote:
> > diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
> > index eb6a4f9..2c80d03 100644
> > --- a/drivers/clk/qcom/gcc-msm8960.c
> > +++ b/drivers/clk/qcom/gcc-msm8960.c
> > @@ -15,6 +15,7 @@
> >  #include <linux/bitops.h>
> >  #include <linux/err.h>
> >  #include <linux/platform_device.h>
> > +#include <linux/of_platform.h>
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> >  #include <linux/of_device.h>
> > @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
> >  	if (IS_ERR(clk))
> >  		return PTR_ERR(clk);
> >  
> > -	return qcom_cc_probe(pdev, match->data);
> > +	qcom_cc_probe(pdev, match->data);
> > +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
> 
> We just lost the error code from qcom_cc_probe()...
> 
> Also, I don't like having a subnode in DT. Why can't we use the
> same node as the GCC node and create a virtual child device here
> for tsens? We can assign the same of_node that this platform
> device has so that DT keeps working correctly.
> 

Can't we make the gcc driver support being a child of a simple-mfd by
having it attempting to acquire the regmap of the parent and falling
back to creating its own mmio regmap?

That way we don't need to make tsense a child of the clock device and
we're still backwards compatible.

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-12 20:18     ` Bjorn Andersson
@ 2015-08-12 21:57       ` Stephen Boyd
  2015-08-13  4:14         ` Bjorn Andersson
  0 siblings, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2015-08-12 21:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/12/2015 01:18 PM, Bjorn Andersson wrote:
> On Tue 11 Aug 15:49 PDT 2015, Stephen Boyd wrote:
>
>> On 07/08, Rajendra Nayak wrote:
>>> diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
>>> index eb6a4f9..2c80d03 100644
>>> --- a/drivers/clk/qcom/gcc-msm8960.c
>>> +++ b/drivers/clk/qcom/gcc-msm8960.c
>>> @@ -15,6 +15,7 @@
>>>   #include <linux/bitops.h>
>>>   #include <linux/err.h>
>>>   #include <linux/platform_device.h>
>>> +#include <linux/of_platform.h>
>>>   #include <linux/module.h>
>>>   #include <linux/of.h>
>>>   #include <linux/of_device.h>
>>> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
>>>   	if (IS_ERR(clk))
>>>   		return PTR_ERR(clk);
>>>   
>>> -	return qcom_cc_probe(pdev, match->data);
>>> +	qcom_cc_probe(pdev, match->data);
>>> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
>> We just lost the error code from qcom_cc_probe()...
>>
>> Also, I don't like having a subnode in DT. Why can't we use the
>> same node as the GCC node and create a virtual child device here
>> for tsens? We can assign the same of_node that this platform
>> device has so that DT keeps working correctly.
>>
> Can't we make the gcc driver support being a child of a simple-mfd by
> having it attempting to acquire the regmap of the parent and falling
> back to creating its own mmio regmap?

So we would need to make a new device and driver for the simple-mfd 
parent? I'm confused about what you're suggesting and what benefit it 
has versus creating a child of the clock controller device.

Here's the patch I'm suggesting. The device name is probably wrong, but 
you get the idea.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----8<----

diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
index aa294b1bad34..802e9794f76e 100644
--- a/drivers/clk/qcom/gcc-msm8960.c
+++ b/drivers/clk/qcom/gcc-msm8960.c
@@ -3505,7 +3505,9 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
  {
  	struct clk *clk;
  	struct device *dev = &pdev->dev;
+	struct platform_device *tsens;
  	const struct of_device_id *match;
+	int ret;
  
  	match = of_match_device(gcc_msm8960_match_table, &pdev->dev);
  	if (!match)
@@ -3520,7 +3522,30 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
  	if (IS_ERR(clk))
  		return PTR_ERR(clk);
  
-	return qcom_cc_probe(pdev, match->data);
+	ret = qcom_cc_probe(pdev, match->data);
+	if (ret)
+		return ret;
+
+	tsens = platform_device_alloc("tsens", -1);
+	if (!tsens) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	tsens->dev.parent = &pdev->dev;
+	tsens->dev.of_node = pdev->dev.of_node;
+	ret = platform_device_add(tsens);
+	if (ret)
+		goto err_add;
+
+	return 0;
+
+err_add:
+	platform_device_put(tsens);
+err_alloc:
+	qcom_cc_remove(pdev);
+
+	return ret;
  }
  
  static int gcc_msm8960_remove(struct platform_device *pdev)

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-12 21:57       ` Stephen Boyd
@ 2015-08-13  4:14         ` Bjorn Andersson
  2015-08-14  0:46           ` Stephen Boyd
  0 siblings, 1 reply; 27+ messages in thread
From: Bjorn Andersson @ 2015-08-13  4:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed 12 Aug 14:57 PDT 2015, Stephen Boyd wrote:

> On 08/12/2015 01:18 PM, Bjorn Andersson wrote:
> > On Tue 11 Aug 15:49 PDT 2015, Stephen Boyd wrote:
> >
> >> On 07/08, Rajendra Nayak wrote:
> >>> diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
> >>> index eb6a4f9..2c80d03 100644
> >>> --- a/drivers/clk/qcom/gcc-msm8960.c
> >>> +++ b/drivers/clk/qcom/gcc-msm8960.c
> >>> @@ -15,6 +15,7 @@
> >>>   #include <linux/bitops.h>
> >>>   #include <linux/err.h>
> >>>   #include <linux/platform_device.h>
> >>> +#include <linux/of_platform.h>
> >>>   #include <linux/module.h>
> >>>   #include <linux/of.h>
> >>>   #include <linux/of_device.h>
> >>> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
> >>>   	if (IS_ERR(clk))
> >>>   		return PTR_ERR(clk);
> >>>   
> >>> -	return qcom_cc_probe(pdev, match->data);
> >>> +	qcom_cc_probe(pdev, match->data);
> >>> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
> >> We just lost the error code from qcom_cc_probe()...
> >>
> >> Also, I don't like having a subnode in DT. Why can't we use the
> >> same node as the GCC node and create a virtual child device here
> >> for tsens? We can assign the same of_node that this platform
> >> device has so that DT keeps working correctly.
> >>
> > Can't we make the gcc driver support being a child of a simple-mfd by
> > having it attempting to acquire the regmap of the parent and falling
> > back to creating its own mmio regmap?
> 
> So we would need to make a new device and driver for the simple-mfd 
> parent?

No that part is already in mainline, so my idea was that we add an early
return in qcom_cc_map() like:

	 struct device *dev = &pdev->dev;
+        struct regmap *map;
+
+        map = syscon_node_to_regmap(dev->parent->of_node);
+        if (!IS_ERR(map))
+                return map;

And then just update the dts to:

	gcc {
		compatible = "syscon", "simple-mfd";
		reg = <0x00900000 0x4000>;

		gcc: clock-controller {
			compatible = "qcom,gcc-apq8064";
			#clock-cells = <1>;
			#reset-cells = <1>;
		};
	};

But as I implemented this I realized that the syscon_node_to_regmap()
does not register the regmap as a devres of the parent, and as such it's
not caught by the regmap lookup in devm_clk_register_regmap().

So either one would need to make the syscon throw the regmap into devres
or make it possible to pass a regmap to devm_clk_register_regmap() for
this to work.

> I'm confused about what you're suggesting and what benefit it 
> has versus creating a child of the clock controller device.

The benefit would simply be that we're using the already existing
mechanism for handling multiple platform_drivers sharing a hw block.

> 
> Here's the patch I'm suggesting. The device name is probably wrong, but 
> you get the idea.

Looks very much like my take on it as well, I do however have concerns
that suddenly the node called "clock-controller" will have to come with
tsens related properties.

Are all the tsens-in-gcc blocks the same? Or do you intend to of_match
on the gcc compatible in the tsens driver?

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-12  9:00     ` Srinivas Kandagatla
@ 2015-08-13  4:28       ` Rajendra Nayak
  2015-08-14  0:42         ` Stephen Boyd
  0 siblings, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2015-08-13  4:28 UTC (permalink / raw)
  To: linux-arm-kernel

> On 11/08/15 23:49, Stephen Boyd wrote:
>> On 07/08, Rajendra Nayak wrote:
>>> diff --git a/drivers/clk/qcom/gcc-msm8960.c
>>> b/drivers/clk/qcom/gcc-msm8960.c
>>> index eb6a4f9..2c80d03 100644
>>> --- a/drivers/clk/qcom/gcc-msm8960.c
>>> +++ b/drivers/clk/qcom/gcc-msm8960.c
>>> @@ -15,6 +15,7 @@
>>>   #include <linux/bitops.h>
>>>   #include <linux/err.h>
>>>   #include <linux/platform_device.h>
>>> +#include <linux/of_platform.h>
>>>   #include <linux/module.h>
>>>   #include <linux/of.h>
>>>   #include <linux/of_device.h>
>>> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct
>>> platform_device *pdev)
>>>       if (IS_ERR(clk))
>>>           return PTR_ERR(clk);
>>>
>>> -    return qcom_cc_probe(pdev, match->data);
>>> +    qcom_cc_probe(pdev, match->data);
>>> +    return of_platform_populate(pdev->dev.of_node, NULL, NULL,
>>> &pdev->dev);
>>
>> We just lost the error code from qcom_cc_probe()...
>>
> I think Rajendra picked up the wrong patch for this series, I did submit
> a v2 (https://patches.linaro.org/44033/) with the above fixed.

ah, sorry about that.

>> Also, I don't like having a subnode in DT. Why can't we use the
>> same node as the GCC node and create a virtual child device here
>> for tsens? We can assign the same of_node that this platform
>> device has so that DT keeps working correctly.

So the current driver looks up data based on compatible strings.
So you suggesting to create a virtual child device for gcc and
associate the gcc DT node to it? (And have the tsens compatible
mentioned as part of the gcc DT node?)
How is this any different from creating a subnode in DT anyway?

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-13  4:28       ` Rajendra Nayak
@ 2015-08-14  0:42         ` Stephen Boyd
  2015-08-14  3:09           ` Rajendra Nayak
  0 siblings, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2015-08-14  0:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/13, Rajendra Nayak wrote:
> >On 11/08/15 23:49, Stephen Boyd wrote:
> >>On 07/08, Rajendra Nayak wrote:
> >>>diff --git a/drivers/clk/qcom/gcc-msm8960.c
> >>>b/drivers/clk/qcom/gcc-msm8960.c
> >>>index eb6a4f9..2c80d03 100644
> >>>--- a/drivers/clk/qcom/gcc-msm8960.c
> >>>+++ b/drivers/clk/qcom/gcc-msm8960.c
> >>>@@ -15,6 +15,7 @@
> >>>  #include <linux/bitops.h>
> >>>  #include <linux/err.h>
> >>>  #include <linux/platform_device.h>
> >>>+#include <linux/of_platform.h>
> >>>  #include <linux/module.h>
> >>>  #include <linux/of.h>
> >>>  #include <linux/of_device.h>
> >>>@@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct
> >>>platform_device *pdev)
> >>>      if (IS_ERR(clk))
> >>>          return PTR_ERR(clk);
> >>>
> >>>-    return qcom_cc_probe(pdev, match->data);
> >>>+    qcom_cc_probe(pdev, match->data);
> >>>+    return of_platform_populate(pdev->dev.of_node, NULL, NULL,
> >>>&pdev->dev);
> >>
> >>We just lost the error code from qcom_cc_probe()...
> >>
> >I think Rajendra picked up the wrong patch for this series, I did submit
> >a v2 (https://patches.linaro.org/44033/) with the above fixed.
> 
> ah, sorry about that.
> 
> >>Also, I don't like having a subnode in DT. Why can't we use the
> >>same node as the GCC node and create a virtual child device here
> >>for tsens? We can assign the same of_node that this platform
> >>device has so that DT keeps working correctly.
> 
> So the current driver looks up data based on compatible strings.

The tsens device is always the same piece of hardware. The only
thing that's changing is the qfprom data and the number of
sensors. So we should be looking at the qfprom compatible string
to figure out how to interpret the qfprom data which would
include the number of sensors and how the data is encoded.

> So you suggesting to create a virtual child device for gcc and
> associate the gcc DT node to it? (And have the tsens compatible
> mentioned as part of the gcc DT node?)

No. The driver should work just fine without having to
interrogate the device's compatible string. If we still need the
compatible check for some reason, then we can always match based
on qcom,gcc-msm8960, qcom,gcc-apq8064, etc. But I don't see why
we need to do that when we should be looking at what type of
qfprom is connected so we can correctly parse the data.

> How is this any different from creating a subnode in DT anyway?

The difference is we don't make up nodes to satisfy linux device
driver design. I suspect the hardware engineers put tsens inside
gcc because both blocks were written by the same person/team and
they just needed some place to jam some registers and call it a
day. That doesn't constitute an MFD or bus, which is what we
would be expressing in DT if we made a child node, it constitutes
a horrible software interface design that we have to live with.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-13  4:14         ` Bjorn Andersson
@ 2015-08-14  0:46           ` Stephen Boyd
  0 siblings, 0 replies; 27+ messages in thread
From: Stephen Boyd @ 2015-08-14  0:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/12, Bjorn Andersson wrote:
> On Wed 12 Aug 14:57 PDT 2015, Stephen Boyd wrote:
> 
> > Here's the patch I'm suggesting. The device name is probably wrong, but 
> > you get the idea.
> 
> Looks very much like my take on it as well, I do however have concerns
> that suddenly the node called "clock-controller" will have to come with
> tsens related properties.
> 
> Are all the tsens-in-gcc blocks the same?

Yes they're all the same, except some of them have more sensors
than others. It depends on what SoC the hardware is instantiated
in. They also messed up the software interface and had to add
discontinuous registers for the sensors because it was never
designed to have more than 4 sensors or something like that. But
even that sort of change can be handled by figuring out the
format of the sensor data in the qfprom.

> Or do you intend to of_match
> on the gcc compatible in the tsens driver?
> 

I hope we don't have to of_match in the tsens driver on gcc
compatible strings.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-14  0:42         ` Stephen Boyd
@ 2015-08-14  3:09           ` Rajendra Nayak
  2015-09-02  2:37             ` Rajendra Nayak
  0 siblings, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2015-08-14  3:09 UTC (permalink / raw)
  To: linux-arm-kernel

[]..
>>>> Also, I don't like having a subnode in DT. Why can't we use the
>>>> same node as the GCC node and create a virtual child device here
>>>> for tsens? We can assign the same of_node that this platform
>>>> device has so that DT keeps working correctly.
>>
>> So the current driver looks up data based on compatible strings.
>
> The tsens device is always the same piece of hardware. The only

Well, not always. The one in 8960 does need additional initializations,
requires you to save/restore context as it can be powered off
not being in an always powered on domain etc.

> thing that's changing is the qfprom data and the number of
> sensors. So we should be looking at the qfprom compatible string

How? Tsens uses nvmem framework apis to read the qfprom atleast
in this series.

> to figure out how to interpret the qfprom data which would
> include the number of sensors and how the data is encoded.
>
>> So you suggesting to create a virtual child device for gcc and
>> associate the gcc DT node to it? (And have the tsens compatible
>> mentioned as part of the gcc DT node?)
>
> No. The driver should work just fine without having to
> interrogate the device's compatible string. If we still need the
> compatible check for some reason, then we can always match based
> on qcom,gcc-msm8960, qcom,gcc-apq8064, etc. But I don't see why

Thats not quite possible I guess. 2 drivers (gcc and tsens) matching
the same compatibles? Will it not just depend on which ends up being
the first match?

> we need to do that when we should be looking at what type of
> qfprom is connected so we can correctly parse the data.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-08-14  3:09           ` Rajendra Nayak
@ 2015-09-02  2:37             ` Rajendra Nayak
  2015-09-03 17:27               ` Stephen Boyd
  0 siblings, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2015-09-02  2:37 UTC (permalink / raw)
  To: linux-arm-kernel

Stephen,

>>>>> Also, I don't like having a subnode in DT. Why can't we use the
>>>>> same node as the GCC node and create a virtual child device here
>>>>> for tsens? We can assign the same of_node that this platform
>>>>> device has so that DT keeps working correctly.
>>>
>>> So the current driver looks up data based on compatible strings.
>>
>> The tsens device is always the same piece of hardware. The only
>
> Well, not always. The one in 8960 does need additional initializations,
> requires you to save/restore context as it can be powered off
> not being in an always powered on domain etc.
>
>> thing that's changing is the qfprom data and the number of
>> sensors. So we should be looking at the qfprom compatible string
>
> How? Tsens uses nvmem framework apis to read the qfprom atleast
> in this series.
>
>> to figure out how to interpret the qfprom data which would
>> include the number of sensors and how the data is encoded.
>>
>>> So you suggesting to create a virtual child device for gcc and
>>> associate the gcc DT node to it? (And have the tsens compatible
>>> mentioned as part of the gcc DT node?)
>>
>> No. The driver should work just fine without having to
>> interrogate the device's compatible string. If we still need the
>> compatible check for some reason, then we can always match based
>> on qcom,gcc-msm8960, qcom,gcc-apq8064, etc. But I don't see why
>
> Thats not quite possible I guess. 2 drivers (gcc and tsens) matching
> the same compatibles? Will it not just depend on which ends up being
> the first match?

Any thoughts on how to move forward with this?

I tried what you were suggesting, and here's what I had to do to get
things working

* Created a gcc node in DT with gcc and tsens compatibles, with gcc and
tsens properties
* gcc driver probes the device/node first given gcc is registered with
a core_initcall()
* creates a virtual child device attaching the same of_node (having
both gcc and tsens compatibles)
* gcc ends up probing the virtual device/node _again_ (due to the gcc
compatible match), fails
* At a later point, tsens driver gets registered (using module_initcall)
ends up probing the virtual child node and succeeds

Is this what you had in mind, or am I at the wrong end of the stick?

regards,
Rajendra

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-09-02  2:37             ` Rajendra Nayak
@ 2015-09-03 17:27               ` Stephen Boyd
  2015-09-07  6:39                 ` Rajendra Nayak
  0 siblings, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2015-09-03 17:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/02, Rajendra Nayak wrote:
> Stephen,
> 
> >>>>>Also, I don't like having a subnode in DT. Why can't we use the
> >>>>>same node as the GCC node and create a virtual child device here
> >>>>>for tsens? We can assign the same of_node that this platform
> >>>>>device has so that DT keeps working correctly.
> >>>
> >>>So the current driver looks up data based on compatible strings.
> >>
> >>The tsens device is always the same piece of hardware. The only
> >
> >Well, not always. The one in 8960 does need additional initializations,
> >requires you to save/restore context as it can be powered off
> >not being in an always powered on domain etc.
> >
> >>thing that's changing is the qfprom data and the number of
> >>sensors. So we should be looking at the qfprom compatible string
> >
> >How? Tsens uses nvmem framework apis to read the qfprom atleast
> >in this series.
> >
> >>to figure out how to interpret the qfprom data which would
> >>include the number of sensors and how the data is encoded.
> >>
> >>>So you suggesting to create a virtual child device for gcc and
> >>>associate the gcc DT node to it? (And have the tsens compatible
> >>>mentioned as part of the gcc DT node?)
> >>
> >>No. The driver should work just fine without having to
> >>interrogate the device's compatible string. If we still need the
> >>compatible check for some reason, then we can always match based
> >>on qcom,gcc-msm8960, qcom,gcc-apq8064, etc. But I don't see why
> >
> >Thats not quite possible I guess. 2 drivers (gcc and tsens) matching
> >the same compatibles? Will it not just depend on which ends up being
> >the first match?
> 
> Any thoughts on how to move forward with this?
> 
> I tried what you were suggesting, and here's what I had to do to get
> things working
> 
> * Created a gcc node in DT with gcc and tsens compatibles, with gcc and
> tsens properties

This is not what I had in mind. This is what's should be in DT

 clock-controller at f000 {
 	compatible = "qcom,gcc-msm8916";
	reg = <0xf000 ...>;
	....
 };

> * gcc driver probes the device/node first given gcc is registered with
> a core_initcall()
> * creates a virtual child device attaching the same of_node (having
> both gcc and tsens compatibles)
> * gcc ends up probing the virtual device/node _again_ (due to the gcc
> compatible match), fails
> * At a later point, tsens driver gets registered (using module_initcall)
> ends up probing the virtual child node and succeeds

Yeah this might happen though because we've assigned the of_node
pointer to the tsens device before we register it on the platform
bus. The other way to pass that data down from gcc to tsens would
be to not have an of_node assigned to the tsens device, and check
for that case in the tsens driver. If there isn't an of_node,
then we look at the parent device's of_node to figure out which
gcc it is (if this even matters) and parse DT properties.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-09-03 17:27               ` Stephen Boyd
@ 2015-09-07  6:39                 ` Rajendra Nayak
  2015-09-08 19:21                   ` Stephen Boyd
  0 siblings, 1 reply; 27+ messages in thread
From: Rajendra Nayak @ 2015-09-07  6:39 UTC (permalink / raw)
  To: linux-arm-kernel

[]..

>>>> No. The driver should work just fine without having to
>>>> interrogate the device's compatible string. If we still need the
>>>> compatible check for some reason, then we can always match based
>>>> on qcom,gcc-msm8960, qcom,gcc-apq8064, etc. But I don't see why
>>>
>>> Thats not quite possible I guess. 2 drivers (gcc and tsens) matching
>>> the same compatibles? Will it not just depend on which ends up being
>>> the first match?
>>
>> Any thoughts on how to move forward with this?
>>
>> I tried what you were suggesting, and here's what I had to do to get
>> things working
>>
>> * Created a gcc node in DT with gcc and tsens compatibles, with gcc and
>> tsens properties
>
> This is not what I had in mind. This is what's should be in DT
>
>   clock-controller at f000 {
>   	compatible = "qcom,gcc-msm8916";
> 	reg = <0xf000 ...>;
> 	....
>   };
>
>> * gcc driver probes the device/node first given gcc is registered with
>> a core_initcall()
>> * creates a virtual child device attaching the same of_node (having
>> both gcc and tsens compatibles)
>> * gcc ends up probing the virtual device/node _again_ (due to the gcc
>> compatible match), fails
>> * At a later point, tsens driver gets registered (using module_initcall)
>> ends up probing the virtual child node and succeeds
>
> Yeah this might happen though because we've assigned the of_node
> pointer to the tsens device before we register it on the platform
> bus. The other way to pass that data down from gcc to tsens would
> be to not have an of_node assigned to the tsens device, and check
> for that case in the tsens driver. If there isn't an of_node,
> then we look at the parent device's of_node to figure out which
> gcc it is (if this even matters) and parse DT properties.

Parsing DT properties from parent (in the tsens driver) is fine, but
the nvmem apis still expect an of_node for the tsens device and hence
fail.

Associating the of_node of the parent to the tsens device while being
probed ends up with the same issues of gcc ending up probing the device
and failing because tsens defers probe a couple times before a
successful probe.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-09-07  6:39                 ` Rajendra Nayak
@ 2015-09-08 19:21                   ` Stephen Boyd
  2015-09-09  3:33                     ` Rajendra Nayak
  0 siblings, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2015-09-08 19:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/07, Rajendra Nayak wrote:
> >
> >Yeah this might happen though because we've assigned the of_node
> >pointer to the tsens device before we register it on the platform
> >bus. The other way to pass that data down from gcc to tsens would
> >be to not have an of_node assigned to the tsens device, and check
> >for that case in the tsens driver. If there isn't an of_node,
> >then we look at the parent device's of_node to figure out which
> >gcc it is (if this even matters) and parse DT properties.
> 
> Parsing DT properties from parent (in the tsens driver) is fine, but
> the nvmem apis still expect an of_node for the tsens device and hence
> fail.

So pass the parent device to the nvmem APIs? Or adjust the nvmem
APIs to look for a parent of_node if there isn't an of_node for
the device being passed? Or make the nvmem APIs work without
using DT, and copy over the nvmem information from the gcc node
to the virtual tsens child device?

> 
> Associating the of_node of the parent to the tsens device while being
> probed ends up with the same issues of gcc ending up probing the device
> and failing because tsens defers probe a couple times before a
> successful probe.

Yeah sounds like we shouldn't do it that way.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-09-08 19:21                   ` Stephen Boyd
@ 2015-09-09  3:33                     ` Rajendra Nayak
  2015-09-09  5:15                       ` Rajendra Nayak
  2015-09-09  9:11                       ` Srinivas Kandagatla
  0 siblings, 2 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-09-09  3:33 UTC (permalink / raw)
  To: linux-arm-kernel


On 09/09/2015 12:51 AM, Stephen Boyd wrote:
> On 09/07, Rajendra Nayak wrote:
>>>
>>> Yeah this might happen though because we've assigned the of_node
>>> pointer to the tsens device before we register it on the platform
>>> bus. The other way to pass that data down from gcc to tsens would
>>> be to not have an of_node assigned to the tsens device, and check
>>> for that case in the tsens driver. If there isn't an of_node,
>>> then we look at the parent device's of_node to figure out which
>>> gcc it is (if this even matters) and parse DT properties.
>>
>> Parsing DT properties from parent (in the tsens driver) is fine, but
>> the nvmem apis still expect an of_node for the tsens device and hence
>> fail.
>
> So pass the parent device to the nvmem APIs? Or adjust the nvmem
> APIs to look for a parent of_node if there isn't an of_node for
> the device being passed? Or make the nvmem APIs work without
> using DT, and copy over the nvmem information from the gcc node
> to the virtual tsens child device?

Srini, you being the nvmem maintainer, any thoughts?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-09-09  3:33                     ` Rajendra Nayak
@ 2015-09-09  5:15                       ` Rajendra Nayak
  2015-09-09  9:11                       ` Srinivas Kandagatla
  1 sibling, 0 replies; 27+ messages in thread
From: Rajendra Nayak @ 2015-09-09  5:15 UTC (permalink / raw)
  To: linux-arm-kernel


On 09/09/2015 09:03 AM, Rajendra Nayak wrote:
>
> On 09/09/2015 12:51 AM, Stephen Boyd wrote:
>> On 09/07, Rajendra Nayak wrote:
>>>>
>>>> Yeah this might happen though because we've assigned the of_node
>>>> pointer to the tsens device before we register it on the platform
>>>> bus. The other way to pass that data down from gcc to tsens would
>>>> be to not have an of_node assigned to the tsens device, and check
>>>> for that case in the tsens driver. If there isn't an of_node,
>>>> then we look at the parent device's of_node to figure out which
>>>> gcc it is (if this even matters) and parse DT properties.
>>>
>>> Parsing DT properties from parent (in the tsens driver) is fine, but
>>> the nvmem apis still expect an of_node for the tsens device and hence
>>> fail.
>>
>> So pass the parent device to the nvmem APIs? Or adjust the nvmem
>> APIs to look for a parent of_node if there isn't an of_node for
>> the device being passed? Or make the nvmem APIs work without
>> using DT, and copy over the nvmem information from the gcc node
>> to the virtual tsens child device?
>
> Srini, you being the nvmem maintainer, any thoughts?

passing the parent device to nvmem APIs seems the cleanest to me,
without having to change much with the nvmem APIs itself.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
  2015-09-09  3:33                     ` Rajendra Nayak
  2015-09-09  5:15                       ` Rajendra Nayak
@ 2015-09-09  9:11                       ` Srinivas Kandagatla
  1 sibling, 0 replies; 27+ messages in thread
From: Srinivas Kandagatla @ 2015-09-09  9:11 UTC (permalink / raw)
  To: linux-arm-kernel



On 09/09/15 04:33, Rajendra Nayak wrote:
>
> On 09/09/2015 12:51 AM, Stephen Boyd wrote:
>> On 09/07, Rajendra Nayak wrote:
>>>>
>>>> Yeah this might happen though because we've assigned the of_node
>>>> pointer to the tsens device before we register it on the platform
>>>> bus. The other way to pass that data down from gcc to tsens would
>>>> be to not have an of_node assigned to the tsens device, and check
>>>> for that case in the tsens driver. If there isn't an of_node,
>>>> then we look at the parent device's of_node to figure out which
>>>> gcc it is (if this even matters) and parse DT properties.
>>>
>>> Parsing DT properties from parent (in the tsens driver) is fine, but
>>> the nvmem apis still expect an of_node for the tsens device and hence
>>> fail.
>>
>> So pass the parent device to the nvmem APIs? Or adjust the nvmem
>> APIs to look for a parent of_node if there isn't an of_node for
>> the device being passed? Or make the nvmem APIs work without
>> using DT, and copy over the nvmem information from the gcc node
>> to the virtual tsens child device?
>
> Srini, you being the nvmem maintainer, any thoughts?

We could do either one of the below.
1> pass parent device for nvmem_get_cell as suggested by Stephen
2> use of_nvmem_get_cell() api to pass correct of_node

Both of them would work.

--srini
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2015-09-09  9:11 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-08  9:47 [PATCH 0/9] qcom: Add support for TSENS driver Rajendra Nayak
2015-07-08  9:47 ` [PATCH 1/9] thermal: qcom: tsens: Add a skeletal TSENS drivers Rajendra Nayak
2015-07-08  9:47 ` [PATCH 2/9] thermal: qcom: tsens-8916: Add support for 8916 family of SoCs Rajendra Nayak
2015-07-08  9:47 ` [PATCH 3/9] thermal: qcom: tsens-8974: Add support for 8974 " Rajendra Nayak
2015-07-08  9:47 ` [PATCH 4/9] thermal: qcom: tsens-8960: Add support for 8960 " Rajendra Nayak
2015-07-08  9:47 ` [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support Rajendra Nayak
2015-08-11 22:49   ` Stephen Boyd
2015-08-12  9:00     ` Srinivas Kandagatla
2015-08-13  4:28       ` Rajendra Nayak
2015-08-14  0:42         ` Stephen Boyd
2015-08-14  3:09           ` Rajendra Nayak
2015-09-02  2:37             ` Rajendra Nayak
2015-09-03 17:27               ` Stephen Boyd
2015-09-07  6:39                 ` Rajendra Nayak
2015-09-08 19:21                   ` Stephen Boyd
2015-09-09  3:33                     ` Rajendra Nayak
2015-09-09  5:15                       ` Rajendra Nayak
2015-09-09  9:11                       ` Srinivas Kandagatla
2015-08-12 20:18     ` Bjorn Andersson
2015-08-12 21:57       ` Stephen Boyd
2015-08-13  4:14         ` Bjorn Andersson
2015-08-14  0:46           ` Stephen Boyd
2015-07-08  9:47 ` [PATCH 6/9] arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes Rajendra Nayak
2015-07-08  9:47 ` [PATCH 7/9] arm: dts: apq8064: " Rajendra Nayak
2015-07-08  9:47 ` [PATCH 8/9] arm: dts: apq8084: " Rajendra Nayak
2015-07-08  9:47 ` [PATCH 9/9] arm64: dts: msm8916: " Rajendra Nayak
2015-08-11  8:26 ` [PATCH 0/9] qcom: Add support for TSENS driver Srinivas Kandagatla

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).