All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 1/2] regulator: max8973: add DT binding details for junction warn temp
@ 2016-04-13  9:59 ` Laxman Dewangan
  0 siblings, 0 replies; 17+ messages in thread
From: Laxman Dewangan @ 2016-04-13  9:59 UTC (permalink / raw)
  To: broonie, robh+dt, lgirdwood
  Cc: mark.rutland, devicetree, linux-kernel, Laxman Dewangan

The driver MAX8973 supports the driver for Maxim MAX77621.
MAX77621 supports the junction temp warning at 120 degC and
140 degC which is configurable. It generates alert signal when
junction temperature crosses these threshold.

Add DT properties and its binding details to make this
configuration from DT.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
 Documentation/devicetree/bindings/regulator/max8973-regulator.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
index f80ea2f..c2c68fc 100644
--- a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
@@ -32,6 +32,13 @@ Optional properties:
 
 Enhanced transient response (ETR) will affect the configuration of CKADV.
 
+-junction-warn-millicelsius: u32, junction warning temperature threshold
+		in millicelsius. If die temperature crosses this level then
+		device generates the warning interrupts.
+
+Please note that thermal functionality is only supported on MAX77621. The
+supported threshold warning temperature for MAX77621 are 120 degC and 140 degC.
+
 Example:
 
 	max8973@1b {
-- 
2.1.4

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

* [PATCH V3 1/2] regulator: max8973: add DT binding details for junction warn temp
@ 2016-04-13  9:59 ` Laxman Dewangan
  0 siblings, 0 replies; 17+ messages in thread
From: Laxman Dewangan @ 2016-04-13  9:59 UTC (permalink / raw)
  To: broonie, robh+dt, lgirdwood
  Cc: mark.rutland, devicetree, linux-kernel, Laxman Dewangan

The driver MAX8973 supports the driver for Maxim MAX77621.
MAX77621 supports the junction temp warning at 120 degC and
140 degC which is configurable. It generates alert signal when
junction temperature crosses these threshold.

Add DT properties and its binding details to make this
configuration from DT.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
---
 Documentation/devicetree/bindings/regulator/max8973-regulator.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
index f80ea2f..c2c68fc 100644
--- a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
@@ -32,6 +32,13 @@ Optional properties:
 
 Enhanced transient response (ETR) will affect the configuration of CKADV.
 
