소스 검색

hwmon: (ntc_thermistor) Add ntc thermistor to thermal subsystem as a sensor.

To get more comprehensive and integrated thermal management, it adds ntc
thermistor to thermal framework as a thermal sensor. It's governed thermal
susbsystem only if it is described in DT node. Otherwise, it just notifies
temperature to userspace via sysfs as it used to be.

Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Jonghwa Lee 11 년 전
부모
커밋
c08860ffe5
3개의 변경된 파일29개의 추가작업 그리고 0개의 파일을 삭제
  1. 3 0
      Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt
  2. 1 0
      drivers/hwmon/Kconfig
  3. 25 0
      drivers/hwmon/ntc_thermistor.c

+ 3 - 0
Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt

@@ -25,6 +25,9 @@ Requires node properties:
 - "io-channels"	Channel node of ADC to be used for
 - "io-channels"	Channel node of ADC to be used for
 		conversion.
 		conversion.
 
 
+Optional node properties:
+- "#thermal-sensor-cells" Used to expose itself to thermal fw.
+
 Read more about iio bindings at
 Read more about iio bindings at
 	Documentation/devicetree/bindings/iio/iio-bindings.txt
 	Documentation/devicetree/bindings/iio/iio-bindings.txt
 
 

+ 1 - 0
drivers/hwmon/Kconfig

@@ -1077,6 +1077,7 @@ config SENSORS_PC87427
 config SENSORS_NTC_THERMISTOR
 config SENSORS_NTC_THERMISTOR
 	tristate "NTC thermistor support from Murata"
 	tristate "NTC thermistor support from Murata"
 	depends on !OF || IIO=n || IIO
 	depends on !OF || IIO=n || IIO
+	depends on THERMAL || !THERMAL_OF
 	help
 	help
 	  This driver supports NTC thermistors sensor reading and its
 	  This driver supports NTC thermistors sensor reading and its
 	  interpretation. The driver can also monitor the temperature and
 	  interpretation. The driver can also monitor the temperature and

+ 25 - 0
drivers/hwmon/ntc_thermistor.c

@@ -38,6 +38,7 @@
 
 
 #include <linux/hwmon.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/thermal.h>
 
 
 struct ntc_compensation {
 struct ntc_compensation {
 	int		temp_c;
 	int		temp_c;
@@ -182,6 +183,7 @@ struct ntc_data {
 	struct device *dev;
 	struct device *dev;
 	int n_comp;
 	int n_comp;
 	char name[PLATFORM_NAME_SIZE];
 	char name[PLATFORM_NAME_SIZE];
+	struct thermal_zone_device *tz;
 };
 };
 
 
 #if defined(CONFIG_OF) && IS_ENABLED(CONFIG_IIO)
 #if defined(CONFIG_OF) && IS_ENABLED(CONFIG_IIO)
@@ -428,6 +430,20 @@ static int ntc_thermistor_get_ohm(struct ntc_data *data)
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
+static int ntc_read_temp(void *dev, long *temp)
+{
+	struct ntc_data *data = dev_get_drvdata(dev);
+	int ohm;
+
+	ohm = ntc_thermistor_get_ohm(data);
+	if (ohm < 0)
+		return ohm;
+
+	*temp = get_temp_mc(data, ohm);
+
+	return 0;
+}
+
 static ssize_t ntc_show_name(struct device *dev,
 static ssize_t ntc_show_name(struct device *dev,
 		struct device_attribute *attr, char *buf)
 		struct device_attribute *attr, char *buf)
 {
 {
@@ -562,6 +578,13 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
 	dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n",
 	dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n",
 								pdev_id->name);
 								pdev_id->name);
 
 
+	data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev,
+						ntc_read_temp, NULL);
+	if (IS_ERR(data->tz)) {
+		dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n");
+		data->tz = NULL;
+	}
+
 	return 0;
 	return 0;
 err_after_sysfs:
 err_after_sysfs:
 	sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
 	sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
@@ -578,6 +601,8 @@ static int ntc_thermistor_remove(struct platform_device *pdev)
 	sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
 	sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
 	ntc_iio_channel_release(pdata);
 	ntc_iio_channel_release(pdata);
 
 
+	thermal_zone_of_sensor_unregister(data->dev, data->tz);
+
 	return 0;
 	return 0;
 }
 }