+-junction-warn-millicelsius: u32, junction warning temperature threshold
+		in millicelsius. If die temperature crosses this level then
+		device generates the warning interrupts.
+
+Please note that thermal functionality is only supported on MAX77621. The
+supported threshold warning temperature for MAX77621 are 120 degC and 140 degC.
+
 Example:
 
 	max8973@1b {
-- 
2.1.4

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

* [PATCH V3 2/2] regulator: max8973: add support for junction thermal warning
  2016-04-13  9:59 ` Laxman Dewangan
@ 2016-04-13  9:59   ` Laxman Dewangan
  -1 siblings, 0 replies; 17+ messages in thread
From: Laxman Dewangan @ 2016-04-13  9:59 UTC (permalink / raw)
  To: broonie, robh+dt, lgirdwood
  Cc: mark.rutland, devicetree, linux-kernel, Laxman Dewangan

The driver MAX8973 supports the driver for Maxim PMIC MAX77621.
MAX77621 supports the junction temp warning at 120 degC and
140 degC which is configurable. It generates alert signal when
junction temperature crosses these threshold.

MAX77621 does not support the continuous temp monitoring of
junction temperature. It just report whether junction temperature
crossed the threshold or not.

Add support to
- Configure junction temp warning threshold via DT property
to generate alert when it crosses the threshold.
- Add support to interrupt the host from this device when alert
occurred.
- read the junction temp via thermal framework.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>

---
Changes from V1:
Split this in 2 patches, one from driver and other for binding doc.
Taken care of Rob's review comment for property change.

Changes from V2:
This patch was submitted earlier and reverted due to compilation issue
from kbuildtest robot.
The fix on this patch are:
- make driver to depends on THERMAL && THERMAL_OF.
- Use devm_ for thermal sensor and interrupt regsitartion and so removed
  the need of .remove callback.
---
 drivers/regulator/Kconfig                   |  1 +
 drivers/regulator/max8973-regulator.c       | 97 +++++++++++++++++++++++++++++
 include/linux/regulator/max8973-regulator.h |  5 ++
 3 files changed, 103 insertions(+)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c77dc08..129359f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -409,6 +409,7 @@ config REGULATOR_MAX8952
 config REGULATOR_MAX8973
 	tristate "Maxim MAX8973 voltage regulator "
 	depends on I2C
+	depends on THERMAL && THERMAL_OF
 	select REGMAP_I2C
 	help
 	  The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 5b75b7c..08d2f13 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -38,6 +38,9 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
+#include <linux/thermal.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 /* Register definitions */
 #define MAX8973_VOUT					0x0
@@ -74,6 +77,7 @@
 #define MAX8973_WDTMR_ENABLE				BIT(6)
 #define MAX8973_DISCH_ENBABLE				BIT(5)
 #define MAX8973_FT_ENABLE				BIT(4)
+#define MAX77621_T_JUNCTION_120				BIT(7)
 
 #define MAX8973_CKKADV_TRIP_MASK			0xC
 #define MAX8973_CKKADV_TRIP_DISABLE			0xC
@@ -93,6 +97,12 @@
 #define MAX8973_VOLATGE_STEP				6250
 #define MAX8973_BUCK_N_VOLTAGE				0x80
 
+#define MAX77621_CHIPID_TJINT_S				BIT(0)
+
+#define MAX77621_NORMAL_OPERATING_TEMP			100000
+#define MAX77621_TJINT_WARNING_TEMP_120			120000
+#define MAX77621_TJINT_WARNING_TEMP_140			140000
+
 enum device_id {
 	MAX8973,
 	MAX77621
@@ -112,6 +122,9 @@ struct max8973_chip {
 	int curr_gpio_val;
 	struct regulator_ops ops;
 	enum device_id id;
+	int junction_temp_warning;
+	int irq;
+	struct thermal_zone_device *tz_device;
 };
 
 /*
@@ -391,6 +404,10 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
 		control1 |= MAX8973_FREQSHIFT_9PER;
 
+	if ((pdata->junction_temp_warning == MAX77621_TJINT_WARNING_TEMP_120) &&
+	    (max->id == MAX77621))
+		control2 |= MAX77621_T_JUNCTION_120;
+
 	if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
 		control2 |= MAX8973_DISCH_ENBABLE;
 
@@ -457,6 +474,79 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	return ret;
 }
 
+static int max8973_thermal_read_temp(void *data, int *temp)
+{
+	struct max8973_chip *mchip = data;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to read register CHIPID1, %d", ret);
+		return ret;
+	}
+
+	/* +1 degC to trigger cool devive */
+	if (val & MAX77621_CHIPID_TJINT_S)
+		*temp = mchip->junction_temp_warning + 1000;
+	else
+		*temp = MAX77621_NORMAL_OPERATING_TEMP;
+
+	return 0;
+}
+
+static irqreturn_t max8973_thermal_irq(int irq, void *data)
+{
+	struct max8973_chip *mchip = data;
+
+	thermal_zone_device_update(mchip->tz_device);
+
+	return IRQ_HANDLED;
+}
+
+static const struct thermal_zone_of_device_ops max77621_tz_ops = {
+	.get_temp = max8973_thermal_read_temp,
+};
+
+static int max8973_thermal_init(struct max8973_chip *mchip)
+{
+	struct thermal_zone_device *tzd;
+	struct irq_data *irq_data;
+	unsigned long irq_flags = 0;
+	int ret;
+
+	if (mchip->id != MAX77621)
+		return 0;
+
+	tzd = devm_thermal_zone_of_sensor_register(mchip->dev, 0, mchip,
+						   &max77621_tz_ops);
+	if (IS_ERR(tzd)) {
+		ret = PTR_ERR(tzd);
+		dev_err(mchip->dev, "Failed to register thermal sensor: %d\n",
+			ret);
+		return ret;
+	}
+
+	if (mchip->irq <= 0)
+		return 0;
+
+	irq_data = irq_get_irq_data(mchip->irq);
+	if (irq_data)
+		irq_flags = irqd_get_trigger_type(irq_data);
+
+	ret = devm_request_threaded_irq(mchip->dev, mchip->irq, NULL,
+					max8973_thermal_irq,
+					IRQF_ONESHOT | IRQF_SHARED | irq_flags,
+					dev_name(mchip->dev), mchip);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to request irq %d, %d\n",
+			mchip->irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static const struct regmap_config max8973_regmap_config = {
 	.reg_bits		= 8,
 	.val_bits		= 8,
@@ -521,6 +611,11 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
 		pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
 	}
 
+	pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140;
+	ret = of_property_read_u32(np, "junction-warn-millicelsius", &pval);
+	if (!ret && (pval <= MAX77621_TJINT_WARNING_TEMP_120))
+		pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120;
+
 	return pdata;
 }
 
@@ -608,6 +703,7 @@ static int max8973_probe(struct i2c_client *client,
 	max->enable_external_control = pdata->enable_ext_control;
 	max->curr_gpio_val = pdata->dvs_def_state;
 	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
+	max->junction_temp_warning = pdata->junction_temp_warning;
 
 	if (gpio_is_valid(max->enable_gpio))
 		max->enable_external_control = true;
@@ -718,6 +814,7 @@ static int max8973_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	max8973_thermal_init(max);
 	return 0;
 }
 
diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h
index f6a8a16..2fcb998 100644
--- a/include/linux/regulator/max8973-regulator.h
+++ b/include/linux/regulator/max8973-regulator.h
@@ -54,6 +54,10 @@
  * @reg_init_data: The regulator init data.
  * @control_flags: Control flags which are ORed value of above flags to
  *		configure device.
+ * @junction_temp_warning: Junction temp in millicelcius on which warning need
+ *			   to be set. Thermal functionality is only supported on
+ *			   MAX77621. The threshold warning supported by MAX77621
+ *			   are 120C and 140C.
  * @enable_ext_control: Enable the voltage enable/disable through external
  *		control signal from EN input pin. If it is false then
  *		voltage output will be enabled/disabled through EN bit of
@@ -67,6 +71,7 @@
 struct max8973_regulator_platform_data {
 	struct regulator_init_data *reg_init_data;
 	unsigned long control_flags;
+	unsigned long junction_temp_warning;
 	bool enable_ext_control;
 	int enable_gpio;
 	int dvs_gpio;
-- 
2.1.4

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

* [PATCH V3 2/2] regulator: max8973: add support for junction thermal warning
@ 2016-04-13  9:59   ` Laxman Dewangan
  0 siblings, 0 replies; 17+ messages in thread
From: Laxman Dewangan @ 2016-04-13  9:59 UTC (permalink / raw)
  To: broonie, robh+dt, lgirdwood
  Cc: mark.rutland, devicetree, linux-kernel, Laxman Dewangan

The driver MAX8973 supports the driver for Maxim PMIC MAX77621.
MAX77621 supports the junction temp warning at 120 degC and
140 degC which is configurable. It generates alert signal when
junction temperature crosses these threshold.

MAX77621 does not support the continuous temp monitoring of
junction temperature. It just report whether junction temperature
crossed the threshold or not.

Add support to
- Configure junction temp warning threshold via DT property
to generate alert when it crosses the threshold.
- Add support to interrupt the host from this device when alert
occurred.
- read the junction temp via thermal framework.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>

---
Changes from V1:
Split this in 2 patches, one from driver and other for binding doc.
Taken care of Rob's review comment for property change.

Changes from V2:
This patch was submitted earlier and reverted due to compilation issue
from kbuildtest robot.
The fix on this patch are:
- make driver to depends on THERMAL && THERMAL_OF.
- Use devm_ for thermal sensor and interrupt regsitartion and so removed
  the need of .remove callback.
---
 drivers/regulator/Kconfig                   |  1 +
 drivers/regulator/max8973-regulator.c       | 97 +++++++++++++++++++++++++++++
 include/linux/regulator/max8973-regulator.h |  5 ++
 3 files changed, 103 insertions(+)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c77dc08..129359f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -409,6 +409,7 @@ config REGULATOR_MAX8952
 config REGULATOR_MAX8973
 	tristate "Maxim MAX8973 voltage regulator "
 	depends on I2C
+	depends on THERMAL && THERMAL_OF
 	select REGMAP_I2C
 	help
 	  The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 5b75b7c..08d2f13 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -38,6 +38,9 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
+#include <linux/thermal.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 /* Register definitions */
 #define MAX8973_VOUT					0x0
@@ -74,6 +77,7 @@
 #define MAX8973_WDTMR_ENABLE				BIT(6)
 #define MAX8973_DISCH_ENBABLE				BIT(5)
 #define MAX8973_FT_ENABLE				BIT(4)
+#define MAX77621_T_JUNCTION_120				BIT(7)
 
 #define MAX8973_CKKADV_TRIP_MASK			0xC
 #define MAX8973_CKKADV_TRIP_DISABLE			0xC
@@ -93,6 +97,12 @@
 #define MAX8973_VOLATGE_STEP				6250
 #define MAX8973_BUCK_N_VOLTAGE				0x80
 
+#define MAX77621_CHIPID_TJINT_S				BIT(0)
+
+#define MAX77621_NORMAL_OPERATING_TEMP			100000
+#define MAX77621_TJINT_WARNING_TEMP_120			120000
+#define MAX77621_TJINT_WARNING_TEMP_140			140000
+
 enum device_id {
 	MAX8973,
 	MAX77621
@@ -112,6 +122,9 @@ struct max8973_chip {
 	int curr_gpio_val;
 	struct regulator_ops ops;
 	enum device_id id;
+	int junction_temp_warning;
+	int irq;
+	struct thermal_zone_device *tz_device;
 };
 
 /*
@@ -391,6 +404,10 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
 		control1 |= MAX8973_FREQSHIFT_9PER;
 
+	if ((pdata->junction_temp_warning == MAX77621_TJINT_WARNING_TEMP_120) &&
+	    (max->id == MAX77621))
+		control2 |= MAX77621_T_JUNCTION_120;
+
 	if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
 		control2 |= MAX8973_DISCH_ENBABLE;
 
@@ -457,6 +474,79 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	return ret;
 }
 
+static int max8973_thermal_read_temp(void *data, int *temp)
+{
+	struct max8973_chip *mchip = data;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to read register CHIPID1, %d", ret);
+		return ret;
+	}
+
+	/* +1 degC to trigger cool devive */
+	if (val & MAX77621_CHIPID_TJINT_S)
+		*temp = mchip->junction_temp_warning + 1000;
+	else
+		*temp = MAX77621_NORMAL_OPERATING_TEMP;
+
+	return 0;
+}
+
+static irqreturn_t max8973_thermal_irq(int irq, void *data)
+{
+	struct max8973_chip *mchip = data;
+
+	thermal_zone_device_update(mchip->tz_device);
+
+	return IRQ_HANDLED;
+}
+
+static const struct thermal_zone_of_device_ops max77621_tz_ops = {
+	.get_temp = max8973_thermal_read_temp,
+};
+
+static int max8973_thermal_init(struct max8973_chip *mchip)
+{
+	struct thermal_zone_device *tzd;
+	struct irq_data *irq_data;
+	unsigned long irq_flags = 0;
+	int ret;
+
+	if (mchip->id != MAX77621)
+		return 0;
+
+	tzd = devm_thermal_zone_of_sensor_register(mchip->dev, 0, mchip,
+						   &max77621_tz_ops);
+	if (IS_ERR(tzd)) {
+		ret = PTR_ERR(tzd);
+		dev_err(mchip->dev, "Failed to register thermal sensor: %d\n",
+			ret);
+		return ret;
+	}
+
+	if (mchip->irq <= 0)
+		return 0;
+
+	irq_data = irq_get_irq_data(mchip->irq);
+	if (irq_data)
+		irq_flags = irqd_get_trigger_type(irq_data);
+
+	ret = devm_request_threaded_irq(mchip->dev, mchip->irq, NULL,
+					max8973_thermal_irq,
+					IRQF_ONESHOT | IRQF_SHARED | irq_flags,
+					dev_name(mchip->dev), mchip);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to request irq %d, %d\n",
+			mchip->irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static const struct regmap_config max8973_regmap_config = {
 	.reg_bits		= 8,
 	.val_bits		= 8,
@@ -521,6 +611,11 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
 		pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
 	}
 
+	pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140;
+	ret = of_property_read_u32(np, "junction-warn-millicelsius", &pval);
+	if (!ret && (pval <= MAX77621_TJINT_WARNING_TEMP_120))
+		pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120;
+
 	return pdata;
 }
 
@@ -608,6 +703,7 @@ static int max8973_probe(struct i2c_client *client,
 	max->enable_external_control = pdata->enable_ext_control;
 	max->curr_gpio_val = pdata->dvs_def_state;
 	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
+	max->junction_temp_warning = pdata->junction_temp_warning;
 
 	if (gpio_is_valid(max->enable_gpio))
 		max->enable_external_control = true;
@@ -718,6 +814,7 @@ static int max8973_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	max8973_thermal_init(max);
 	return 0;
 }
 
diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h
index f6a8a16..2fcb998 100644
--- a/include/linux/regulator/max8973-regulator.h
+++ b/include/linux/regulator/max8973-regulator.h
@@ -54,6 +54,10 @@
  * @reg_init_data: The regulator init data.
  * @control_flags: Control flags which are ORed value of above flags to
  *		configure device.
+ * @junction_temp_warning: Junction temp in millicelcius on which warning need
+ *			   to be set. Thermal functionality is only supported on
+ *			   MAX77621. The threshold warning supported by MAX77621
+ *			   are 120C and 140C.
  * @enable_ext_control: Enable the voltage enable/disable through external
  *		control signal from EN input pin. If it is false then
  *		voltage output will be enabled/disabled through EN bit of
@@ -67,6 +71,7 @@
 struct max8973_regulator_platform_data {
 	struct regulator_init_data *reg_init_data;
 	unsigned long control_flags;
+	unsigned long junction_temp_warning;
 	bool enable_ext_control;
 	int enable_gpio;
 	int dvs_gpio;
-- 
2.1.4

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

* Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
@ 2016-04-13 16:21     ` Mark Brown
  0 siblings, 0 replies; 17+ messages in thread
From: Mark Brown @ 2016-04-13 16:21 UTC (permalink / raw)
  To: Laxman Dewangan
  Cc: Mark Brown, broonie, robh+dt, lgirdwood, mark.rutland,
	devicetree, linux-kernel

The patch

   regulator: max8973: add support for junction thermal warning

has been applied to the regulator tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From d2d5437bdfdde20a75bdf59db1c1a77721613b22 Mon Sep 17 00:00:00 2001
From: Laxman Dewangan <ldewangan@nvidia.com>
Date: Wed, 13 Apr 2016 15:29:45 +0530
Subject: [PATCH] regulator: max8973: add support for junction thermal warning

The driver MAX8973 supports the driver for Maxim PMIC MAX77621.
MAX77621 supports the junction temp warning at 120 degC and
140 degC which is configurable. It generates alert signal when
junction temperature crosses these threshold.

MAX77621 does not support the continuous temp monitoring of
junction temperature. It just report whether junction temperature
crossed the threshold or not.

Add support to
- Configure junction temp warning threshold via DT property
to generate alert when it crosses the threshold.
- Add support to interrupt the host from this device when alert
occurred.
- read the junction temp via thermal framework.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/regulator/Kconfig                   |  1 +
 drivers/regulator/max8973-regulator.c       | 97 +++++++++++++++++++++++++++++
 include/linux/regulator/max8973-regulator.h |  5 ++
 3 files changed, 103 insertions(+)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c77dc08b1202..129359f775d0 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -409,6 +409,7 @@ config REGULATOR_MAX8952
 config REGULATOR_MAX8973
 	tristate "Maxim MAX8973 voltage regulator "
 	depends on I2C
+	depends on THERMAL && THERMAL_OF
 	select REGMAP_I2C
 	help
 	  The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 5b75b7c2e3ea..08d2f13eca00 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -38,6 +38,9 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
+#include <linux/thermal.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 /* Register definitions */
 #define MAX8973_VOUT					0x0
@@ -74,6 +77,7 @@
 #define MAX8973_WDTMR_ENABLE				BIT(6)
 #define MAX8973_DISCH_ENBABLE				BIT(5)
 #define MAX8973_FT_ENABLE				BIT(4)
+#define MAX77621_T_JUNCTION_120				BIT(7)
 
 #define MAX8973_CKKADV_TRIP_MASK			0xC
 #define MAX8973_CKKADV_TRIP_DISABLE			0xC
@@ -93,6 +97,12 @@
 #define MAX8973_VOLATGE_STEP				6250
 #define MAX8973_BUCK_N_VOLTAGE				0x80
 
+#define MAX77621_CHIPID_TJINT_S				BIT(0)
+
+#define MAX77621_NORMAL_OPERATING_TEMP			100000
+#define MAX77621_TJINT_WARNING_TEMP_120			120000
+#define MAX77621_TJINT_WARNING_TEMP_140			140000
+
 enum device_id {
 	MAX8973,
 	MAX77621
@@ -112,6 +122,9 @@ struct max8973_chip {
 	int curr_gpio_val;
 	struct regulator_ops ops;
 	enum device_id id;
+	int junction_temp_warning;
+	int irq;
+	struct thermal_zone_device *tz_device;
 };
 
 /*
@@ -391,6 +404,10 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
 		control1 |= MAX8973_FREQSHIFT_9PER;
 
+	if ((pdata->junction_temp_warning == MAX77621_TJINT_WARNING_TEMP_120) &&
+	    (max->id == MAX77621))
+		control2 |= MAX77621_T_JUNCTION_120;
+
 	if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
 		control2 |= MAX8973_DISCH_ENBABLE;
 
@@ -457,6 +474,79 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	return ret;
 }
 
+static int max8973_thermal_read_temp(void *data, int *temp)
+{
+	struct max8973_chip *mchip = data;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to read register CHIPID1, %d", ret);
+		return ret;
+	}
+
+	/* +1 degC to trigger cool devive */
+	if (val & MAX77621_CHIPID_TJINT_S)
+		*temp = mchip->junction_temp_warning + 1000;
+	else
+		*temp = MAX77621_NORMAL_OPERATING_TEMP;
+
+	return 0;
+}
+
+static irqreturn_t max8973_thermal_irq(int irq, void *data)
+{
+	struct max8973_chip *mchip = data;
+
+	thermal_zone_device_update(mchip->tz_device);
+
+	return IRQ_HANDLED;
+}
+
+static const struct thermal_zone_of_device_ops max77621_tz_ops = {
+	.get_temp = max8973_thermal_read_temp,
+};
+
+static int max8973_thermal_init(struct max8973_chip *mchip)
+{
+	struct thermal_zone_device *tzd;
+	struct irq_data *irq_data;
+	unsigned long irq_flags = 0;
+	int ret;
+
+	if (mchip->id != MAX77621)
+		return 0;
+
+	tzd = devm_thermal_zone_of_sensor_register(mchip->dev, 0, mchip,
+						   &max77621_tz_ops);
+	if (IS_ERR(tzd)) {
+		ret = PTR_ERR(tzd);
+		dev_err(mchip->dev, "Failed to register thermal sensor: %d\n",
+			ret);
+		return ret;
+	}
+
+	if (mchip->irq <= 0)
+		return 0;
+
+	irq_data = irq_get_irq_data(mchip->irq);
+	if (irq_data)
+		irq_flags = irqd_get_trigger_type(irq_data);
+
+	ret = devm_request_threaded_irq(mchip->dev, mchip->irq, NULL,
+					max8973_thermal_irq,
+					IRQF_ONESHOT | IRQF_SHARED | irq_flags,
+					dev_name(mchip->dev), mchip);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to request irq %d, %d\n",
+			mchip->irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static const struct regmap_config max8973_regmap_config = {
 	.reg_bits		= 8,
 	.val_bits		= 8,
@@ -521,6 +611,11 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
 		pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
 	}
 
+	pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140;
+	ret = of_property_read_u32(np, "junction-warn-millicelsius", &pval);
+	if (!ret && (pval <= MAX77621_TJINT_WARNING_TEMP_120))
+		pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120;
+
 	return pdata;
 }
 
@@ -608,6 +703,7 @@ static int max8973_probe(struct i2c_client *client,
 	max->enable_external_control = pdata->enable_ext_control;
 	max->curr_gpio_val = pdata->dvs_def_state;
 	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
+	max->junction_temp_warning = pdata->junction_temp_warning;
 
 	if (gpio_is_valid(max->enable_gpio))
 		max->enable_external_control = true;
@@ -718,6 +814,7 @@ static int max8973_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	max8973_thermal_init(max);
 	return 0;
 }
 
diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h
index f6a8a16a0d4d..2fcb9980262a 100644
--- a/include/linux/regulator/max8973-regulator.h
+++ b/include/linux/regulator/max8973-regulator.h
@@ -54,6 +54,10 @@
  * @reg_init_data: The regulator init data.
  * @control_flags: Control flags which are ORed value of above flags to
  *		configure device.
+ * @junction_temp_warning: Junction temp in millicelcius on which warning need
+ *			   to be set. Thermal functionality is only supported on
+ *			   MAX77621. The threshold warning supported by MAX77621
+ *			   are 120C and 140C.
  * @enable_ext_control: Enable the voltage enable/disable through external
  *		control signal from EN input pin. If it is false then
  *		voltage output will be enabled/disabled through EN bit of
@@ -67,6 +71,7 @@
 struct max8973_regulator_platform_data {
 	struct regulator_init_data *reg_init_data;
 	unsigned long control_flags;
+	unsigned long junction_temp_warning;
 	bool enable_ext_control;
 	int enable_gpio;
 	int dvs_gpio;
-- 
2.8.0.rc3

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

* Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
@ 2016-04-13 16:21     ` Mark Brown
  0 siblings, 0 replies; 17+ messages in thread
From: Mark Brown @ 2016-04-13 16:21 UTC (permalink / raw)
  To: Laxman Dewangan; +Cc: Mark Brown

The patch

   regulator: max8973: add support for junction thermal warning

has been applied to the regulator tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From d2d5437bdfdde20a75bdf59db1c1a77721613b22 Mon Sep 17 00:00:00 2001
From: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Date: Wed, 13 Apr 2016 15:29:45 +0530
Subject: [PATCH] regulator: max8973: add support for junction thermal warning

The driver MAX8973 supports the driver for Maxim PMIC MAX77621.
MAX77621 supports the junction temp warning at 120 degC and
140 degC which is configurable. It generates alert signal when
junction temperature crosses these threshold.

MAX77621 does not support the continuous temp monitoring of
junction temperature. It just report whether junction temperature
crossed the threshold or not.

Add support to
- Configure junction temp warning threshold via DT property
to generate alert when it crosses the threshold.
- Add support to interrupt the host from this device when alert
occurred.
- read the junction temp via thermal framework.

Signed-off-by: Laxman Dewangan <ldewangan-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 drivers/regulator/Kconfig                   |  1 +
 drivers/regulator/max8973-regulator.c       | 97 +++++++++++++++++++++++++++++
 include/linux/regulator/max8973-regulator.h |  5 ++
 3 files changed, 103 insertions(+)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c77dc08b1202..129359f775d0 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -409,6 +409,7 @@ config REGULATOR_MAX8952
 config REGULATOR_MAX8973
 	tristate "Maxim MAX8973 voltage regulator "
 	depends on I2C
+	depends on THERMAL && THERMAL_OF
 	select REGMAP_I2C
 	help
 	  The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 5b75b7c2e3ea..08d2f13eca00 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -38,6 +38,9 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
+#include <linux/thermal.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 /* Register definitions */
 #define MAX8973_VOUT					0x0
@@ -74,6 +77,7 @@
 #define MAX8973_WDTMR_ENABLE				BIT(6)
 #define MAX8973_DISCH_ENBABLE				BIT(5)
 #define MAX8973_FT_ENABLE				BIT(4)
+#define MAX77621_T_JUNCTION_120				BIT(7)
 
 #define MAX8973_CKKADV_TRIP_MASK			0xC
 #define MAX8973_CKKADV_TRIP_DISABLE			0xC
@@ -93,6 +97,12 @@
 #define MAX8973_VOLATGE_STEP				6250
 #define MAX8973_BUCK_N_VOLTAGE				0x80
 
+#define MAX77621_CHIPID_TJINT_S				BIT(0)
+
+#define MAX77621_NORMAL_OPERATING_TEMP			100000
+#define MAX77621_TJINT_WARNING_TEMP_120			120000
+#define MAX77621_TJINT_WARNING_TEMP_140			140000
+
 enum device_id {
 	MAX8973,
 	MAX77621
@@ -112,6 +122,9 @@ struct max8973_chip {
 	int curr_gpio_val;
 	struct regulator_ops ops;
 	enum device_id id;
+	int junction_temp_warning;
+	int irq;
+	struct thermal_zone_device *tz_device;
 };
 
 /*
@@ -391,6 +404,10 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
 		control1 |= MAX8973_FREQSHIFT_9PER;
 
+	if ((pdata->junction_temp_warning == MAX77621_TJINT_WARNING_TEMP_120) &&
+	    (max->id == MAX77621))
+		control2 |= MAX77621_T_JUNCTION_120;
+
 	if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
 		control2 |= MAX8973_DISCH_ENBABLE;
 
@@ -457,6 +474,79 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	return ret;
 }
 
+static int max8973_thermal_read_temp(void *data, int *temp)
+{
+	struct max8973_chip *mchip = data;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to read register CHIPID1, %d", ret);
+		return ret;
+	}
+
+	/* +1 degC to trigger cool devive */
+	if (val & MAX77621_CHIPID_TJINT_S)
+		*temp = mchip->junction_temp_warning + 1000;
+	else
+		*temp = MAX77621_NORMAL_OPERATING_TEMP;
+
+	return 0;
+}
+
+static irqreturn_t max8973_thermal_irq(int irq, void *data)
+{
+	struct max8973_chip *mchip = data;
+
+	thermal_zone_device_update(mchip->tz_device);
+
+	return IRQ_HANDLED;
+}
+
+static const struct thermal_zone_of_device_ops max77621_tz_ops = {
+	.get_temp = max8973_thermal_read_temp,
+};
+
+static int max8973_thermal_init(struct max8973_chip *mchip)
+{
+	struct thermal_zone_device *tzd;
+	struct irq_data *irq_data;
+	unsigned long irq_flags = 0;
+	int ret;
+
+	if (mchip->id != MAX77621)
+		return 0;
+
+	tzd = devm_thermal_zone_of_sensor_register(mchip->dev, 0, mchip,
+						   &max77621_tz_ops);
+	if (IS_ERR(tzd)) {
+		ret = PTR_ERR(tzd);
+		dev_err(mchip->dev, "Failed to register thermal sensor: %d\n",
+			ret);
+		return ret;
+	}
+
+	if (mchip->irq <= 0)
+		return 0;
+
+	irq_data = irq_get_irq_data(mchip->irq);
+	if (irq_data)
+		irq_flags = irqd_get_trigger_type(irq_data);
+
+	ret = devm_request_threaded_irq(mchip->dev, mchip->irq, NULL,
+					max8973_thermal_irq,
+					IRQF_ONESHOT | IRQF_SHARED | irq_flags,
+					dev_name(mchip->dev), mchip);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to request irq %d, %d\n",
+			mchip->irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static const struct regmap_config max8973_regmap_config = {
 	.reg_bits		= 8,
 	.val_bits		= 8,
@@ -521,6 +611,11 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
 		pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
 	}
 
+	pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140;
+	ret = of_property_read_u32(np, "junction-warn-millicelsius", &pval);
+	if (!ret && (pval <= MAX77621_TJINT_WARNING_TEMP_120))
+		pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120;
+
 	return pdata;
 }
 
@@ -608,6 +703,7 @@ static int max8973_probe(struct i2c_client *client,
 	max->enable_external_control = pdata->enable_ext_control;
 	max->curr_gpio_val = pdata->dvs_def_state;
 	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
+	max->junction_temp_warning = pdata->junction_temp_warning;
 
 	if (gpio_is_valid(max->enable_gpio))
 		max->enable_external_control = true;
@@ -718,6 +814,7 @@ static int max8973_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	max8973_thermal_init(max);
 	return 0;
 }
 
diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h
index f6a8a16a0d4d..2fcb9980262a 100644
--- a/include/linux/regulator/max8973-regulator.h
+++ b/include/linux/regulator/max8973-regulator.h
@@ -54,6 +54,10 @@
  * @reg_init_data: The regulator init data.
  * @control_flags: Control flags which are ORed value of above flags to
  *		configure device.
+ * @junction_temp_warning: Junction temp in millicelcius on which warning need
+ *			   to be set. Thermal functionality is only supported on
+ *			   MAX77621. The threshold warning supported by MAX77621
+ *			   are 120C and 140C.
  * @enable_ext_control: Enable the voltage enable/disable through external
  *		control signal from EN input pin. If it is false then
  *		voltage output will be enabled/disabled through EN bit of
@@ -67,6 +71,7 @@
 struct max8973_regulator_platform_data {
 	struct regulator_init_data *reg_init_data;
 	unsigned long control_flags;
+	unsigned long junction_temp_warning;
 	bool enable_ext_control;
 	int enable_gpio;
 	int dvs_gpio;
-- 
2.8.0.rc3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-04-13 16:21     ` Mark Brown
@ 2016-04-13 17:01       ` Laxman Dewangan
  -1 siblings, 0 replies; 17+ messages in thread
From: Laxman Dewangan @ 2016-04-13 17:01 UTC (permalink / raw)
  To: Mark Brown; +Cc: robh+dt, lgirdwood, mark.rutland, devicetree, linux-kernel


On Wednesday 13 April 2016 09:51 PM, Mark Brown wrote:
> The patch
>
>     regulator: max8973: add support for junction thermal warning
>
> has been applied to the regulator tree at
>
>     git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
>
> All being well this means that it will be integrated into the linux-next
> tree (usually sometime in the next 24 hours) and sent to Linus during
> the next merge window (or sooner if it is a bug fix), however if
> problems are discovered then the patch may be dropped or reverted.
>
> You may get further e-mails resulting from automated or manual testing
> and review of the tree, please engage with people reporting problems and
> send followup patches addressing any issues that are reported if needed.
>
> If any updates are required or you are submitting further changes they
> should be sent as incremental updates against current git, existing
> patches will not be replaced.
>
> Please add any relevant lists and maintainers to the CCs when replying
> to this mail.
>
> Thanks,
> Mark
>
>  From d2d5437bdfdde20a75bdf59db1c1a77721613b22 Mon Sep 17 00:00:00 2001
> From: Laxman Dewangan <ldewangan@nvidia.com>
> Date: Wed, 13 Apr 2016 15:29:45 +0530
> Subject: [PATCH] regulator: max8973: add support for junction thermal warning
>

Thank you very much for accepting patch. Hope at this time, it will pass 
the build test robot.
Unfortunately, it was reverted 2 times due to build issue on random config.

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
@ 2016-04-13 17:01       ` Laxman Dewangan
  0 siblings, 0 replies; 17+ messages in thread
From: Laxman Dewangan @ 2016-04-13 17:01 UTC (permalink / raw)
  To: Mark Brown; +Cc: robh+dt, lgirdwood, mark.rutland, devicetree, linux-kernel


On Wednesday 13 April 2016 09:51 PM, Mark Brown wrote:
> The patch
>
>     regulator: max8973: add support for junction thermal warning
>
> has been applied to the regulator tree at
>
>     git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
>
> All being well this means that it will be integrated into the linux-next
> tree (usually sometime in the next 24 hours) and sent to Linus during
> the next merge window (or sooner if it is a bug fix), however if
> problems are discovered then the patch may be dropped or reverted.
>
> You may get further e-mails resulting from automated or manual testing
> and review of the tree, please engage with people reporting problems and
> send followup patches addressing any issues that are reported if needed.
>
> If any updates are required or you are submitting further changes they
> should be sent as incremental updates against current git, existing
> patches will not be replaced.
>
> Please add any relevant lists and maintainers to the CCs when replying
> to this mail.
>
> Thanks,
> Mark
>
>  From d2d5437bdfdde20a75bdf59db1c1a77721613b22 Mon Sep 17 00:00:00 2001
> From: Laxman Dewangan <ldewangan@nvidia.com>
> Date: Wed, 13 Apr 2016 15:29:45 +0530
> Subject: [PATCH] regulator: max8973: add support for junction thermal warning
>

Thank you very much for accepting patch. Hope at this time, it will pass 
the build test robot.
Unfortunately, it was reverted 2 times due to build issue on random config.

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-03-07 10:54           ` Laxman Dewangan
@ 2016-03-08  2:22             ` Mark Brown
  0 siblings, 0 replies; 17+ messages in thread
From: Mark Brown @ 2016-03-08  2:22 UTC (permalink / raw)
  To: Laxman Dewangan
  Cc: linux-kernel, edubezval, rui.zhang, Geert Uytterhoeven, Simon Horman

[-- Attachment #1: Type: text/plain, Size: 267 bytes --]

On Mon, Mar 07, 2016 at 04:24:10PM +0530, Laxman Dewangan wrote:
> On Monday 07 March 2016 01:14 PM, Mark Brown wrote:

> >So that should be depends on THERMAL if THERMAL_OF

> depends on THERMAL &&  THERMAL_OF

THERMAL_OF hopefully can't be enabled without THERMAL.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-03-07  7:44         ` Mark Brown
@ 2016-03-07 10:54           ` Laxman Dewangan
  2016-03-08  2:22             ` Mark Brown
  0 siblings, 1 reply; 17+ messages in thread
From: Laxman Dewangan @ 2016-03-07 10:54 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-kernel, edubezval, rui.zhang, Geert Uytterhoeven, Simon Horman


On Monday 07 March 2016 01:14 PM, Mark Brown wrote:
> * PGP Signed by an unknown key
>
> On Mon, Mar 07, 2016 at 12:06:46PM +0530, Laxman Dewangan wrote:
>
>> Following will not help
>>              depends on THERMAL_OF if THERMAL_OF
>> because THERMAL_OF is always "y" even if THERMAL is "m".
>> Build error can by resolved by adding below in the Kconfig
>>      depends on THERMAL
>> but the issue is if THERMAL is "m" and  REGULATOR_MAX8973 is "y" as per the
> So that should be depends on THERMAL if THERMAL_OF

depends on THERMAL &&  THERMAL_OF

>> failure rand config then REGULATOR_MAX8973 automatically become "m". This
>> may break some existing platform.
> That's an inevitable consequence of adding this support, you can't get
> around it.
>

Did some more investigation on linux-next about the regression if we 
make this depends on THERMAL.

  MAX8973 enabled in  following defconfig
     arch/arm64/configs/defconfig:CONFIG_REGULATOR_MAX8973=y
         This has CONFIG_THERMAL=y
     arch/arm/configs/shmobile_defconfig:CONFIG_REGULATOR_MAX8973=y
         This has THERMAL_CONFIG=y
     arch/arm/configs/multi_v7_defconfig:CONFIG_REGULATOR_MAX8973=y
         This has THERMAL_CONFIG=y
     arch/arm/configs/pxa_defconfig:CONFIG_REGULATOR_MAX8973=m
         This has THERMAL_CONFIG=m

So there is no issue on making "depends on THERMAL".

Currently, only one user for this device in linux-next:
     arch/arm/boot/dts/r8a73a4-ape6evm.dts: compatible = "maxim,max8973";

and this is shmobile based.
     Adding Geert and Simon for their comment.

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-03-07  6:36       ` Laxman Dewangan
@ 2016-03-07  7:44         ` Mark Brown
  2016-03-07 10:54           ` Laxman Dewangan
  0 siblings, 1 reply; 17+ messages in thread
From: Mark Brown @ 2016-03-07  7:44 UTC (permalink / raw)
  To: Laxman Dewangan; +Cc: linux-kernel, edubezval, rui.zhang

[-- Attachment #1: Type: text/plain, Size: 1198 bytes --]

On Mon, Mar 07, 2016 at 12:06:46PM +0530, Laxman Dewangan wrote:

> Following will not help
>             depends on THERMAL_OF if THERMAL_OF
> because THERMAL_OF is always "y" even if THERMAL is "m".

> Build error can by resolved by adding below in the Kconfig
>     depends on THERMAL

> but the issue is if THERMAL is "m" and  REGULATOR_MAX8973 is "y" as per the

So that should be depends on THERMAL if THERMAL_OF

> failure rand config then REGULATOR_MAX8973 automatically become "m". This
> may break some existing platform.

That's an inevitable consequence of adding this support, you can't get
around it.

> Also this driver does not need hard dependency in the thermal as max8973
> does not support thermal but max77621 supports it which is again optional.

> Some of driver use
>     drivers/power/charger-manager.c:#ifdef CONFIG_THERMAL
>     drivers/power/power_supply_core.c:#ifdef CONFIG_THERMAL

> So can we give the similar try here and test for build?

This is still a hack; if this is causing real problems the thermal
subsystem should be doing something to avoid the issue (for example
providing an always built in stub) though I suspect in reality it's not
a practical issue.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-03-06 11:35     ` Mark Brown
@ 2016-03-07  6:36       ` Laxman Dewangan
  2016-03-07  7:44         ` Mark Brown
  0 siblings, 1 reply; 17+ messages in thread
From: Laxman Dewangan @ 2016-03-07  6:36 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, edubezval, rui.zhang


On Sunday 06 March 2016 05:05 PM, Mark Brown wrote:
> * PGP Signed by an unknown key
>
> On Sun, Mar 06, 2016 at 01:17:37PM +0530, Laxman Dewangan wrote:
>
>> Here driver is built in binary and THERMAL is the loadable module.
>> Do we really have THERMAL as module i.e. basic framework?
> If randconfig can generate it it's valid.
>
>> -#ifdef CONFIG_THERMAL_OF
>> +#ifdef CONFIG_THERMAL
>>   static int max8973_thermal_read_temp(void *data, int *temp)
>>   {
>>          struct max8973_chip *mchip = data;
> That looks like a hack that might break, I'd not expect it to help here
> and probably has some other config that can generate issues.  What I
> think should be happening here is something like
>
> 	depends on THERMAL_OF if THERMAL_OF
>
> or similar (ie, there's a direct dependency once the config is enabled).
>
Following will not help
             depends on THERMAL_OF if THERMAL_OF
because THERMAL_OF is always "y" even if THERMAL is "m".

Build error can by resolved by adding below in the Kconfig
     depends on THERMAL

but the issue is if THERMAL is "m" and  REGULATOR_MAX8973 is "y" as per 
the failure rand config then REGULATOR_MAX8973 automatically become "m". 
This may break some existing platform.

Also this driver does not need hard dependency in the thermal as max8973 
does not support thermal but max77621 supports it which is again optional.

Some of driver use
     drivers/power/charger-manager.c:#ifdef CONFIG_THERMAL
     drivers/power/power_supply_core.c:#ifdef CONFIG_THERMAL


So can we give the similar try here and test for build?

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-03-06  7:47   ` Laxman Dewangan
@ 2016-03-06 11:35     ` Mark Brown
  2016-03-07  6:36       ` Laxman Dewangan
  0 siblings, 1 reply; 17+ messages in thread
From: Mark Brown @ 2016-03-06 11:35 UTC (permalink / raw)
  To: Laxman Dewangan; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 732 bytes --]

On Sun, Mar 06, 2016 at 01:17:37PM +0530, Laxman Dewangan wrote:

> Here driver is built in binary and THERMAL is the loadable module.

> Do we really have THERMAL as module i.e. basic framework?

If randconfig can generate it it's valid.  

> -#ifdef CONFIG_THERMAL_OF
> +#ifdef CONFIG_THERMAL
>  static int max8973_thermal_read_temp(void *data, int *temp)
>  {
>         struct max8973_chip *mchip = data;

That looks like a hack that might break, I'd not expect it to help here
and probably has some other config that can generate issues.  What I
think should be happening here is something like

	depends on THERMAL_OF if THERMAL_OF

or similar (ie, there's a direct dependency once the config is enabled).

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-03-06  2:35 ` Mark Brown
@ 2016-03-06  7:47   ` Laxman Dewangan
  2016-03-06 11:35     ` Mark Brown
  0 siblings, 1 reply; 17+ messages in thread
From: Laxman Dewangan @ 2016-03-06  7:47 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel


On Sunday 06 March 2016 08:05 AM, Mark Brown wrote:
> * PGP Signed by an unknown key
>
> On Sat, Mar 05, 2016 at 09:25:49PM +0900, Mark Brown wrote:
>> The patch
>>
>>     regulator: max8973: add support for junction thermal warning
>>
>> has been applied to the regulator tree at
>>
>>     git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
>>
>> All being well this means that it will be integrated into the linux-next
>> tree (usually sometime in the next 24 hours) and sent to Linus during
>> the next merge window (or sooner if it is a bug fix), however if
>> problems are discovered then the patch may be dropped or reverted.
> ...and reverted because the 0day bot found similar build failures to the
> last time :(
>

I built for CONFIG_THERMAL=y and with  CONFIG_THERMAL disabled for arm64 
and it passed the build.

The failure is seen on following combination:
CONFIG_THERMAL=m
CONFIG_THERMAL_OF=y

CONFIG_REGULATOR_MAX8973=y


Here driver is built in binary and THERMAL is the loadable module.

Do we really have THERMAL as module i.e. basic framework?

I like to make 8973 independent of the THERMAL and that's why I used the 
ifdefs CONFIG_THERMAL_OF inside the driver. If THERMAL config is enabled 
then enable thermal support inside driver.

In driver, I used
#ifdef CONFIG_THERMAL_OF

This config is "y" if the THERMAL is enabled.

I made following change inside driver and then it builds properly for 
above combination:

/**
diff --git a/drivers/regulator/max8973-regulator.c 
b/drivers/regulator/max8973-regulator.c
index a5e0346..d79a487 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -474,7 +474,7 @@ static int max8973_init_dcdc(struct max8973_chip *max,
         return ret;
  }

-#ifdef CONFIG_THERMAL_OF
+#ifdef CONFIG_THERMAL
  static int max8973_thermal_read_temp(void *data, int *temp)
  {
         struct max8973_chip *mchip = data;

**/



Should I send the modified patch here?

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

* Re: Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-03-05 12:25 Mark Brown
@ 2016-03-06  2:35 ` Mark Brown
  2016-03-06  7:47   ` Laxman Dewangan
  0 siblings, 1 reply; 17+ messages in thread
From: Mark Brown @ 2016-03-06  2:35 UTC (permalink / raw)
  To: Laxman Dewangan; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 656 bytes --]

On Sat, Mar 05, 2016 at 09:25:49PM +0900, Mark Brown wrote:
> The patch
> 
>    regulator: max8973: add support for junction thermal warning
> 
> has been applied to the regulator tree at
> 
>    git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 
> 
> All being well this means that it will be integrated into the linux-next
> tree (usually sometime in the next 24 hours) and sent to Linus during
> the next merge window (or sooner if it is a bug fix), however if
> problems are discovered then the patch may be dropped or reverted.  

...and reverted because the 0day bot found similar build failures to the
last time :(

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
@ 2016-03-05 12:25 Mark Brown
  2016-03-06  2:35 ` Mark Brown
  0 siblings, 1 reply; 17+ messages in thread
From: Mark Brown @ 2016-03-05 12:25 UTC (permalink / raw)
  To: Laxman Dewangan, Mark Brown; +Cc: linux-kernel

The patch

   regulator: max8973: add support for junction thermal warning

has been applied to the regulator tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 74c37a230bd0cde829e26ec4c89ab8265eb18ed6 Mon Sep 17 00:00:00 2001
From: Laxman Dewangan <ldewangan@nvidia.com>
Date: Fri, 4 Mar 2016 15:57:54 +0530
Subject: [PATCH] regulator: max8973: add support for junction thermal warning

The driver MAX8973 supports the driver for Maxim PMIC MAX77621.
MAX77621 supports the junction temp warning at 120 degC and
140 degC which is configurable. It generates alert signal when
junction temperature crosses these threshold.

MAX77621 does not support the continuous temp monitoring of
junction temperature. It just report whether junction temperature
crossed the threshold or not.

Add support to
- Configure junction temp warning threshold via DT property
to generate alert when it crosses the threshold.
- Add support to interrupt the host from this device when alert
occurred.
- read the junction temp via thermal framework.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/regulator/max8973-regulator.c       | 132 ++++++++++++++++++++++++++++
 include/linux/regulator/max8973-regulator.h |   5 ++
 2 files changed, 137 insertions(+)

diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 5b75b7c2e3ea..a5e0346b7e01 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -38,6 +38,9 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
+#include <linux/thermal.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 /* Register definitions */
 #define MAX8973_VOUT					0x0
@@ -74,6 +77,7 @@
 #define MAX8973_WDTMR_ENABLE				BIT(6)
 #define MAX8973_DISCH_ENBABLE				BIT(5)
 #define MAX8973_FT_ENABLE				BIT(4)
+#define MAX77621_T_JUNCTION_120				BIT(7)
 
 #define MAX8973_CKKADV_TRIP_MASK			0xC
 #define MAX8973_CKKADV_TRIP_DISABLE			0xC
@@ -93,6 +97,12 @@
 #define MAX8973_VOLATGE_STEP				6250
 #define MAX8973_BUCK_N_VOLTAGE				0x80
 
+#define MAX77621_CHIPID_TJINT_S				BIT(0)
+
+#define MAX77621_NORMAL_OPERATING_TEMP			100000
+#define MAX77621_TJINT_WARNING_TEMP_120			120000
+#define MAX77621_TJINT_WARNING_TEMP_140			140000
+
 enum device_id {
 	MAX8973,
 	MAX77621
@@ -112,6 +122,9 @@ struct max8973_chip {
 	int curr_gpio_val;
 	struct regulator_ops ops;
 	enum device_id id;
+	int junction_temp_warning;
+	int irq;
+	struct thermal_zone_device *tz_device;
 };
 
 /*
@@ -391,6 +404,10 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
 		control1 |= MAX8973_FREQSHIFT_9PER;
 
+	if ((pdata->junction_temp_warning == MAX77621_TJINT_WARNING_TEMP_120) &&
+	     (max->id == MAX77621))
+		control2 |= MAX77621_T_JUNCTION_120;
+
 	if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
 		control2 |= MAX8973_DISCH_ENBABLE;
 
@@ -457,6 +474,104 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	return ret;
 }
 
+#ifdef CONFIG_THERMAL_OF
+static int max8973_thermal_read_temp(void *data, int *temp)
+{
+	struct max8973_chip *mchip = data;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to read register CHIPID1, %d", ret);
+		return ret;
+	}
+
+	/* +1 degC to trigger cool devive */
+	if (val & MAX77621_CHIPID_TJINT_S)
+		*temp = mchip->junction_temp_warning + 1000;
+	else
+		*temp = MAX77621_NORMAL_OPERATING_TEMP;
+
+	return 0;
+}
+
+static irqreturn_t max8973_thermal_irq(int irq, void *data)
+{
+	struct max8973_chip *mchip = data;
+
+	thermal_zone_device_update(mchip->tz_device);
+
+	return IRQ_HANDLED;
+}
+
+static const struct thermal_zone_of_device_ops max77621_tz_ops = {
+	.get_temp = max8973_thermal_read_temp,
+};
+
+static int max8973_thermal_init(struct max8973_chip *mchip)
+{
+	struct thermal_zone_device *tzd;
+	struct irq_data *irq_data;
+	unsigned long irq_flags = 0;
+	int ret;
+
+	if (mchip->id != MAX77621)
+		return 0;
+
+	tzd = thermal_zone_of_sensor_register(mchip->dev, 0, mchip,
+					      &max77621_tz_ops);
+	if (IS_ERR(tzd)) {
+		ret = PTR_ERR(tzd);
+		dev_err(mchip->dev, "Failed to register thermal sensor: %d\n",
+			ret);
+		return ret;
+	}
+
+	if (mchip->irq <= 0)
+		return 0;
+
+	irq_data = irq_get_irq_data(mchip->irq);
+	if (irq_data)
+		irq_flags = irqd_get_trigger_type(irq_data);
+
+	ret = request_threaded_irq(mchip->irq, NULL, max8973_thermal_irq,
+				   IRQF_ONESHOT | IRQF_SHARED | irq_flags,
+				   dev_name(mchip->dev), mchip);
+	if (ret < 0) {
+		dev_err(mchip->dev, "Failed to request irq %d, %d\n",
+			mchip->irq, ret);
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	thermal_zone_of_sensor_unregister(mchip->dev, mchip->tz_device);
+
+	return ret;
+}
+
+
+static void max8973_thermal_deinit(struct max8973_chip *mchip)
+{
+	if ((mchip->id != MAX77621) || !mchip->tz_device)
+		return;
+
+	 if (mchip->irq > 0)
+		free_irq(mchip->irq, mchip);
+
+	thermal_zone_of_sensor_unregister(mchip->dev, mchip->tz_device);
+}
+#else
+static int max8973_thermal_init(struct max8973_chip *mchip)
+{
+	 return 0;
+}
+
+static void max8973_thermal_deinit(struct max8973_chip *mchip) { }
+#endif
+
 static const struct regmap_config max8973_regmap_config = {
 	.reg_bits		= 8,
 	.val_bits		= 8,
@@ -521,6 +636,11 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
 		pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
 	}
 
+	pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140;
+	ret = of_property_read_u32(np, "junction-warn-millicelsius", &pval);
+	if (!ret && (pval <= MAX77621_TJINT_WARNING_TEMP_120))
+		pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120;
+
 	return pdata;
 }
 
@@ -608,6 +728,7 @@ static int max8973_probe(struct i2c_client *client,
 	max->enable_external_control = pdata->enable_ext_control;
 	max->curr_gpio_val = pdata->dvs_def_state;
 	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
+	max->junction_temp_warning = pdata->junction_temp_warning;
 
 	if (gpio_is_valid(max->enable_gpio))
 		max->enable_external_control = true;
@@ -718,6 +839,16 @@ static int max8973_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	max8973_thermal_init(max);
+	return 0;
+}
+
+static int max8973_remove(struct i2c_client *i2c)
+{
+	struct max8973_chip *mchip = i2c_get_clientdata(i2c);
+
+	max8973_thermal_deinit(mchip);
+
 	return 0;
 }
 
@@ -734,6 +865,7 @@ static struct i2c_driver max8973_i2c_driver = {
 		.of_match_table = of_max8973_match_tbl,
 	},
 	.probe = max8973_probe,
+	.remove = max8973_remove,
 	.id_table = max8973_id,
 };
 
diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h
index f6a8a16a0d4d..2fcb9980262a 100644
--- a/include/linux/regulator/max8973-regulator.h
+++ b/include/linux/regulator/max8973-regulator.h
@@ -54,6 +54,10 @@
  * @reg_init_data: The regulator init data.
  * @control_flags: Control flags which are ORed value of above flags to
  *		configure device.
+ * @junction_temp_warning: Junction temp in millicelcius on which warning need
+ *			   to be set. Thermal functionality is only supported on
+ *			   MAX77621. The threshold warning supported by MAX77621
+ *			   are 120C and 140C.
  * @enable_ext_control: Enable the voltage enable/disable through external
  *		control signal from EN input pin. If it is false then
  *		voltage output will be enabled/disabled through EN bit of
@@ -67,6 +71,7 @@
 struct max8973_regulator_platform_data {
 	struct regulator_init_data *reg_init_data;
 	unsigned long control_flags;
+	unsigned long junction_temp_warning;
 	bool enable_ext_control;
 	int enable_gpio;
 	int dvs_gpio;
-- 
2.7.0

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

* Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree
  2016-01-06 16:07 [PATCH V2] regulator: max8973: add support for junction thermal warning Laxman Dewangan
@ 2016-01-06 18:12 ` Mark Brown
  0 siblings, 0 replies; 17+ messages in thread
From: Mark Brown @ 2016-01-06 18:12 UTC (permalink / raw)
  To: Laxman Dewangan, Mark Brown; +Cc: linux-kernel

The patch

   regulator: max8973: add support for junction thermal warning

has been applied to the regulator tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 1b7a4c6a9eeaa2d44186da98270d325a3857b88b Mon Sep 17 00:00:00 2001
From: Laxman Dewangan <ldewangan@nvidia.com>
Date: Wed, 6 Jan 2016 21:37:20 +0530
Subject: [PATCH] regulator: max8973: add support for junction thermal warning

The driver MAX8973 supports the driver for Maxim PMIC MAX77621.
MAX77621 supports the  junction temp warning at 120 degC and
140 degC which is configurable. It generates alert signal when
junction temperature crosses these threshold.

MAX77621 does not support the continuous temp monitoring of
junction temperature. It just report whether junction temperature
crossed the threshold or not.

Add support to
- Configure junction temp warning threshold via DT property
  to generate alert when it crosses the threshold.
- Add support to interrupt the host from this device when alert
  occurred.
- read the junction temp via thermal framework.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 .../bindings/regulator/max8973-regulator.txt       |   5 +
 drivers/regulator/max8973-regulator.c              | 140 ++++++++++++++++++++-
 include/linux/regulator/max8973-regulator.h        |   4 +
 3 files changed, 147 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
index f80ea2fe27e6..93f9939115af 100644
--- a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
@@ -31,6 +31,11 @@ Optional properties:
 		property is available then etr will be enable default.
 
 Enhanced transient response (ETR) will affect the configuration of CKADV.
+-maxim,junction-temp-warning: Junction temp warning on which device generates
+		warning interrupts. This is in millicelcius.
+
+Please note that thermal functionality is only supported on MAX77621. The
+threshold warning supported by MAX77621 are 120 degC and 140 degC.
 
 Example:
 
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 5b75b7c2e3ea..4640d1b85b35 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -38,6 +38,9 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
+#include <linux/thermal.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 /* Register definitions */
 #define MAX8973_VOUT					0x0
@@ -74,6 +77,7 @@
 #define MAX8973_WDTMR_ENABLE				BIT(6)
 #define MAX8973_DISCH_ENBABLE				BIT(5)
 #define MAX8973_FT_ENABLE				BIT(4)
+#define MAX77621_T_JUNCTION_120				BIT(7)
 
 #define MAX8973_CKKADV_TRIP_MASK			0xC
 #define MAX8973_CKKADV_TRIP_DISABLE			0xC
@@ -93,6 +97,13 @@
 #define MAX8973_VOLATGE_STEP				6250
 #define MAX8973_BUCK_N_VOLTAGE				0x80
 
+#define MAX77621_CHIPID_TJINT_S				BIT(0)
+
+#define MAX77621_NORMAL_OPERATING_TEMP			100000
+#define MAX77621_TJINT_WARNING_TEMP_120			120000
+#define MAX77621_TJINT_WARNING_TEMP_140			140000
+
+
 enum device_id {
 	MAX8973,
 	MAX77621
@@ -112,6 +123,9 @@ struct max8973_chip {
 	int curr_gpio_val;
 	struct regulator_ops ops;
 	enum device_id id;
+	int junction_temp_warning;
+	int irq;
+	struct thermal_zone_device *tz_device;
 };
 
 /*
@@ -391,6 +405,10 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
 		control1 |= MAX8973_FREQSHIFT_9PER;
 
+	if ((max->id == MAX77621) && (pdata->junction_temp_warning ==
+					MAX77621_TJINT_WARNING_TEMP_120))
+		control2 |=  MAX77621_T_JUNCTION_120;
+
 	if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
 		control2 |= MAX8973_DISCH_ENBABLE;
 
@@ -457,6 +475,100 @@ static int max8973_init_dcdc(struct max8973_chip *max,
 	return ret;
 }
 
+#ifdef CONFIG_THERMAL_OF
+static int max8973_thermal_read_temp(void *data, int *temp)
+{
+	struct max8973_chip *mchip = data;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
+	if (ret < 0) {
+		dev_err(mchip->dev, "register CHIPID1 read failed, %d", ret);
+		return ret;
+	}
+
+	/* +1 degC to trigger cool devive */
+	if (val & MAX77621_CHIPID_TJINT_S)
+		*temp = mchip->junction_temp_warning + 1000;
+	else
+		*temp = MAX77621_NORMAL_OPERATING_TEMP;
+
+	return 0;
+}
+
+static irqreturn_t max8973_thermal_irq(int irq, void *data)
+{
+	struct max8973_chip *mchip = data;
+
+	dev_info(mchip->dev, "Junction Temp warning occurred\n");
+	thermal_zone_device_update(mchip->tz_device,
+			THERMAL_DEVICE_EVENT_THRESHOLD);
+	return IRQ_HANDLED;
+}
+
+static const struct thermal_zone_of_device_ops max77621_tz_ops = {
+	.get_temp = max8973_thermal_read_temp,
+};
+
+static int max8973_thermal_init(struct max8973_chip *mchip)
+{
+	struct irq_data *irq_data;
+	unsigned long irq_flags = 0;
+	int ret;
+
+	if (mchip->id != MAX77621)
+		return 0;
+
+	mchip->tz_device = thermal_zone_of_sensor_register(mchip->dev, 0,
+					mchip, &max77621_tz_ops);
+	if (IS_ERR(mchip->tz_device)) {
+		ret = PTR_ERR(mchip->tz_device);
+		dev_err(mchip->dev,
+			"Device can not register as thermal sensor: %d\n", ret);
+		mchip->tz_device = NULL;
+		return ret;
+	}
+
+	if (mchip->irq <= 0)
+		return 0;
+
+	irq_data = irq_get_irq_data(mchip->irq);
+	if (irq_data)
+		irq_flags = irqd_get_trigger_type(irq_data);
+	ret = request_threaded_irq(mchip->irq, NULL, max8973_thermal_irq,
+			IRQF_ONESHOT | IRQF_SHARED | irq_flags,
+			dev_name(mchip->dev), mchip);
+	if (ret < 0) {
+		dev_err(mchip->dev, "request irq %d failed: %d\n",
+			mchip->irq, ret);
+		goto fail;
+	}
+	return 0;
+
+fail:
+	thermal_zone_of_sensor_unregister(mchip->dev, mchip->tz_device);
+	return ret;
+}
+
+static void max8973_thermal_deinit(struct max8973_chip *mchip)
+{
+	if ((mchip->id != MAX77621) || !mchip->tz_device)
+		return;
+
+	if (mchip->irq > 0)
+		free_irq(mchip->irq, mchip);
+
+	thermal_zone_of_sensor_unregister(mchip->dev, mchip->tz_device);
+}
+#else
+static int max8973_thermal_init(struct max8973_chip *mchip)
+{
+	return 0;
+}
+static void max8973_thermal_deinit(struct max8973_chip *mchip) { }
+#endif
+
 static const struct regmap_config max8973_regmap_config = {
 	.reg_bits		= 8,
 	.val_bits		= 8,
@@ -465,9 +577,10 @@ static const struct regmap_config max8973_regmap_config = {
 };
 
 static struct max8973_regulator_platform_data *max8973_parse_dt(
-		struct device *dev)
+		struct i2c_client *client)
 {
 	struct max8973_regulator_platform_data *pdata;
+	struct device *dev = &client->dev;
 	struct device_node *np = dev->of_node;
 	int ret;
 	u32 pval;
@@ -521,6 +634,13 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
 		pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
 	}
 
+	ret = of_property_read_u32(np, "maxim,junction-temp-warning", &pval);
+	if (!ret)
+		pdata->junction_temp_warning = pval;
+	pdata->junction_temp_warning = (pdata->junction_temp_warning <
+					MAX77621_TJINT_WARNING_TEMP_120) ?
+					MAX77621_TJINT_WARNING_TEMP_120 :
+					MAX77621_TJINT_WARNING_TEMP_140;
 	return pdata;
 }
 
@@ -546,7 +666,7 @@ static int max8973_probe(struct i2c_client *client,
 	pdata = dev_get_platdata(&client->dev);
 
 	if (!pdata && client->dev.of_node) {
-		pdata = max8973_parse_dt(&client->dev);
+		pdata = max8973_parse_dt(client);
 		pdata_from_dt = true;
 	}
 
@@ -592,6 +712,7 @@ static int max8973_probe(struct i2c_client *client,
 			(chip_id >> 4) & 0xF, (chip_id >> 1) & 0x7);
 
 	i2c_set_clientdata(client, max);
+	max->irq = client->irq;
 	max->ops = max8973_dcdc_ops;
 	max->dev = &client->dev;
 	max->desc.name = id->name;
@@ -608,6 +729,7 @@ static int max8973_probe(struct i2c_client *client,
 	max->enable_external_control = pdata->enable_ext_control;
 	max->curr_gpio_val = pdata->dvs_def_state;
 	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
+	max->junction_temp_warning = pdata->junction_temp_warning;
 
 	if (gpio_is_valid(max->enable_gpio))
 		max->enable_external_control = true;
@@ -718,6 +840,19 @@ static int max8973_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	ret = max8973_thermal_init(max);
+	if (ret < 0)
+		dev_info(max->dev, "Juntion Thermal not initialised, %d\n",
+			ret);
+
+	return 0;
+}
+
+static int max8973_remove(struct i2c_client *i2c)
+{
+	struct max8973_chip *mchip = i2c_get_clientdata(i2c);
+
+	max8973_thermal_deinit(mchip);
 	return 0;
 }
 
@@ -734,6 +869,7 @@ static struct i2c_driver max8973_i2c_driver = {
 		.of_match_table = of_max8973_match_tbl,
 	},
 	.probe = max8973_probe,
+	.remove = max8973_remove,
 	.id_table = max8973_id,
 };
 
diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h
index f6a8a16a0d4d..abde9c4941cf 100644
--- a/include/linux/regulator/max8973-regulator.h
+++ b/include/linux/regulator/max8973-regulator.h
@@ -54,6 +54,9 @@
  * @reg_init_data: The regulator init data.
  * @control_flags: Control flags which are ORed value of above flags to
  *		configure device.
+ * @junction_temp_warning: Junction temp in millicelcius on which warning need
+ *		to be set. Thermal functionality is only supported on MAX77621.
+ *		The threshold warning supported by MAX77621 are 120C and 140C.
  * @enable_ext_control: Enable the voltage enable/disable through external
  *		control signal from EN input pin. If it is false then
  *		voltage output will be enabled/disabled through EN bit of
@@ -67,6 +70,7 @@
 struct max8973_regulator_platform_data {
 	struct regulator_init_data *reg_init_data;
 	unsigned long control_flags;
+	int junction_temp_warning;
 	bool enable_ext_control;
 	int enable_gpio;
 	int dvs_gpio;
-- 
2.7.0.rc3


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

end of thread, other threads:[~2016-04-13 17:12 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-13  9:59 [PATCH V3 1/2] regulator: max8973: add DT binding details for junction warn temp Laxman Dewangan
2016-04-13  9:59 ` Laxman Dewangan
2016-04-13  9:59 ` [PATCH V3 2/2] regulator: max8973: add support for junction thermal warning Laxman Dewangan
2016-04-13  9:59   ` Laxman Dewangan
2016-04-13 16:21   ` Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree Mark Brown
2016-04-13 16:21     ` Mark Brown
2016-04-13 17:01     ` Laxman Dewangan
2016-04-13 17:01       ` Laxman Dewangan
  -- strict thread matches above, loose matches on Subject: below --
2016-03-05 12:25 Mark Brown
2016-03-06  2:35 ` Mark Brown
2016-03-06  7:47   ` Laxman Dewangan
2016-03-06 11:35     ` Mark Brown
2016-03-07  6:36       ` Laxman Dewangan
2016-03-07  7:44         ` Mark Brown
2016-03-07 10:54           ` Laxman Dewangan
2016-03-08  2:22             ` Mark Brown
2016-01-06 16:07 [PATCH V2] regulator: max8973: add support for junction thermal warning Laxman Dewangan
2016-01-06 18:12 ` Applied "regulator: max8973: add support for junction thermal warning" to the regulator tree Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.