All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] hwmon: Driver for TI TMP103 temperature sensor
@ 2014-06-13  7:10 ` Heiko Schocher
  0 siblings, 0 replies; 5+ messages in thread
From: Heiko Schocher @ 2014-06-13  7:10 UTC (permalink / raw
  To: lm-sensors
  Cc: Heiko Schocher, Jean Delvare, Guenter Roeck, linux-kernel,
	devicetree, linux-doc

Driver for the TI TMP103.

The TI TMP103 is similar to the TMP102.  It differs from the TMP102
by having only 8 bit registers.

Signed-off-by: Heiko Schocher <hs@denx.de>

---

Cc: Jean Delvare <khali@linux-fr.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: linux-kernel@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-doc@vger.kernel.org

- change for v2:
  - add comments from GuenterRoeck:
    - remove Cc from commit subject
    - add devicetree mailinglist
    - move Documentation to Documentation/hwmon/tmp103
    - remove devicetree bindings from Documentation
    - add compatible string to
      "Documentation/devicetree/bindings/i2c/trivial-devices.txt"
    - remove CamelCase
    - fix Codingstyle issues
    - use ATTRIBUTE_GROUPS and devm_hwmon_device_register_with_groups()
    - remove unsused define TMP103_CONFIG_RD_ONLY
    - restore config register when exit()
    - use regmap

 .../devicetree/bindings/i2c/trivial-devices.txt    |   1 +
 Documentation/hwmon/tmp103                         |  28 ++
 drivers/hwmon/Kconfig                              |  10 +
 drivers/hwmon/Makefile                             |   1 +
 drivers/hwmon/tmp103.c                             | 304 +++++++++++++++++++++
 5 files changed, 344 insertions(+)
 create mode 100644 Documentation/hwmon/tmp103
 create mode 100644 drivers/hwmon/tmp103.c

diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index bef86e5..fc944e0 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -83,5 +83,6 @@ stm,m41t80		M41T80 - SERIAL ACCESS RTC WITH ALARMS
 taos,tsl2550		Ambient Light Sensor with SMBUS/Two Wire Serial Interface
 ti,tsc2003		I2C Touch-Screen Controller
 ti,tmp102		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
+ti,tmp103		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
 ti,tmp275		Digital Temperature Sensor
 winbond,wpct301		i2c trusted platform module (TPM)
diff --git a/Documentation/hwmon/tmp103 b/Documentation/hwmon/tmp103
new file mode 100644
index 0000000..559fea5
--- /dev/null
+++ b/Documentation/hwmon/tmp103
@@ -0,0 +1,28 @@
+Kernel driver tmp103
+====================
+
+Supported chips:
+  * Texas Instruments TMP103
+    Prefix: 'tmp103'
+    Addresses scanned: none
+    Product info and datasheet: http://www.ti.com/product/tmp103
+
+Author:
+	Heiko Schocher <hs@denx.de>
+
+Description
+-----------
+
+The TMP103 is a digital output temperature sensor in a four-ball
+wafer chip-scale package (WCSP). The TMP103 is capable of reading
+temperatures to a resolution of 1°C. The TMP103 is specified for
+operation over a temperature range of –40°C to +125°C.
+
+Resolution: 8 Bits
+Accuracy: ±1°C Typ (–10°C to +100°C)
+
+The driver provides the common sysfs-interface for temperatures (see
+Documentation/hwmon/sysfs-interface under Temperatures).
+
+please refer how to instantiate this driver:
+Documentation/i2c/instantiating-devices
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 0034316..0f44dbb 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1381,6 +1381,16 @@ config SENSORS_TMP102
 	  This driver can also be built as a module.  If so, the module
 	  will be called tmp102.
 
+config SENSORS_TMP103
+	tristate "Texas Instruments TMP103"
+	depends on I2C
+	help
+	  If you say yes here you get support for Texas Instruments TMP103
+	  sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tmp103.
+
 config SENSORS_TMP401
 	tristate "Texas Instruments TMP401 and compatibles"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 11798ad..8e2f6a2 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -134,6 +134,7 @@ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
 obj-$(CONFIG_SENSORS_AMC6821)	+= amc6821.o
 obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
 obj-$(CONFIG_SENSORS_TMP102)	+= tmp102.o
+obj-$(CONFIG_SENSORS_TMP103)	+= tmp103.o
 obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
 obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
 obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
diff --git a/drivers/hwmon/tmp103.c b/drivers/hwmon/tmp103.c
new file mode 100644
index 0000000..01119a6
--- /dev/null
+++ b/drivers/hwmon/tmp103.c
@@ -0,0 +1,304 @@
+/*
+ * Texas Instruments TMP103 SMBus temperature sensor driver
+ * Copyright (C) 2014 Heiko Schocher <hs@denx.de>
+ *
+ * Based on:
+ * Texas Instruments TMP102 SMBus temperature sensor driver
+ *
+ * Copyright (C) 2010 Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/regmap.h>
+
+#define	DRIVER_NAME "tmp103"
+
+#define	TMP103_TEMP_REG			0x00
+#define	TMP103_CONF_REG			0x01
+#define	TMP103_TLOW_REG			0x02
+#define	TMP103_THIGH_REG		0x03
+
+#define		TMP103_CONF_M0		0x01
+#define		TMP103_CONF_M1		0x02
+#define		TMP103_CONF_LC		0x04
+#define		TMP103_CONF_FL		0x08
+#define		TMP103_CONF_FH		0x10
+#define		TMP103_CONF_CR0		0x20
+#define		TMP103_CONF_CR1		0x40
+#define		TMP103_CONF_ID		0x80
+#define		TMP103_CONF_SD		(TMP103_CONF_M0 | TMP103_CONF_M1)
+
+struct tmp103 {
+	struct i2c_client *client;
+	struct device *hwmon_dev;
+	struct regmap *regmap;
+	struct mutex lock;
+	unsigned int config_orig;
+	unsigned long last_update;
+	int temp[3];
+};
+
+static inline int tmp103_reg_to_mc(s8 val)
+{
+	return val * 1000;
+}
+
+static inline u8 tmp103_mc_to_reg(int val)
+{
+	return DIV_ROUND_CLOSEST(val, 1000);
+}
+
+static const u8 tmp103_reg[] = {
+	TMP103_TEMP_REG,
+	TMP103_TLOW_REG,
+	TMP103_THIGH_REG,
+};
+
+#define TMP103_INVALID	0xffff
+
+static ssize_t tmp103_show_temp(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tmp103 *tmp103 = i2c_get_clientdata(client);
+	unsigned int status;
+	int ret;
+
+	mutex_lock(&tmp103->lock);
+	if (time_after(jiffies, tmp103->last_update + HZ / 3)) {
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(tmp103->temp); ++i) {
+			ret = regmap_read(tmp103->regmap, tmp103_reg[i],
+					  &status);
+			if (ret < 0)
+				tmp103->temp[i] = TMP103_INVALID;
+			else
+				tmp103->temp[i] = tmp103_reg_to_mc(status);
+		}
+		tmp103->last_update = jiffies;
+	}
+	mutex_unlock(&tmp103->lock);
+
+	if (tmp103->temp[sda->index] != TMP103_INVALID)
+		return sprintf(buf, "%d\n", tmp103->temp[sda->index]);
+
+	return sprintf(buf, "invalid\n");
+}
+
+static ssize_t tmp103_set_temp(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tmp103 *tmp103 = i2c_get_clientdata(client);
+	long val;
+	int ret;
+
+	if (kstrtol(buf, 10, &val) < 0)
+		return -EINVAL;
+
+	val = clamp_val(val, -55000, 127000);
+	mutex_lock(&tmp103->lock);
+	tmp103->temp[sda->index] = val;
+	ret = regmap_write(tmp103->regmap, tmp103_reg[sda->index],
+			   tmp103_mc_to_reg(val));
+	mutex_unlock(&tmp103->lock);
+	return ret ? : count;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp103_show_temp, NULL , 0);
+
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, tmp103_show_temp,
+			  tmp103_set_temp, 1);
+
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp103_show_temp,
+			  tmp103_set_temp, 2);
+
+static struct attribute *tmp103_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(tmp103);
+
+static struct regmap_config tmp103_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TMP103_THIGH_REG,
+};
+
+#define TMP103_CONFIG		(TMP103_CONF_CR1 | TMP103_CONF_M1)
+
+static int tmp103_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
+	struct tmp103 *tmp103;
+	int ret;
+	unsigned int status;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev,
+			"adapter doesn't support SMBus byte transactions\n");
+		return -ENODEV;
+	}
+
+	tmp103 = devm_kzalloc(&client->dev, sizeof(*tmp103), GFP_KERNEL);
+	if (!tmp103)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, tmp103);
+	tmp103->client = client;
+
+	tmp103->regmap = devm_regmap_init_i2c(client, &tmp103_regmap_config);
+	if (IS_ERR(tmp103->regmap)) {
+		dev_err(dev, "failed to allocate register map\n");
+		return PTR_ERR(tmp103->regmap);
+	}
+
+	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &status);
+	if (ret < 0)
+		goto fail_init_regmap;
+
+	tmp103->config_orig = status;
+	ret = regmap_write(tmp103->regmap, TMP103_CONF_REG, TMP103_CONFIG);
+	if (ret < 0) {
+		dev_err(&client->dev, "error writing config register\n");
+		goto fail_restore_config;
+	}
+
+	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &status);
+	if (ret < 0) {
+		dev_err(&client->dev, "error reading config register\n");
+		goto fail_restore_config;
+	}
+	if (status != TMP103_CONFIG) {
+		dev_err(&client->dev, "config settings did not stick\n");
+		ret = -ENODEV;
+		goto fail_restore_config;
+	}
+	tmp103->last_update = jiffies - HZ;
+	mutex_init(&tmp103->lock);
+
+	hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
+						      tmp103, tmp103_groups);
+	if (IS_ERR(hwmon_dev)) {
+		dev_dbg(dev, "unable to register hwmon device\n");
+		status = PTR_ERR(hwmon_dev);
+		goto fail_restore_config;
+	}
+	tmp103->hwmon_dev = hwmon_dev;
+
+	return 0;
+
+fail_restore_config:
+	regmap_write(tmp103->regmap, TMP103_CONF_REG, tmp103->config_orig);
+fail_init_regmap:
+	regmap_exit(tmp103->regmap);
+	return ret;
+}
+
+static int tmp103_remove(struct i2c_client *client)
+{
+	struct tmp103 *tmp103 = i2c_get_clientdata(client);
+	int ret;
+
+	ret = regmap_write(tmp103->regmap, TMP103_CONF_REG,
+			   tmp103->config_orig);
+	if (ret < 0)
+		dev_err(&client->dev, "error writing config register\n");
+
+	hwmon_device_unregister(tmp103->hwmon_dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int tmp103_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tmp103 *tmp103 = i2c_get_clientdata(client);
+	unsigned int config;
+	int ret;
+
+	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &config);
+	if (ret < 0)
+		return ret;
+
+	config &= ~TMP103_CONF_SD;
+	return regmap_write(tmp103->regmap, TMP103_CONF_REG, config);
+}
+
+static int tmp103_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tmp103 *tmp103 = i2c_get_clientdata(client);
+	unsigned int config;
+	int ret;
+
+	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &config);
+	if (ret < 0)
+		return ret;
+
+	config |= TMP103_CONF_SD;
+	return regmap_write(tmp103->regmap, TMP103_CONF_REG, config);
+}
+
+static const struct dev_pm_ops tmp103_dev_pm_ops = {
+	.suspend	= tmp103_suspend,
+	.resume		= tmp103_resume,
+};
+
+#define TMP103_DEV_PM_OPS (&tmp103_dev_pm_ops)
+#else
+#define	TMP103_DEV_PM_OPS NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id tmp103_id[] = {
+	{ DRIVER_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tmp103_id);
+
+static struct i2c_driver tmp103_driver = {
+	.driver = {
+		.name	= DRIVER_NAME,
+		.pm	= TMP103_DEV_PM_OPS,
+	},
+	.probe		= tmp103_probe,
+	.remove		= tmp103_remove,
+	.id_table	= tmp103_id,
+};
+
+module_i2c_driver(tmp103_driver);
+
+MODULE_AUTHOR("Heiko Schocher <hs@denx.de>");
+MODULE_DESCRIPTION("Texas Instruments TMP103 temperature sensor driver");
+MODULE_LICENSE("GPL");
-- 
1.8.3.1


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

* [lm-sensors] [PATCH v2] hwmon: Driver for TI TMP103 temperature sensor
@ 2014-06-13  7:10 ` Heiko Schocher
  0 siblings, 0 replies; 5+ messages in thread
From: Heiko Schocher @ 2014-06-13  7:10 UTC (permalink / raw
  To: lm-sensors
  Cc: Heiko Schocher, Jean Delvare, Guenter Roeck, linux-kernel,
	devicetree, linux-doc

RHJpdmVyIGZvciB0aGUgVEkgVE1QMTAzLgoKVGhlIFRJIFRNUDEwMyBpcyBzaW1pbGFyIHRvIHRo
ZSBUTVAxMDIuICBJdCBkaWZmZXJzIGZyb20gdGhlIFRNUDEwMgpieSBoYXZpbmcgb25seSA4IGJp
dCByZWdpc3RlcnMuCgpTaWduZWQtb2ZmLWJ5OiBIZWlrbyBTY2hvY2hlciA8aHNAZGVueC5kZT4K
Ci0tLQoKQ2M6IEplYW4gRGVsdmFyZSA8a2hhbGlAbGludXgtZnIub3JnPgpDYzogR3VlbnRlciBS
b2VjayA8bGludXhAcm9lY2stdXMubmV0PgpDYzogbGludXgta2VybmVsQHZnZXIua2VybmVsLm9y
ZwpDYzogZGV2aWNldHJlZUB2Z2VyLmtlcm5lbC5vcmcKQ2M6IGxpbnV4LWRvY0B2Z2VyLmtlcm5l
bC5vcmcKCi0gY2hhbmdlIGZvciB2MjoKICAtIGFkZCBjb21tZW50cyBmcm9tIEd1ZW50ZXJSb2Vj
azoKICAgIC0gcmVtb3ZlIENjIGZyb20gY29tbWl0IHN1YmplY3QKICAgIC0gYWRkIGRldmljZXRy
ZWUgbWFpbGluZ2xpc3QKICAgIC0gbW92ZSBEb2N1bWVudGF0aW9uIHRvIERvY3VtZW50YXRpb24v
aHdtb24vdG1wMTAzCiAgICAtIHJlbW92ZSBkZXZpY2V0cmVlIGJpbmRpbmdzIGZyb20gRG9jdW1l
bnRhdGlvbgogICAgLSBhZGQgY29tcGF0aWJsZSBzdHJpbmcgdG8KICAgICAgIkRvY3VtZW50YXRp
b24vZGV2aWNldHJlZS9iaW5kaW5ncy9pMmMvdHJpdmlhbC1kZXZpY2VzLnR4dCIKICAgIC0gcmVt
b3ZlIENhbWVsQ2FzZQogICAgLSBmaXggQ29kaW5nc3R5bGUgaXNzdWVzCiAgICAtIHVzZSBBVFRS
SUJVVEVfR1JPVVBTIGFuZCBkZXZtX2h3bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3Vwcygp
CiAgICAtIHJlbW92ZSB1bnN1c2VkIGRlZmluZSBUTVAxMDNfQ09ORklHX1JEX09OTFkKICAgIC0g
cmVzdG9yZSBjb25maWcgcmVnaXN0ZXIgd2hlbiBleGl0KCkKICAgIC0gdXNlIHJlZ21hcAoKIC4u
Li9kZXZpY2V0cmVlL2JpbmRpbmdzL2kyYy90cml2aWFsLWRldmljZXMudHh0ICAgIHwgICAxICsK
IERvY3VtZW50YXRpb24vaHdtb24vdG1wMTAzICAgICAgICAgICAgICAgICAgICAgICAgIHwgIDI4
ICsrCiBkcml2ZXJzL2h3bW9uL0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8
ICAxMCArCiBkcml2ZXJzL2h3bW9uL01ha2VmaWxlICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICB8ICAgMSArCiBkcml2ZXJzL2h3bW9uL3RtcDEwMy5jICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICB8IDMwNCArKysrKysrKysrKysrKysrKysrKysKIDUgZmlsZXMgY2hhbmdlZCwgMzQ0IGlu
c2VydGlvbnMoKykKIGNyZWF0ZSBtb2RlIDEwMDY0NCBEb2N1bWVudGF0aW9uL2h3bW9uL3RtcDEw
MwogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaHdtb24vdG1wMTAzLmMKCmRpZmYgLS1naXQg
YS9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvaTJjL3RyaXZpYWwtZGV2aWNlcy50
eHQgYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvaTJjL3RyaXZpYWwtZGV2aWNl
cy50eHQKaW5kZXggYmVmODZlNS4uZmM5NDRlMCAxMDA2NDQKLS0tIGEvRG9jdW1lbnRhdGlvbi9k
ZXZpY2V0cmVlL2JpbmRpbmdzL2kyYy90cml2aWFsLWRldmljZXMudHh0CisrKyBiL0RvY3VtZW50
YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9pMmMvdHJpdmlhbC1kZXZpY2VzLnR4dApAQCAtODMs
NSArODMsNiBAQCBzdG0sbTQxdDgwCQlNNDFUODAgLSBTRVJJQUwgQUNDRVNTIFJUQyBXSVRIIEFM
QVJNUwogdGFvcyx0c2wyNTUwCQlBbWJpZW50IExpZ2h0IFNlbnNvciB3aXRoIFNNQlVTL1R3byBX
aXJlIFNlcmlhbCBJbnRlcmZhY2UKIHRpLHRzYzIwMDMJCUkyQyBUb3VjaC1TY3JlZW4gQ29udHJv
bGxlcgogdGksdG1wMTAyCQlMb3cgUG93ZXIgRGlnaXRhbCBUZW1wZXJhdHVyZSBTZW5zb3Igd2l0
aCBTTUJVUy9Ud28gV2lyZSBTZXJpYWwgSW50ZXJmYWNlCit0aSx0bXAxMDMJCUxvdyBQb3dlciBE
aWdpdGFsIFRlbXBlcmF0dXJlIFNlbnNvciB3aXRoIFNNQlVTL1R3byBXaXJlIFNlcmlhbCBJbnRl
cmZhY2UKIHRpLHRtcDI3NQkJRGlnaXRhbCBUZW1wZXJhdHVyZSBTZW5zb3IKIHdpbmJvbmQsd3Bj
dDMwMQkJaTJjIHRydXN0ZWQgcGxhdGZvcm0gbW9kdWxlIChUUE0pCmRpZmYgLS1naXQgYS9Eb2N1
bWVudGF0aW9uL2h3bW9uL3RtcDEwMyBiL0RvY3VtZW50YXRpb24vaHdtb24vdG1wMTAzCm5ldyBm
aWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1OWZlYTUKLS0tIC9kZXYvbnVsbAorKysg
Yi9Eb2N1bWVudGF0aW9uL2h3bW9uL3RtcDEwMwpAQCAtMCwwICsxLDI4IEBACitLZXJuZWwgZHJp
dmVyIHRtcDEwMworPT09PT09PT09PT09PT09PT09PT0KKworU3VwcG9ydGVkIGNoaXBzOgorICAq
IFRleGFzIEluc3RydW1lbnRzIFRNUDEwMworICAgIFByZWZpeDogJ3RtcDEwMycKKyAgICBBZGRy
ZXNzZXMgc2Nhbm5lZDogbm9uZQorICAgIFByb2R1Y3QgaW5mbyBhbmQgZGF0YXNoZWV0OiBodHRw
Oi8vd3d3LnRpLmNvbS9wcm9kdWN0L3RtcDEwMworCitBdXRob3I6CisJSGVpa28gU2Nob2NoZXIg
PGhzQGRlbnguZGU+CisKK0Rlc2NyaXB0aW9uCistLS0tLS0tLS0tLQorCitUaGUgVE1QMTAzIGlz
IGEgZGlnaXRhbCBvdXRwdXQgdGVtcGVyYXR1cmUgc2Vuc29yIGluIGEgZm91ci1iYWxsCit3YWZl
ciBjaGlwLXNjYWxlIHBhY2thZ2UgKFdDU1ApLiBUaGUgVE1QMTAzIGlzIGNhcGFibGUgb2YgcmVh
ZGluZwordGVtcGVyYXR1cmVzIHRvIGEgcmVzb2x1dGlvbiBvZiAxwrBDLiBUaGUgVE1QMTAzIGlz
IHNwZWNpZmllZCBmb3IKK29wZXJhdGlvbiBvdmVyIGEgdGVtcGVyYXR1cmUgcmFuZ2Ugb2Yg4oCT
NDDCsEMgdG8gKzEyNcKwQy4KKworUmVzb2x1dGlvbjogOCBCaXRzCitBY2N1cmFjeTogwrExwrBD
IFR5cCAo4oCTMTDCsEMgdG8gKzEwMMKwQykKKworVGhlIGRyaXZlciBwcm92aWRlcyB0aGUgY29t
bW9uIHN5c2ZzLWludGVyZmFjZSBmb3IgdGVtcGVyYXR1cmVzIChzZWUKK0RvY3VtZW50YXRpb24v
aHdtb24vc3lzZnMtaW50ZXJmYWNlIHVuZGVyIFRlbXBlcmF0dXJlcykuCisKK3BsZWFzZSByZWZl
ciBob3cgdG8gaW5zdGFudGlhdGUgdGhpcyBkcml2ZXI6CitEb2N1bWVudGF0aW9uL2kyYy9pbnN0
YW50aWF0aW5nLWRldmljZXMKZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2Ry
aXZlcnMvaHdtb24vS2NvbmZpZwppbmRleCAwMDM0MzE2Li4wZjQ0ZGJiIDEwMDY0NAotLS0gYS9k
cml2ZXJzL2h3bW9uL0tjb25maWcKKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCkBAIC0xMzgx
LDYgKzEzODEsMTYgQEAgY29uZmlnIFNFTlNPUlNfVE1QMTAyCiAJICBUaGlzIGRyaXZlciBjYW4g
YWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gIElmIHNvLCB0aGUgbW9kdWxlCiAJICB3aWxsIGJl
IGNhbGxlZCB0bXAxMDIuCiAKK2NvbmZpZyBTRU5TT1JTX1RNUDEwMworCXRyaXN0YXRlICJUZXhh
cyBJbnN0cnVtZW50cyBUTVAxMDMiCisJZGVwZW5kcyBvbiBJMkMKKwloZWxwCisJICBJZiB5b3Ug
c2F5IHllcyBoZXJlIHlvdSBnZXQgc3VwcG9ydCBmb3IgVGV4YXMgSW5zdHJ1bWVudHMgVE1QMTAz
CisJICBzZW5zb3IgY2hpcHMuCisKKwkgIFRoaXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFz
IGEgbW9kdWxlLiAgSWYgc28sIHRoZSBtb2R1bGUKKwkgIHdpbGwgYmUgY2FsbGVkIHRtcDEwMy4K
KwogY29uZmlnIFNFTlNPUlNfVE1QNDAxCiAJdHJpc3RhdGUgIlRleGFzIEluc3RydW1lbnRzIFRN
UDQwMSBhbmQgY29tcGF0aWJsZXMiCiAJZGVwZW5kcyBvbiBJMkMKZGlmZiAtLWdpdCBhL2RyaXZl
cnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCmluZGV4IDExNzk4YWQu
LjhlMmY2YTIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUKKysrIGIvZHJpdmVy
cy9od21vbi9NYWtlZmlsZQpAQCAtMTM0LDYgKzEzNCw3IEBAIG9iai0kKENPTkZJR19TRU5TT1JT
X1NNU0M0N00xOTIpKz0gc21zYzQ3bTE5Mi5vCiBvYmotJChDT05GSUdfU0VOU09SU19BTUM2ODIx
KQkrPSBhbWM2ODIxLm8KIG9iai0kKENPTkZJR19TRU5TT1JTX1RITUM1MCkJKz0gdGhtYzUwLm8K
IG9iai0kKENPTkZJR19TRU5TT1JTX1RNUDEwMikJKz0gdG1wMTAyLm8KK29iai0kKENPTkZJR19T
RU5TT1JTX1RNUDEwMykJKz0gdG1wMTAzLm8KIG9iai0kKENPTkZJR19TRU5TT1JTX1RNUDQwMSkJ
Kz0gdG1wNDAxLm8KIG9iai0kKENPTkZJR19TRU5TT1JTX1RNUDQyMSkJKz0gdG1wNDIxLm8KIG9i
ai0kKENPTkZJR19TRU5TT1JTX1RXTDQwMzBfTUFEQykrPSB0d2w0MDMwLW1hZGMtaHdtb24ubwpk
aWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi90bXAxMDMuYyBiL2RyaXZlcnMvaHdtb24vdG1wMTAz
LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDExMTlhNgotLS0gL2Rldi9u
dWxsCisrKyBiL2RyaXZlcnMvaHdtb24vdG1wMTAzLmMKQEAgLTAsMCArMSwzMDQgQEAKKy8qCisg
KiBUZXhhcyBJbnN0cnVtZW50cyBUTVAxMDMgU01CdXMgdGVtcGVyYXR1cmUgc2Vuc29yIGRyaXZl
cgorICogQ29weXJpZ2h0IChDKSAyMDE0IEhlaWtvIFNjaG9jaGVyIDxoc0BkZW54LmRlPgorICoK
KyAqIEJhc2VkIG9uOgorICogVGV4YXMgSW5zdHJ1bWVudHMgVE1QMTAyIFNNQnVzIHRlbXBlcmF0
dXJlIHNlbnNvciBkcml2ZXIKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgU3RldmVuIEtpbmcg
PHNma2luZ0BmZHdkYy5jb20+CisgKgorICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7
IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKKyAqIGl0IHVuZGVyIHRoZSB0
ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5Cisg
KiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBM
aWNlbnNlLCBvcgorICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KKyAqCisg
KiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJl
IHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBp
bXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQ
QVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCisgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5z
ZSBmb3IgbW9yZSBkZXRhaWxzLgorICoKKyAqLworCisjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+
CisjaW5jbHVkZSA8bGludXgvaW5pdC5oPgorI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KKyNpbmNs
dWRlIDxsaW51eC9pMmMuaD4KKyNpbmNsdWRlIDxsaW51eC9od21vbi5oPgorI2luY2x1ZGUgPGxp
bnV4L2h3bW9uLXN5c2ZzLmg+CisjaW5jbHVkZSA8bGludXgvZXJyLmg+CisjaW5jbHVkZSA8bGlu
dXgvbXV0ZXguaD4KKyNpbmNsdWRlIDxsaW51eC9kZXZpY2UuaD4KKyNpbmNsdWRlIDxsaW51eC9q
aWZmaWVzLmg+CisjaW5jbHVkZSA8bGludXgvcmVnbWFwLmg+CisKKyNkZWZpbmUJRFJJVkVSX05B
TUUgInRtcDEwMyIKKworI2RlZmluZQlUTVAxMDNfVEVNUF9SRUcJCQkweDAwCisjZGVmaW5lCVRN
UDEwM19DT05GX1JFRwkJCTB4MDEKKyNkZWZpbmUJVE1QMTAzX1RMT1dfUkVHCQkJMHgwMgorI2Rl
ZmluZQlUTVAxMDNfVEhJR0hfUkVHCQkweDAzCisKKyNkZWZpbmUJCVRNUDEwM19DT05GX00wCQkw
eDAxCisjZGVmaW5lCQlUTVAxMDNfQ09ORl9NMQkJMHgwMgorI2RlZmluZQkJVE1QMTAzX0NPTkZf
TEMJCTB4MDQKKyNkZWZpbmUJCVRNUDEwM19DT05GX0ZMCQkweDA4CisjZGVmaW5lCQlUTVAxMDNf
Q09ORl9GSAkJMHgxMAorI2RlZmluZQkJVE1QMTAzX0NPTkZfQ1IwCQkweDIwCisjZGVmaW5lCQlU
TVAxMDNfQ09ORl9DUjEJCTB4NDAKKyNkZWZpbmUJCVRNUDEwM19DT05GX0lECQkweDgwCisjZGVm
aW5lCQlUTVAxMDNfQ09ORl9TRAkJKFRNUDEwM19DT05GX00wIHwgVE1QMTAzX0NPTkZfTTEpCisK
K3N0cnVjdCB0bXAxMDMgeworCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQ7CisJc3RydWN0IGRl
dmljZSAqaHdtb25fZGV2OworCXN0cnVjdCByZWdtYXAgKnJlZ21hcDsKKwlzdHJ1Y3QgbXV0ZXgg
bG9jazsKKwl1bnNpZ25lZCBpbnQgY29uZmlnX29yaWc7CisJdW5zaWduZWQgbG9uZyBsYXN0X3Vw
ZGF0ZTsKKwlpbnQgdGVtcFszXTsKK307CisKK3N0YXRpYyBpbmxpbmUgaW50IHRtcDEwM19yZWdf
dG9fbWMoczggdmFsKQoreworCXJldHVybiB2YWwgKiAxMDAwOworfQorCitzdGF0aWMgaW5saW5l
IHU4IHRtcDEwM19tY190b19yZWcoaW50IHZhbCkKK3sKKwlyZXR1cm4gRElWX1JPVU5EX0NMT1NF
U1QodmFsLCAxMDAwKTsKK30KKworc3RhdGljIGNvbnN0IHU4IHRtcDEwM19yZWdbXSA9IHsKKwlU
TVAxMDNfVEVNUF9SRUcsCisJVE1QMTAzX1RMT1dfUkVHLAorCVRNUDEwM19USElHSF9SRUcsCit9
OworCisjZGVmaW5lIFRNUDEwM19JTlZBTElECTB4ZmZmZgorCitzdGF0aWMgc3NpemVfdCB0bXAx
MDNfc2hvd190ZW1wKHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCQlzdHJ1Y3QgZGV2aWNlX2F0dHJp
YnV0ZSAqYXR0ciwKKwkJCQljaGFyICpidWYpCit7CisJc3RydWN0IHNlbnNvcl9kZXZpY2VfYXR0
cmlidXRlICpzZGEgPSB0b19zZW5zb3JfZGV2X2F0dHIoYXR0cik7CisJc3RydWN0IGkyY19jbGll
bnQgKmNsaWVudCA9IHRvX2kyY19jbGllbnQoZGV2KTsKKwlzdHJ1Y3QgdG1wMTAzICp0bXAxMDMg
PSBpMmNfZ2V0X2NsaWVudGRhdGEoY2xpZW50KTsKKwl1bnNpZ25lZCBpbnQgc3RhdHVzOworCWlu
dCByZXQ7CisKKwltdXRleF9sb2NrKCZ0bXAxMDMtPmxvY2spOworCWlmICh0aW1lX2FmdGVyKGpp
ZmZpZXMsIHRtcDEwMy0+bGFzdF91cGRhdGUgKyBIWiAvIDMpKSB7CisJCWludCBpOworCisJCWZv
ciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKHRtcDEwMy0+dGVtcCk7ICsraSkgeworCQkJcmV0ID0g
cmVnbWFwX3JlYWQodG1wMTAzLT5yZWdtYXAsIHRtcDEwM19yZWdbaV0sCisJCQkJCSAgJnN0YXR1
cyk7CisJCQlpZiAocmV0IDwgMCkKKwkJCQl0bXAxMDMtPnRlbXBbaV0gPSBUTVAxMDNfSU5WQUxJ
RDsKKwkJCWVsc2UKKwkJCQl0bXAxMDMtPnRlbXBbaV0gPSB0bXAxMDNfcmVnX3RvX21jKHN0YXR1
cyk7CisJCX0KKwkJdG1wMTAzLT5sYXN0X3VwZGF0ZSA9IGppZmZpZXM7CisJfQorCW11dGV4X3Vu
bG9jaygmdG1wMTAzLT5sb2NrKTsKKworCWlmICh0bXAxMDMtPnRlbXBbc2RhLT5pbmRleF0gIT0g
VE1QMTAzX0lOVkFMSUQpCisJCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVkXG4iLCB0bXAxMDMtPnRl
bXBbc2RhLT5pbmRleF0pOworCisJcmV0dXJuIHNwcmludGYoYnVmLCAiaW52YWxpZFxuIik7Cit9
CisKK3N0YXRpYyBzc2l6ZV90IHRtcDEwM19zZXRfdGVtcChzdHJ1Y3QgZGV2aWNlICpkZXYsCisJ
CQkgICAgICAgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsCisJCQkgICAgICAgY29uc3Qg
Y2hhciAqYnVmLCBzaXplX3QgY291bnQpCit7CisJc3RydWN0IHNlbnNvcl9kZXZpY2VfYXR0cmli
dXRlICpzZGEgPSB0b19zZW5zb3JfZGV2X2F0dHIoYXR0cik7CisJc3RydWN0IGkyY19jbGllbnQg
KmNsaWVudCA9IHRvX2kyY19jbGllbnQoZGV2KTsKKwlzdHJ1Y3QgdG1wMTAzICp0bXAxMDMgPSBp
MmNfZ2V0X2NsaWVudGRhdGEoY2xpZW50KTsKKwlsb25nIHZhbDsKKwlpbnQgcmV0OworCisJaWYg
KGtzdHJ0b2woYnVmLCAxMCwgJnZhbCkgPCAwKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCXZhbCA9
IGNsYW1wX3ZhbCh2YWwsIC01NTAwMCwgMTI3MDAwKTsKKwltdXRleF9sb2NrKCZ0bXAxMDMtPmxv
Y2spOworCXRtcDEwMy0+dGVtcFtzZGEtPmluZGV4XSA9IHZhbDsKKwlyZXQgPSByZWdtYXBfd3Jp
dGUodG1wMTAzLT5yZWdtYXAsIHRtcDEwM19yZWdbc2RhLT5pbmRleF0sCisJCQkgICB0bXAxMDNf
bWNfdG9fcmVnKHZhbCkpOworCW11dGV4X3VubG9jaygmdG1wMTAzLT5sb2NrKTsKKwlyZXR1cm4g
cmV0ID8gOiBjb3VudDsKK30KKworc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUih0ZW1wMV9pbnB1
dCwgU19JUlVHTywgdG1wMTAzX3Nob3dfdGVtcCwgTlVMTCAsIDApOworCitzdGF0aWMgU0VOU09S
X0RFVklDRV9BVFRSKHRlbXAxX21pbiwgU19JV1VTUiB8IFNfSVJVR08sIHRtcDEwM19zaG93X3Rl
bXAsCisJCQkgIHRtcDEwM19zZXRfdGVtcCwgMSk7CisKK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FU
VFIodGVtcDFfbWF4LCBTX0lXVVNSIHwgU19JUlVHTywgdG1wMTAzX3Nob3dfdGVtcCwKKwkJCSAg
dG1wMTAzX3NldF90ZW1wLCAyKTsKKworc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGUgKnRtcDEwM19h
dHRyc1tdID0geworCSZzZW5zb3JfZGV2X2F0dHJfdGVtcDFfaW5wdXQuZGV2X2F0dHIuYXR0ciwK
Kwkmc2Vuc29yX2Rldl9hdHRyX3RlbXAxX21pbi5kZXZfYXR0ci5hdHRyLAorCSZzZW5zb3JfZGV2
X2F0dHJfdGVtcDFfbWF4LmRldl9hdHRyLmF0dHIsCisJTlVMTAorfTsKK0FUVFJJQlVURV9HUk9V
UFModG1wMTAzKTsKKworc3RhdGljIHN0cnVjdCByZWdtYXBfY29uZmlnIHRtcDEwM19yZWdtYXBf
Y29uZmlnID0geworCS5yZWdfYml0cyA9IDgsCisJLnZhbF9iaXRzID0gOCwKKwkubWF4X3JlZ2lz
dGVyID0gVE1QMTAzX1RISUdIX1JFRywKK307CisKKyNkZWZpbmUgVE1QMTAzX0NPTkZJRwkJKFRN
UDEwM19DT05GX0NSMSB8IFRNUDEwM19DT05GX00xKQorCitzdGF0aWMgaW50IHRtcDEwM19wcm9i
ZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LAorCQkJY29uc3Qgc3RydWN0IGkyY19kZXZpY2Vf
aWQgKmlkKQoreworCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZjbGllbnQtPmRldjsKKwlzdHJ1Y3Qg
ZGV2aWNlICpod21vbl9kZXY7CisJc3RydWN0IHRtcDEwMyAqdG1wMTAzOworCWludCByZXQ7CisJ
dW5zaWduZWQgaW50IHN0YXR1czsKKworCWlmICghaTJjX2NoZWNrX2Z1bmN0aW9uYWxpdHkoY2xp
ZW50LT5hZGFwdGVyLAorCQkJCSAgICAgSTJDX0ZVTkNfU01CVVNfQllURV9EQVRBKSkgeworCQlk
ZXZfZXJyKCZjbGllbnQtPmRldiwKKwkJCSJhZGFwdGVyIGRvZXNuJ3Qgc3VwcG9ydCBTTUJ1cyBi
eXRlIHRyYW5zYWN0aW9uc1xuIik7CisJCXJldHVybiAtRU5PREVWOworCX0KKworCXRtcDEwMyA9
IGRldm1fa3phbGxvYygmY2xpZW50LT5kZXYsIHNpemVvZigqdG1wMTAzKSwgR0ZQX0tFUk5FTCk7
CisJaWYgKCF0bXAxMDMpCisJCXJldHVybiAtRU5PTUVNOworCisJaTJjX3NldF9jbGllbnRkYXRh
KGNsaWVudCwgdG1wMTAzKTsKKwl0bXAxMDMtPmNsaWVudCA9IGNsaWVudDsKKworCXRtcDEwMy0+
cmVnbWFwID0gZGV2bV9yZWdtYXBfaW5pdF9pMmMoY2xpZW50LCAmdG1wMTAzX3JlZ21hcF9jb25m
aWcpOworCWlmIChJU19FUlIodG1wMTAzLT5yZWdtYXApKSB7CisJCWRldl9lcnIoZGV2LCAiZmFp
bGVkIHRvIGFsbG9jYXRlIHJlZ2lzdGVyIG1hcFxuIik7CisJCXJldHVybiBQVFJfRVJSKHRtcDEw
My0+cmVnbWFwKTsKKwl9CisKKwlyZXQgPSByZWdtYXBfcmVhZCh0bXAxMDMtPnJlZ21hcCwgVE1Q
MTAzX0NPTkZfUkVHLCAmc3RhdHVzKTsKKwlpZiAocmV0IDwgMCkKKwkJZ290byBmYWlsX2luaXRf
cmVnbWFwOworCisJdG1wMTAzLT5jb25maWdfb3JpZyA9IHN0YXR1czsKKwlyZXQgPSByZWdtYXBf
d3JpdGUodG1wMTAzLT5yZWdtYXAsIFRNUDEwM19DT05GX1JFRywgVE1QMTAzX0NPTkZJRyk7CisJ
aWYgKHJldCA8IDApIHsKKwkJZGV2X2VycigmY2xpZW50LT5kZXYsICJlcnJvciB3cml0aW5nIGNv
bmZpZyByZWdpc3RlclxuIik7CisJCWdvdG8gZmFpbF9yZXN0b3JlX2NvbmZpZzsKKwl9CisKKwly
ZXQgPSByZWdtYXBfcmVhZCh0bXAxMDMtPnJlZ21hcCwgVE1QMTAzX0NPTkZfUkVHLCAmc3RhdHVz
KTsKKwlpZiAocmV0IDwgMCkgeworCQlkZXZfZXJyKCZjbGllbnQtPmRldiwgImVycm9yIHJlYWRp
bmcgY29uZmlnIHJlZ2lzdGVyXG4iKTsKKwkJZ290byBmYWlsX3Jlc3RvcmVfY29uZmlnOworCX0K
KwlpZiAoc3RhdHVzICE9IFRNUDEwM19DT05GSUcpIHsKKwkJZGV2X2VycigmY2xpZW50LT5kZXYs
ICJjb25maWcgc2V0dGluZ3MgZGlkIG5vdCBzdGlja1xuIik7CisJCXJldCA9IC1FTk9ERVY7CisJ
CWdvdG8gZmFpbF9yZXN0b3JlX2NvbmZpZzsKKwl9CisJdG1wMTAzLT5sYXN0X3VwZGF0ZSA9IGpp
ZmZpZXMgLSBIWjsKKwltdXRleF9pbml0KCZ0bXAxMDMtPmxvY2spOworCisJaHdtb25fZGV2ID0g
aHdtb25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhfZ3JvdXBzKGRldiwgY2xpZW50LT5uYW1lLAorCQkJ
CQkJICAgICAgdG1wMTAzLCB0bXAxMDNfZ3JvdXBzKTsKKwlpZiAoSVNfRVJSKGh3bW9uX2Rldikp
IHsKKwkJZGV2X2RiZyhkZXYsICJ1bmFibGUgdG8gcmVnaXN0ZXIgaHdtb24gZGV2aWNlXG4iKTsK
KwkJc3RhdHVzID0gUFRSX0VSUihod21vbl9kZXYpOworCQlnb3RvIGZhaWxfcmVzdG9yZV9jb25m
aWc7CisJfQorCXRtcDEwMy0+aHdtb25fZGV2ID0gaHdtb25fZGV2OworCisJcmV0dXJuIDA7CisK
K2ZhaWxfcmVzdG9yZV9jb25maWc6CisJcmVnbWFwX3dyaXRlKHRtcDEwMy0+cmVnbWFwLCBUTVAx
MDNfQ09ORl9SRUcsIHRtcDEwMy0+Y29uZmlnX29yaWcpOworZmFpbF9pbml0X3JlZ21hcDoKKwly
ZWdtYXBfZXhpdCh0bXAxMDMtPnJlZ21hcCk7CisJcmV0dXJuIHJldDsKK30KKworc3RhdGljIGlu
dCB0bXAxMDNfcmVtb3ZlKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCit7CisJc3RydWN0IHRt
cDEwMyAqdG1wMTAzID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7CisJaW50IHJldDsKKwor
CXJldCA9IHJlZ21hcF93cml0ZSh0bXAxMDMtPnJlZ21hcCwgVE1QMTAzX0NPTkZfUkVHLAorCQkJ
ICAgdG1wMTAzLT5jb25maWdfb3JpZyk7CisJaWYgKHJldCA8IDApCisJCWRldl9lcnIoJmNsaWVu
dC0+ZGV2LCAiZXJyb3Igd3JpdGluZyBjb25maWcgcmVnaXN0ZXJcbiIpOworCisJaHdtb25fZGV2
aWNlX3VucmVnaXN0ZXIodG1wMTAzLT5od21vbl9kZXYpOworCisJcmV0dXJuIDA7Cit9CisKKyNp
ZmRlZiBDT05GSUdfUE0KK3N0YXRpYyBpbnQgdG1wMTAzX3N1c3BlbmQoc3RydWN0IGRldmljZSAq
ZGV2KQoreworCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQgPSB0b19pMmNfY2xpZW50KGRldik7
CisJc3RydWN0IHRtcDEwMyAqdG1wMTAzID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7CisJ
dW5zaWduZWQgaW50IGNvbmZpZzsKKwlpbnQgcmV0OworCisJcmV0ID0gcmVnbWFwX3JlYWQodG1w
MTAzLT5yZWdtYXAsIFRNUDEwM19DT05GX1JFRywgJmNvbmZpZyk7CisJaWYgKHJldCA8IDApCisJ
CXJldHVybiByZXQ7CisKKwljb25maWcgJj0gflRNUDEwM19DT05GX1NEOworCXJldHVybiByZWdt
YXBfd3JpdGUodG1wMTAzLT5yZWdtYXAsIFRNUDEwM19DT05GX1JFRywgY29uZmlnKTsKK30KKwor
c3RhdGljIGludCB0bXAxMDNfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3Qg
aTJjX2NsaWVudCAqY2xpZW50ID0gdG9faTJjX2NsaWVudChkZXYpOworCXN0cnVjdCB0bXAxMDMg
KnRtcDEwMyA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGllbnQpOworCXVuc2lnbmVkIGludCBjb25m
aWc7CisJaW50IHJldDsKKworCXJldCA9IHJlZ21hcF9yZWFkKHRtcDEwMy0+cmVnbWFwLCBUTVAx
MDNfQ09ORl9SRUcsICZjb25maWcpOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gcmV0OworCisJ
Y29uZmlnIHw9IFRNUDEwM19DT05GX1NEOworCXJldHVybiByZWdtYXBfd3JpdGUodG1wMTAzLT5y
ZWdtYXAsIFRNUDEwM19DT05GX1JFRywgY29uZmlnKTsKK30KKworc3RhdGljIGNvbnN0IHN0cnVj
dCBkZXZfcG1fb3BzIHRtcDEwM19kZXZfcG1fb3BzID0geworCS5zdXNwZW5kCT0gdG1wMTAzX3N1
c3BlbmQsCisJLnJlc3VtZQkJPSB0bXAxMDNfcmVzdW1lLAorfTsKKworI2RlZmluZSBUTVAxMDNf
REVWX1BNX09QUyAoJnRtcDEwM19kZXZfcG1fb3BzKQorI2Vsc2UKKyNkZWZpbmUJVE1QMTAzX0RF
Vl9QTV9PUFMgTlVMTAorI2VuZGlmIC8qIENPTkZJR19QTSAqLworCitzdGF0aWMgY29uc3Qgc3Ry
dWN0IGkyY19kZXZpY2VfaWQgdG1wMTAzX2lkW10gPSB7CisJeyBEUklWRVJfTkFNRSwgMCB9LAor
CXsgfQorfTsKK01PRFVMRV9ERVZJQ0VfVEFCTEUoaTJjLCB0bXAxMDNfaWQpOworCitzdGF0aWMg
c3RydWN0IGkyY19kcml2ZXIgdG1wMTAzX2RyaXZlciA9IHsKKwkuZHJpdmVyID0geworCQkubmFt
ZQk9IERSSVZFUl9OQU1FLAorCQkucG0JPSBUTVAxMDNfREVWX1BNX09QUywKKwl9LAorCS5wcm9i
ZQkJPSB0bXAxMDNfcHJvYmUsCisJLnJlbW92ZQkJPSB0bXAxMDNfcmVtb3ZlLAorCS5pZF90YWJs
ZQk9IHRtcDEwM19pZCwKK307CisKK21vZHVsZV9pMmNfZHJpdmVyKHRtcDEwM19kcml2ZXIpOwor
CitNT0RVTEVfQVVUSE9SKCJIZWlrbyBTY2hvY2hlciA8aHNAZGVueC5kZT4iKTsKK01PRFVMRV9E
RVNDUklQVElPTigiVGV4YXMgSW5zdHJ1bWVudHMgVE1QMTAzIHRlbXBlcmF0dXJlIHNlbnNvciBk
cml2ZXIiKTsKK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsKLS0gCjEuOC4zLjEKCgpfX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcg
bGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMub3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9y
Zy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNvcnM

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

* Re: [PATCH v2] hwmon: Driver for TI TMP103 temperature sensor
@ 2014-06-13 16:03   ` Guenter Roeck
  0 siblings, 0 replies; 5+ messages in thread
From: Guenter Roeck @ 2014-06-13 16:03 UTC (permalink / raw
  To: Heiko Schocher, lm-sensors
  Cc: Jean Delvare, linux-kernel, devicetree, linux-doc

On 06/13/2014 12:10 AM, Heiko Schocher wrote:
> Driver for the TI TMP103.
>
> The TI TMP103 is similar to the TMP102.  It differs from the TMP102
> by having only 8 bit registers.
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
>
Hello Heiko,

Couple of additional comments.

Thanks,
Guenter

> ---
>
> Cc: Jean Delvare <khali@linux-fr.org>
> Cc: Guenter Roeck <linux@roeck-us.net>
> Cc: linux-kernel@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> Cc: linux-doc@vger.kernel.org
>
> - change for v2:
>    - add comments from GuenterRoeck:
>      - remove Cc from commit subject
>      - add devicetree mailinglist
>      - move Documentation to Documentation/hwmon/tmp103
>      - remove devicetree bindings from Documentation
>      - add compatible string to
>        "Documentation/devicetree/bindings/i2c/trivial-devices.txt"
>      - remove CamelCase
>      - fix Codingstyle issues
>      - use ATTRIBUTE_GROUPS and devm_hwmon_device_register_with_groups()
>      - remove unsused define TMP103_CONFIG_RD_ONLY
>      - restore config register when exit()
>      - use regmap
>
>   .../devicetree/bindings/i2c/trivial-devices.txt    |   1 +
>   Documentation/hwmon/tmp103                         |  28 ++
>   drivers/hwmon/Kconfig                              |  10 +
>   drivers/hwmon/Makefile                             |   1 +
>   drivers/hwmon/tmp103.c                             | 304 +++++++++++++++++++++
>   5 files changed, 344 insertions(+)
>   create mode 100644 Documentation/hwmon/tmp103
>   create mode 100644 drivers/hwmon/tmp103.c
>
> diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> index bef86e5..fc944e0 100644
> --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> @@ -83,5 +83,6 @@ stm,m41t80		M41T80 - SERIAL ACCESS RTC WITH ALARMS
>   taos,tsl2550		Ambient Light Sensor with SMBUS/Two Wire Serial Interface
>   ti,tsc2003		I2C Touch-Screen Controller
>   ti,tmp102		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
> +ti,tmp103		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
>   ti,tmp275		Digital Temperature Sensor
>   winbond,wpct301		i2c trusted platform module (TPM)
> diff --git a/Documentation/hwmon/tmp103 b/Documentation/hwmon/tmp103
> new file mode 100644
> index 0000000..559fea5
> --- /dev/null
> +++ b/Documentation/hwmon/tmp103
> @@ -0,0 +1,28 @@
> +Kernel driver tmp103
> +====================
> +
> +Supported chips:
> +  * Texas Instruments TMP103
> +    Prefix: 'tmp103'
> +    Addresses scanned: none
> +    Product info and datasheet: http://www.ti.com/product/tmp103
> +
> +Author:
> +	Heiko Schocher <hs@denx.de>
> +
> +Description
> +-----------
> +
> +The TMP103 is a digital output temperature sensor in a four-ball
> +wafer chip-scale package (WCSP). The TMP103 is capable of reading
> +temperatures to a resolution of 1°C. The TMP103 is specified for
> +operation over a temperature range of –40°C to +125°C.
> +
> +Resolution: 8 Bits
> +Accuracy: ±1°C Typ (–10°C to +100°C)
> +
> +The driver provides the common sysfs-interface for temperatures (see
> +Documentation/hwmon/sysfs-interface under Temperatures).
> +
> +please refer how to instantiate this driver:

s/please/Please/

> +Documentation/i2c/instantiating-devices
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 0034316..0f44dbb 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -1381,6 +1381,16 @@ config SENSORS_TMP102
>   	  This driver can also be built as a module.  If so, the module
>   	  will be called tmp102.
>
> +config SENSORS_TMP103
> +	tristate "Texas Instruments TMP103"
> +	depends on I2C
> +	help
> +	  If you say yes here you get support for Texas Instruments TMP103
> +	  sensor chips.
> +
> +	  This driver can also be built as a module.  If so, the module
> +	  will be called tmp103.
> +
>   config SENSORS_TMP401
>   	tristate "Texas Instruments TMP401 and compatibles"
>   	depends on I2C
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 11798ad..8e2f6a2 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -134,6 +134,7 @@ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
>   obj-$(CONFIG_SENSORS_AMC6821)	+= amc6821.o
>   obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
>   obj-$(CONFIG_SENSORS_TMP102)	+= tmp102.o
> +obj-$(CONFIG_SENSORS_TMP103)	+= tmp103.o
>   obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
>   obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
>   obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
> diff --git a/drivers/hwmon/tmp103.c b/drivers/hwmon/tmp103.c
> new file mode 100644
> index 0000000..01119a6
> --- /dev/null
> +++ b/drivers/hwmon/tmp103.c
> @@ -0,0 +1,304 @@
> +/*
> + * Texas Instruments TMP103 SMBus temperature sensor driver
> + * Copyright (C) 2014 Heiko Schocher <hs@denx.de>
> + *
> + * Based on:
> + * Texas Instruments TMP102 SMBus temperature sensor driver
> + *
> + * Copyright (C) 2010 Steven King <sfking@fdwdc.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * 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/module.h>
> +#include <linux/init.h>
> +#include <linux/slab.h>
> +#include <linux/i2c.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +#include <linux/device.h>
> +#include <linux/jiffies.h>
> +#include <linux/regmap.h>
> +
> +#define	DRIVER_NAME "tmp103"
> +
> +#define	TMP103_TEMP_REG			0x00
> +#define	TMP103_CONF_REG			0x01
> +#define	TMP103_TLOW_REG			0x02
> +#define	TMP103_THIGH_REG		0x03
> +
> +#define		TMP103_CONF_M0		0x01
> +#define		TMP103_CONF_M1		0x02
> +#define		TMP103_CONF_LC		0x04
> +#define		TMP103_CONF_FL		0x08
> +#define		TMP103_CONF_FH		0x10
> +#define		TMP103_CONF_CR0		0x20
> +#define		TMP103_CONF_CR1		0x40
> +#define		TMP103_CONF_ID		0x80
> +#define		TMP103_CONF_SD		(TMP103_CONF_M0 | TMP103_CONF_M1)
> +
No tab between #define and the actual definition, please.

> +struct tmp103 {
> +	struct i2c_client *client;

No longer needed. See below.

> +	struct device *hwmon_dev;
> +	struct regmap *regmap;
> +	struct mutex lock;
> +	unsigned int config_orig;
> +	unsigned long last_update;
> +	int temp[3];

Both no longer needed.

Actually, the entire structure is not really needed anymore with the changes suggested
below. The only value still needed would be regmap, and you could store that directly
in drvdata.

> +};
> +
> +static inline int tmp103_reg_to_mc(s8 val)
> +{
> +	return val * 1000;
> +}
> +
> +static inline u8 tmp103_mc_to_reg(int val)
> +{
> +	return DIV_ROUND_CLOSEST(val, 1000);
> +}
> +
> +static const u8 tmp103_reg[] = {
> +	TMP103_TEMP_REG,
> +	TMP103_TLOW_REG,
> +	TMP103_THIGH_REG,
> +};

No longer needed; you can put the register directly into sda->index.

> +
> +#define TMP103_INVALID	0xffff
> +
> +static ssize_t tmp103_show_temp(struct device *dev,
> +				struct device_attribute *attr,
> +				char *buf)
> +{
> +	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);

Too complicated. Attributes are now attached to the hwmon device, and tmp103
can be retrieved from there.

	struct tmp103 *tmp103 = dev_get_drvdata(dev);
or, with all the changes I suggested, even simpler
	struct regmap *regmap = dev_get_drvdata(dev);

> +	unsigned int status;
> +	int ret;
> +
> +	mutex_lock(&tmp103->lock);
> +	if (time_after(jiffies, tmp103->last_update + HZ / 3)) {
> +		int i;
> +
> +		for (i = 0; i < ARRAY_SIZE(tmp103->temp); ++i) {
> +			ret = regmap_read(tmp103->regmap, tmp103_reg[i],
> +					  &status);
> +			if (ret < 0)
> +				tmp103->temp[i] = TMP103_INVALID;

Good idea, but not really what we'd want to see. In this case the error
should be reported to use space, ie return the value of 'ret', not "invalid".
Also, you don't need to read all registers here, and just forget about
local caching (not worth it).

Suggested replacement below.

> +			else
> +				tmp103->temp[i] = tmp103_reg_to_mc(status);
> +		}
> +		tmp103->last_update = jiffies;
> +	}
> +	mutex_unlock(&tmp103->lock);
> +
> +	if (tmp103->temp[sda->index] != TMP103_INVALID)
> +		return sprintf(buf, "%d\n", tmp103->temp[sda->index]);
> +
> +	return sprintf(buf, "invalid\n");
> +}

static ssize_t tmp103_show_temp(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
	struct tmp103 *tmp103 = dev_get_drvdata(dev);	/* or struct regmap *regmap = dev_get_drvdata(dev); */
	unsigned int regval;
	int ret;

	ret = regmap_read(tmp103->regmap, sda->index, &regval);
	if (ret < 0)
		return ret;

	return return sprintf(buf, "%d\n", tmp103_reg_to_mc(regval));
}


> +
> +static ssize_t tmp103_set_temp(struct device *dev,
> +			       struct device_attribute *attr,
> +			       const char *buf, size_t count)
> +{
> +	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);

Same as above.
	struct tmp103 *tmp103 = dev_get_drvdata(dev);


> +	long val;
> +	int ret;
> +
> +	if (kstrtol(buf, 10, &val) < 0)
> +		return -EINVAL;
> +
> +	val = clamp_val(val, -55000, 127000);
> +	mutex_lock(&tmp103->lock);
> +	tmp103->temp[sda->index] = val;
> +	ret = regmap_write(tmp103->regmap, tmp103_reg[sda->index],
> +			   tmp103_mc_to_reg(val));

After dropping tmp103->temp[] you don't need the lock anymore,
which means it can go away completely.

> +	mutex_unlock(&tmp103->lock);
> +	return ret ? : count;
> +}
> +
> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp103_show_temp, NULL , 0);
> +
As suggested above, instead of using an indirect index, use TMP103_TEMP_REG directly
to simplify the code.

> +static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, tmp103_show_temp,
> +			  tmp103_set_temp, 1);
> +
> +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp103_show_temp,
> +			  tmp103_set_temp, 2);
> +
> +static struct attribute *tmp103_attrs[] = {
> +	&sensor_dev_attr_temp1_input.dev_attr.attr,
> +	&sensor_dev_attr_temp1_min.dev_attr.attr,
> +	&sensor_dev_attr_temp1_max.dev_attr.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(tmp103);
> +
> +static struct regmap_config tmp103_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = TMP103_THIGH_REG,

You can also add a 'volatile' function to tell regmap which registers are volatile.

	.volatile_reg = tmp103_is_volatile,

with

static bool tmp103_regmap_is_volatile(struct device *dev, unsigned int reg)
{
	return reg == TMP103_TEMP_REG;
}

With this, only the temperature register will be read after the first initialization.
If you add alarm attributes, you'd have to add the configuration register, but not
for now.

> +};
> +
> +#define TMP103_CONFIG		(TMP103_CONF_CR1 | TMP103_CONF_M1)
> +
Can you move this to the other definitions ? TMP103_CONF_SD is already there,
so this would be more consistent.

> +static int tmp103_probe(struct i2c_client *client,
> +			const struct i2c_device_id *id)
> +{
> +	struct device *dev = &client->dev;
> +	struct device *hwmon_dev;
> +	struct tmp103 *tmp103;
> +	int ret;
> +	unsigned int status;
> +
> +	if (!i2c_check_functionality(client->adapter,
> +				     I2C_FUNC_SMBUS_BYTE_DATA)) {
> +		dev_err(&client->dev,
> +			"adapter doesn't support SMBus byte transactions\n");
> +		return -ENODEV;
> +	}
> +
> +	tmp103 = devm_kzalloc(&client->dev, sizeof(*tmp103), GFP_KERNEL);
> +	if (!tmp103)
> +		return -ENOMEM;
> +
> +	i2c_set_clientdata(client, tmp103);
> +	tmp103->client = client;

Both no longer needed.

> +
> +	tmp103->regmap = devm_regmap_init_i2c(client, &tmp103_regmap_config);
> +	if (IS_ERR(tmp103->regmap)) {
> +		dev_err(dev, "failed to allocate register map\n");
> +		return PTR_ERR(tmp103->regmap);
> +	}
> +
> +	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &status);
> +	if (ret < 0)
> +		goto fail_init_regmap;
> +
> +	tmp103->config_orig = status;
> +	ret = regmap_write(tmp103->regmap, TMP103_CONF_REG, TMP103_CONFIG);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "error writing config register\n");
> +		goto fail_restore_config;
> +	}
> +
> +	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &status);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "error reading config register\n");
> +		goto fail_restore_config;
> +	}
> +	if (status != TMP103_CONFIG) {
> +		dev_err(&client->dev, "config settings did not stick\n");
> +		ret = -ENODEV;
> +		goto fail_restore_config;
> +	}

The above write/read sequence can be made conditional.
If (config_orig & 0x67) == TMP103_CONFIG, there is no need to update the
configuration register.

Also, I just realized that the current code won't work: The FH and FL bits
are not controlled by you, but by the chip. So the verification (as written)
will fail if you have an alarm condition. I would suggest to drop the
verification entirely; I don't think it adds much if any value.
At the very least, you'll have to mask the result against 0x67.

Actually, I would suggest to drop config_orig entirely. Then you can
use regmap_update_bits() to set the configuration. Also, you can then use
devm_hwmon_device_register_with_groups(), and drop the remove function
as well.

> +	tmp103->last_update = jiffies - HZ;

No longer needed.

> +	mutex_init(&tmp103->lock);
> +
> +	hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
> +						      tmp103, tmp103_groups);
> +	if (IS_ERR(hwmon_dev)) {
> +		dev_dbg(dev, "unable to register hwmon device\n");


> +		status = PTR_ERR(hwmon_dev);
> +		goto fail_restore_config;
> +	}
> +	tmp103->hwmon_dev = hwmon_dev;
> +
> +	return 0;
> +
> +fail_restore_config:
> +	regmap_write(tmp103->regmap, TMP103_CONF_REG, tmp103->config_orig);
> +fail_init_regmap:
> +	regmap_exit(tmp103->regmap);

This is not needed since you used the devm_ initialization function above.
In fact, it is likely wrong.

If you drop restoring the configuration register, the entire sequence can become

	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
						           tmp103, tmp103_groups);
	return PTR_ERR_OR_ZERO(hwmon_dev);

> +	return ret;
> +}
> +
> +static int tmp103_remove(struct i2c_client *client)
> +{
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);
> +	int ret;
> +
> +	ret = regmap_write(tmp103->regmap, TMP103_CONF_REG,
> +			   tmp103->config_orig);

Only needed if (config_orig & 0x67) != TMP103_CONFIG.

> +	if (ret < 0)
> +		dev_err(&client->dev, "error writing config register\n");
> +
I'd suggest to drop the error message. It does not really matter,
after all, and is quite unlikely.

> +	hwmon_device_unregister(tmp103->hwmon_dev);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int tmp103_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);
> +	unsigned int config;
> +	int ret;
> +
> +	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &config);
> +	if (ret < 0)
> +		return ret;
> +
> +	config &= ~TMP103_CONF_SD;
> +	return regmap_write(tmp103->regmap, TMP103_CONF_REG, config);

You can use regmap_update_bits() here.

> +}
> +
> +static int tmp103_resume(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);
> +	unsigned int config;
> +	int ret;
> +
> +	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &config);
> +	if (ret < 0)
> +		return ret;
> +
> +	config |= TMP103_CONF_SD;
> +	return regmap_write(tmp103->regmap, TMP103_CONF_REG, config);

You can use regmap_update_bits() here.

> +}
> +
> +static const struct dev_pm_ops tmp103_dev_pm_ops = {
> +	.suspend	= tmp103_suspend,
> +	.resume		= tmp103_resume,
> +};
> +
> +#define TMP103_DEV_PM_OPS (&tmp103_dev_pm_ops)
> +#else
> +#define	TMP103_DEV_PM_OPS NULL
> +#endif /* CONFIG_PM */
> +
> +static const struct i2c_device_id tmp103_id[] = {
> +	{ DRIVER_NAME, 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, tmp103_id);
> +
> +static struct i2c_driver tmp103_driver = {
> +	.driver = {
> +		.name	= DRIVER_NAME,
> +		.pm	= TMP103_DEV_PM_OPS,
> +	},
> +	.probe		= tmp103_probe,
> +	.remove		= tmp103_remove,
> +	.id_table	= tmp103_id,
> +};
> +
> +module_i2c_driver(tmp103_driver);
> +
> +MODULE_AUTHOR("Heiko Schocher <hs@denx.de>");
> +MODULE_DESCRIPTION("Texas Instruments TMP103 temperature sensor driver");
> +MODULE_LICENSE("GPL");
>


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

* Re: [PATCH v2] hwmon: Driver for TI TMP103 temperature sensor
@ 2014-06-13 16:03   ` Guenter Roeck
  0 siblings, 0 replies; 5+ messages in thread
From: Guenter Roeck @ 2014-06-13 16:03 UTC (permalink / raw
  To: Heiko Schocher, lm-sensors-GZX6beZjE8VD60Wz+7aTrA
  Cc: Jean Delvare, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA

On 06/13/2014 12:10 AM, Heiko Schocher wrote:
> Driver for the TI TMP103.
>
> The TI TMP103 is similar to the TMP102.  It differs from the TMP102
> by having only 8 bit registers.
>
> Signed-off-by: Heiko Schocher <hs-ynQEQJNshbs@public.gmane.org>
>
Hello Heiko,

Couple of additional comments.

Thanks,
Guenter

> ---
>
> Cc: Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
> Cc: Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
> Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>
> - change for v2:
>    - add comments from GuenterRoeck:
>      - remove Cc from commit subject
>      - add devicetree mailinglist
>      - move Documentation to Documentation/hwmon/tmp103
>      - remove devicetree bindings from Documentation
>      - add compatible string to
>        "Documentation/devicetree/bindings/i2c/trivial-devices.txt"
>      - remove CamelCase
>      - fix Codingstyle issues
>      - use ATTRIBUTE_GROUPS and devm_hwmon_device_register_with_groups()
>      - remove unsused define TMP103_CONFIG_RD_ONLY
>      - restore config register when exit()
>      - use regmap
>
>   .../devicetree/bindings/i2c/trivial-devices.txt    |   1 +
>   Documentation/hwmon/tmp103                         |  28 ++
>   drivers/hwmon/Kconfig                              |  10 +
>   drivers/hwmon/Makefile                             |   1 +
>   drivers/hwmon/tmp103.c                             | 304 +++++++++++++++++++++
>   5 files changed, 344 insertions(+)
>   create mode 100644 Documentation/hwmon/tmp103
>   create mode 100644 drivers/hwmon/tmp103.c
>
> diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> index bef86e5..fc944e0 100644
> --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> @@ -83,5 +83,6 @@ stm,m41t80		M41T80 - SERIAL ACCESS RTC WITH ALARMS
>   taos,tsl2550		Ambient Light Sensor with SMBUS/Two Wire Serial Interface
>   ti,tsc2003		I2C Touch-Screen Controller
>   ti,tmp102		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
> +ti,tmp103		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
>   ti,tmp275		Digital Temperature Sensor
>   winbond,wpct301		i2c trusted platform module (TPM)
> diff --git a/Documentation/hwmon/tmp103 b/Documentation/hwmon/tmp103
> new file mode 100644
> index 0000000..559fea5
> --- /dev/null
> +++ b/Documentation/hwmon/tmp103
> @@ -0,0 +1,28 @@
> +Kernel driver tmp103
> +====================
> +
> +Supported chips:
> +  * Texas Instruments TMP103
> +    Prefix: 'tmp103'
> +    Addresses scanned: none
> +    Product info and datasheet: http://www.ti.com/product/tmp103
> +
> +Author:
> +	Heiko Schocher <hs-ynQEQJNshbs@public.gmane.org>
> +
> +Description
> +-----------
> +
> +The TMP103 is a digital output temperature sensor in a four-ball
> +wafer chip-scale package (WCSP). The TMP103 is capable of reading
> +temperatures to a resolution of 1°C. The TMP103 is specified for
> +operation over a temperature range of –40°C to +125°C.
> +
> +Resolution: 8 Bits
> +Accuracy: ±1°C Typ (–10°C to +100°C)
> +
> +The driver provides the common sysfs-interface for temperatures (see
> +Documentation/hwmon/sysfs-interface under Temperatures).
> +
> +please refer how to instantiate this driver:

s/please/Please/

> +Documentation/i2c/instantiating-devices
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 0034316..0f44dbb 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -1381,6 +1381,16 @@ config SENSORS_TMP102
>   	  This driver can also be built as a module.  If so, the module
>   	  will be called tmp102.
>
> +config SENSORS_TMP103
> +	tristate "Texas Instruments TMP103"
> +	depends on I2C
> +	help
> +	  If you say yes here you get support for Texas Instruments TMP103
> +	  sensor chips.
> +
> +	  This driver can also be built as a module.  If so, the module
> +	  will be called tmp103.
> +
>   config SENSORS_TMP401
>   	tristate "Texas Instruments TMP401 and compatibles"
>   	depends on I2C
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 11798ad..8e2f6a2 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -134,6 +134,7 @@ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
>   obj-$(CONFIG_SENSORS_AMC6821)	+= amc6821.o
>   obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
>   obj-$(CONFIG_SENSORS_TMP102)	+= tmp102.o
> +obj-$(CONFIG_SENSORS_TMP103)	+= tmp103.o
>   obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
>   obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
>   obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
> diff --git a/drivers/hwmon/tmp103.c b/drivers/hwmon/tmp103.c
> new file mode 100644
> index 0000000..01119a6
> --- /dev/null
> +++ b/drivers/hwmon/tmp103.c
> @@ -0,0 +1,304 @@
> +/*
> + * Texas Instruments TMP103 SMBus temperature sensor driver
> + * Copyright (C) 2014 Heiko Schocher <hs-ynQEQJNshbs@public.gmane.org>
> + *
> + * Based on:
> + * Texas Instruments TMP102 SMBus temperature sensor driver
> + *
> + * Copyright (C) 2010 Steven King <sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * 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/module.h>
> +#include <linux/init.h>
> +#include <linux/slab.h>
> +#include <linux/i2c.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +#include <linux/device.h>
> +#include <linux/jiffies.h>
> +#include <linux/regmap.h>
> +
> +#define	DRIVER_NAME "tmp103"
> +
> +#define	TMP103_TEMP_REG			0x00
> +#define	TMP103_CONF_REG			0x01
> +#define	TMP103_TLOW_REG			0x02
> +#define	TMP103_THIGH_REG		0x03
> +
> +#define		TMP103_CONF_M0		0x01
> +#define		TMP103_CONF_M1		0x02
> +#define		TMP103_CONF_LC		0x04
> +#define		TMP103_CONF_FL		0x08
> +#define		TMP103_CONF_FH		0x10
> +#define		TMP103_CONF_CR0		0x20
> +#define		TMP103_CONF_CR1		0x40
> +#define		TMP103_CONF_ID		0x80
> +#define		TMP103_CONF_SD		(TMP103_CONF_M0 | TMP103_CONF_M1)
> +
No tab between #define and the actual definition, please.

> +struct tmp103 {
> +	struct i2c_client *client;

No longer needed. See below.

> +	struct device *hwmon_dev;
> +	struct regmap *regmap;
> +	struct mutex lock;
> +	unsigned int config_orig;
> +	unsigned long last_update;
> +	int temp[3];

Both no longer needed.

Actually, the entire structure is not really needed anymore with the changes suggested
below. The only value still needed would be regmap, and you could store that directly
in drvdata.

> +};
> +
> +static inline int tmp103_reg_to_mc(s8 val)
> +{
> +	return val * 1000;
> +}
> +
> +static inline u8 tmp103_mc_to_reg(int val)
> +{
> +	return DIV_ROUND_CLOSEST(val, 1000);
> +}
> +
> +static const u8 tmp103_reg[] = {
> +	TMP103_TEMP_REG,
> +	TMP103_TLOW_REG,
> +	TMP103_THIGH_REG,
> +};

No longer needed; you can put the register directly into sda->index.

> +
> +#define TMP103_INVALID	0xffff
> +
> +static ssize_t tmp103_show_temp(struct device *dev,
> +				struct device_attribute *attr,
> +				char *buf)
> +{
> +	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);

Too complicated. Attributes are now attached to the hwmon device, and tmp103
can be retrieved from there.

	struct tmp103 *tmp103 = dev_get_drvdata(dev);
or, with all the changes I suggested, even simpler
	struct regmap *regmap = dev_get_drvdata(dev);

> +	unsigned int status;
> +	int ret;
> +
> +	mutex_lock(&tmp103->lock);
> +	if (time_after(jiffies, tmp103->last_update + HZ / 3)) {
> +		int i;
> +
> +		for (i = 0; i < ARRAY_SIZE(tmp103->temp); ++i) {
> +			ret = regmap_read(tmp103->regmap, tmp103_reg[i],
> +					  &status);
> +			if (ret < 0)
> +				tmp103->temp[i] = TMP103_INVALID;

Good idea, but not really what we'd want to see. In this case the error
should be reported to use space, ie return the value of 'ret', not "invalid".
Also, you don't need to read all registers here, and just forget about
local caching (not worth it).

Suggested replacement below.

> +			else
> +				tmp103->temp[i] = tmp103_reg_to_mc(status);
> +		}
> +		tmp103->last_update = jiffies;
> +	}
> +	mutex_unlock(&tmp103->lock);
> +
> +	if (tmp103->temp[sda->index] != TMP103_INVALID)
> +		return sprintf(buf, "%d\n", tmp103->temp[sda->index]);
> +
> +	return sprintf(buf, "invalid\n");
> +}

static ssize_t tmp103_show_temp(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
	struct tmp103 *tmp103 = dev_get_drvdata(dev);	/* or struct regmap *regmap = dev_get_drvdata(dev); */
	unsigned int regval;
	int ret;

	ret = regmap_read(tmp103->regmap, sda->index, &regval);
	if (ret < 0)
		return ret;

	return return sprintf(buf, "%d\n", tmp103_reg_to_mc(regval));
}


> +
> +static ssize_t tmp103_set_temp(struct device *dev,
> +			       struct device_attribute *attr,
> +			       const char *buf, size_t count)
> +{
> +	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);

Same as above.
	struct tmp103 *tmp103 = dev_get_drvdata(dev);


> +	long val;
> +	int ret;
> +
> +	if (kstrtol(buf, 10, &val) < 0)
> +		return -EINVAL;
> +
> +	val = clamp_val(val, -55000, 127000);
> +	mutex_lock(&tmp103->lock);
> +	tmp103->temp[sda->index] = val;
> +	ret = regmap_write(tmp103->regmap, tmp103_reg[sda->index],
> +			   tmp103_mc_to_reg(val));

After dropping tmp103->temp[] you don't need the lock anymore,
which means it can go away completely.

> +	mutex_unlock(&tmp103->lock);
> +	return ret ? : count;
> +}
> +
> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp103_show_temp, NULL , 0);
> +
As suggested above, instead of using an indirect index, use TMP103_TEMP_REG directly
to simplify the code.

> +static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, tmp103_show_temp,
> +			  tmp103_set_temp, 1);
> +
> +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp103_show_temp,
> +			  tmp103_set_temp, 2);
> +
> +static struct attribute *tmp103_attrs[] = {
> +	&sensor_dev_attr_temp1_input.dev_attr.attr,
> +	&sensor_dev_attr_temp1_min.dev_attr.attr,
> +	&sensor_dev_attr_temp1_max.dev_attr.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(tmp103);
> +
> +static struct regmap_config tmp103_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = TMP103_THIGH_REG,

You can also add a 'volatile' function to tell regmap which registers are volatile.

	.volatile_reg = tmp103_is_volatile,

with

static bool tmp103_regmap_is_volatile(struct device *dev, unsigned int reg)
{
	return reg == TMP103_TEMP_REG;
}

With this, only the temperature register will be read after the first initialization.
If you add alarm attributes, you'd have to add the configuration register, but not
for now.

> +};
> +
> +#define TMP103_CONFIG		(TMP103_CONF_CR1 | TMP103_CONF_M1)
> +
Can you move this to the other definitions ? TMP103_CONF_SD is already there,
so this would be more consistent.

> +static int tmp103_probe(struct i2c_client *client,
> +			const struct i2c_device_id *id)
> +{
> +	struct device *dev = &client->dev;
> +	struct device *hwmon_dev;
> +	struct tmp103 *tmp103;
> +	int ret;
> +	unsigned int status;
> +
> +	if (!i2c_check_functionality(client->adapter,
> +				     I2C_FUNC_SMBUS_BYTE_DATA)) {
> +		dev_err(&client->dev,
> +			"adapter doesn't support SMBus byte transactions\n");
> +		return -ENODEV;
> +	}
> +
> +	tmp103 = devm_kzalloc(&client->dev, sizeof(*tmp103), GFP_KERNEL);
> +	if (!tmp103)
> +		return -ENOMEM;
> +
> +	i2c_set_clientdata(client, tmp103);
> +	tmp103->client = client;

Both no longer needed.

> +
> +	tmp103->regmap = devm_regmap_init_i2c(client, &tmp103_regmap_config);
> +	if (IS_ERR(tmp103->regmap)) {
> +		dev_err(dev, "failed to allocate register map\n");
> +		return PTR_ERR(tmp103->regmap);
> +	}
> +
> +	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &status);
> +	if (ret < 0)
> +		goto fail_init_regmap;
> +
> +	tmp103->config_orig = status;
> +	ret = regmap_write(tmp103->regmap, TMP103_CONF_REG, TMP103_CONFIG);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "error writing config register\n");
> +		goto fail_restore_config;
> +	}
> +
> +	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &status);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "error reading config register\n");
> +		goto fail_restore_config;
> +	}
> +	if (status != TMP103_CONFIG) {
> +		dev_err(&client->dev, "config settings did not stick\n");
> +		ret = -ENODEV;
> +		goto fail_restore_config;
> +	}

The above write/read sequence can be made conditional.
If (config_orig & 0x67) == TMP103_CONFIG, there is no need to update the
configuration register.

Also, I just realized that the current code won't work: The FH and FL bits
are not controlled by you, but by the chip. So the verification (as written)
will fail if you have an alarm condition. I would suggest to drop the
verification entirely; I don't think it adds much if any value.
At the very least, you'll have to mask the result against 0x67.

Actually, I would suggest to drop config_orig entirely. Then you can
use regmap_update_bits() to set the configuration. Also, you can then use
devm_hwmon_device_register_with_groups(), and drop the remove function
as well.

> +	tmp103->last_update = jiffies - HZ;

No longer needed.

> +	mutex_init(&tmp103->lock);
> +
> +	hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
> +						      tmp103, tmp103_groups);
> +	if (IS_ERR(hwmon_dev)) {
> +		dev_dbg(dev, "unable to register hwmon device\n");


> +		status = PTR_ERR(hwmon_dev);
> +		goto fail_restore_config;
> +	}
> +	tmp103->hwmon_dev = hwmon_dev;
> +
> +	return 0;
> +
> +fail_restore_config:
> +	regmap_write(tmp103->regmap, TMP103_CONF_REG, tmp103->config_orig);
> +fail_init_regmap:
> +	regmap_exit(tmp103->regmap);

This is not needed since you used the devm_ initialization function above.
In fact, it is likely wrong.

If you drop restoring the configuration register, the entire sequence can become

	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
						           tmp103, tmp103_groups);
	return PTR_ERR_OR_ZERO(hwmon_dev);

> +	return ret;
> +}
> +
> +static int tmp103_remove(struct i2c_client *client)
> +{
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);
> +	int ret;
> +
> +	ret = regmap_write(tmp103->regmap, TMP103_CONF_REG,
> +			   tmp103->config_orig);

Only needed if (config_orig & 0x67) != TMP103_CONFIG.

> +	if (ret < 0)
> +		dev_err(&client->dev, "error writing config register\n");
> +
I'd suggest to drop the error message. It does not really matter,
after all, and is quite unlikely.

> +	hwmon_device_unregister(tmp103->hwmon_dev);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int tmp103_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);
> +	unsigned int config;
> +	int ret;
> +
> +	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &config);
> +	if (ret < 0)
> +		return ret;
> +
> +	config &= ~TMP103_CONF_SD;
> +	return regmap_write(tmp103->regmap, TMP103_CONF_REG, config);

You can use regmap_update_bits() here.

> +}
> +
> +static int tmp103_resume(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp103 *tmp103 = i2c_get_clientdata(client);
> +	unsigned int config;
> +	int ret;
> +
> +	ret = regmap_read(tmp103->regmap, TMP103_CONF_REG, &config);
> +	if (ret < 0)
> +		return ret;
> +
> +	config |= TMP103_CONF_SD;
> +	return regmap_write(tmp103->regmap, TMP103_CONF_REG, config);

You can use regmap_update_bits() here.

> +}
> +
> +static const struct dev_pm_ops tmp103_dev_pm_ops = {
> +	.suspend	= tmp103_suspend,
> +	.resume		= tmp103_resume,
> +};
> +
> +#define TMP103_DEV_PM_OPS (&tmp103_dev_pm_ops)
> +#else
> +#define	TMP103_DEV_PM_OPS NULL
> +#endif /* CONFIG_PM */
> +
> +static const struct i2c_device_id tmp103_id[] = {
> +	{ DRIVER_NAME, 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, tmp103_id);
> +
> +static struct i2c_driver tmp103_driver = {
> +	.driver = {
> +		.name	= DRIVER_NAME,
> +		.pm	= TMP103_DEV_PM_OPS,
> +	},
> +	.probe		= tmp103_probe,
> +	.remove		= tmp103_remove,
> +	.id_table	= tmp103_id,
> +};
> +
> +module_i2c_driver(tmp103_driver);
> +
> +MODULE_AUTHOR("Heiko Schocher <hs-ynQEQJNshbs@public.gmane.org>");
> +MODULE_DESCRIPTION("Texas Instruments TMP103 temperature sensor driver");
> +MODULE_LICENSE("GPL");
>

--
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	[flat|nested] 5+ messages in thread

* Re: [lm-sensors] [PATCH v2] hwmon: Driver for TI TMP103 temperature sensor
@ 2014-06-13 16:03   ` Guenter Roeck
  0 siblings, 0 replies; 5+ messages in thread
From: Guenter Roeck @ 2014-06-13 16:03 UTC (permalink / raw
  To: Heiko Schocher, lm-sensors
  Cc: Jean Delvare, linux-kernel, devicetree, linux-doc

T24gMDYvMTMvMjAxNCAxMjoxMCBBTSwgSGVpa28gU2Nob2NoZXIgd3JvdGU6Cj4gRHJpdmVyIGZv
ciB0aGUgVEkgVE1QMTAzLgo+Cj4gVGhlIFRJIFRNUDEwMyBpcyBzaW1pbGFyIHRvIHRoZSBUTVAx
MDIuICBJdCBkaWZmZXJzIGZyb20gdGhlIFRNUDEwMgo+IGJ5IGhhdmluZyBvbmx5IDggYml0IHJl
Z2lzdGVycy4KPgo+IFNpZ25lZC1vZmYtYnk6IEhlaWtvIFNjaG9jaGVyIDxoc0BkZW54LmRlPgo+
CkhlbGxvIEhlaWtvLAoKQ291cGxlIG9mIGFkZGl0aW9uYWwgY29tbWVudHMuCgpUaGFua3MsCkd1
ZW50ZXIKCj4gLS0tCj4KPiBDYzogSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+Cj4g
Q2M6IEd1ZW50ZXIgUm9lY2sgPGxpbnV4QHJvZWNrLXVzLm5ldD4KPiBDYzogbGludXgta2VybmVs
QHZnZXIua2VybmVsLm9yZwo+IENjOiBkZXZpY2V0cmVlQHZnZXIua2VybmVsLm9yZwo+IENjOiBs
aW51eC1kb2NAdmdlci5rZXJuZWwub3JnCj4KPiAtIGNoYW5nZSBmb3IgdjI6Cj4gICAgLSBhZGQg
Y29tbWVudHMgZnJvbSBHdWVudGVyUm9lY2s6Cj4gICAgICAtIHJlbW92ZSBDYyBmcm9tIGNvbW1p
dCBzdWJqZWN0Cj4gICAgICAtIGFkZCBkZXZpY2V0cmVlIG1haWxpbmdsaXN0Cj4gICAgICAtIG1v
dmUgRG9jdW1lbnRhdGlvbiB0byBEb2N1bWVudGF0aW9uL2h3bW9uL3RtcDEwMwo+ICAgICAgLSBy
ZW1vdmUgZGV2aWNldHJlZSBiaW5kaW5ncyBmcm9tIERvY3VtZW50YXRpb24KPiAgICAgIC0gYWRk
IGNvbXBhdGlibGUgc3RyaW5nIHRvCj4gICAgICAgICJEb2N1bWVudGF0aW9uL2RldmljZXRyZWUv
YmluZGluZ3MvaTJjL3RyaXZpYWwtZGV2aWNlcy50eHQiCj4gICAgICAtIHJlbW92ZSBDYW1lbENh
c2UKPiAgICAgIC0gZml4IENvZGluZ3N0eWxlIGlzc3Vlcwo+ICAgICAgLSB1c2UgQVRUUklCVVRF
X0dST1VQUyBhbmQgZGV2bV9od21vbl9kZXZpY2VfcmVnaXN0ZXJfd2l0aF9ncm91cHMoKQo+ICAg
ICAgLSByZW1vdmUgdW5zdXNlZCBkZWZpbmUgVE1QMTAzX0NPTkZJR19SRF9PTkxZCj4gICAgICAt
IHJlc3RvcmUgY29uZmlnIHJlZ2lzdGVyIHdoZW4gZXhpdCgpCj4gICAgICAtIHVzZSByZWdtYXAK
Pgo+ICAgLi4uL2RldmljZXRyZWUvYmluZGluZ3MvaTJjL3RyaXZpYWwtZGV2aWNlcy50eHQgICAg
fCAgIDEgKwo+ICAgRG9jdW1lbnRhdGlvbi9od21vbi90bXAxMDMgICAgICAgICAgICAgICAgICAg
ICAgICAgfCAgMjggKysKPiAgIGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgIHwgIDEwICsKPiAgIGRyaXZlcnMvaHdtb24vTWFrZWZpbGUgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIHwgICAxICsKPiAgIGRyaXZlcnMvaHdtb24vdG1wMTAzLmMgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgIHwgMzA0ICsrKysrKysrKysrKysrKysrKysrKwo+ICAg
NSBmaWxlcyBjaGFuZ2VkLCAzNDQgaW5zZXJ0aW9ucygrKQo+ICAgY3JlYXRlIG1vZGUgMTAwNjQ0
IERvY3VtZW50YXRpb24vaHdtb24vdG1wMTAzCj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy
cy9od21vbi90bXAxMDMuYwo+Cj4gZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vZGV2aWNldHJl
ZS9iaW5kaW5ncy9pMmMvdHJpdmlhbC1kZXZpY2VzLnR4dCBiL0RvY3VtZW50YXRpb24vZGV2aWNl
dHJlZS9iaW5kaW5ncy9pMmMvdHJpdmlhbC1kZXZpY2VzLnR4dAo+IGluZGV4IGJlZjg2ZTUuLmZj
OTQ0ZTAgMTAwNjQ0Cj4gLS0tIGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2ky
Yy90cml2aWFsLWRldmljZXMudHh0Cj4gKysrIGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2Jp
bmRpbmdzL2kyYy90cml2aWFsLWRldmljZXMudHh0Cj4gQEAgLTgzLDUgKzgzLDYgQEAgc3RtLG00
MXQ4MAkJTTQxVDgwIC0gU0VSSUFMIEFDQ0VTUyBSVEMgV0lUSCBBTEFSTVMKPiAgIHRhb3MsdHNs
MjU1MAkJQW1iaWVudCBMaWdodCBTZW5zb3Igd2l0aCBTTUJVUy9Ud28gV2lyZSBTZXJpYWwgSW50
ZXJmYWNlCj4gICB0aSx0c2MyMDAzCQlJMkMgVG91Y2gtU2NyZWVuIENvbnRyb2xsZXIKPiAgIHRp
LHRtcDEwMgkJTG93IFBvd2VyIERpZ2l0YWwgVGVtcGVyYXR1cmUgU2Vuc29yIHdpdGggU01CVVMv
VHdvIFdpcmUgU2VyaWFsIEludGVyZmFjZQo+ICt0aSx0bXAxMDMJCUxvdyBQb3dlciBEaWdpdGFs
IFRlbXBlcmF0dXJlIFNlbnNvciB3aXRoIFNNQlVTL1R3byBXaXJlIFNlcmlhbCBJbnRlcmZhY2UK
PiAgIHRpLHRtcDI3NQkJRGlnaXRhbCBUZW1wZXJhdHVyZSBTZW5zb3IKPiAgIHdpbmJvbmQsd3Bj
dDMwMQkJaTJjIHRydXN0ZWQgcGxhdGZvcm0gbW9kdWxlIChUUE0pCj4gZGlmZiAtLWdpdCBhL0Rv
Y3VtZW50YXRpb24vaHdtb24vdG1wMTAzIGIvRG9jdW1lbnRhdGlvbi9od21vbi90bXAxMDMKPiBu
ZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjU1OWZlYTUKPiAtLS0gL2Rldi9u
dWxsCj4gKysrIGIvRG9jdW1lbnRhdGlvbi9od21vbi90bXAxMDMKPiBAQCAtMCwwICsxLDI4IEBA
Cj4gK0tlcm5lbCBkcml2ZXIgdG1wMTAzCj4gKz09PT09PT09PT09PT09PT09PT09Cj4gKwo+ICtT
dXBwb3J0ZWQgY2hpcHM6Cj4gKyAgKiBUZXhhcyBJbnN0cnVtZW50cyBUTVAxMDMKPiArICAgIFBy
ZWZpeDogJ3RtcDEwMycKPiArICAgIEFkZHJlc3NlcyBzY2FubmVkOiBub25lCj4gKyAgICBQcm9k
dWN0IGluZm8gYW5kIGRhdGFzaGVldDogaHR0cDovL3d3dy50aS5jb20vcHJvZHVjdC90bXAxMDMK
PiArCj4gK0F1dGhvcjoKPiArCUhlaWtvIFNjaG9jaGVyIDxoc0BkZW54LmRlPgo+ICsKPiArRGVz
Y3JpcHRpb24KPiArLS0tLS0tLS0tLS0KPiArCj4gK1RoZSBUTVAxMDMgaXMgYSBkaWdpdGFsIG91
dHB1dCB0ZW1wZXJhdHVyZSBzZW5zb3IgaW4gYSBmb3VyLWJhbGwKPiArd2FmZXIgY2hpcC1zY2Fs
ZSBwYWNrYWdlIChXQ1NQKS4gVGhlIFRNUDEwMyBpcyBjYXBhYmxlIG9mIHJlYWRpbmcKPiArdGVt
cGVyYXR1cmVzIHRvIGEgcmVzb2x1dGlvbiBvZiAxwrBDLiBUaGUgVE1QMTAzIGlzIHNwZWNpZmll
ZCBmb3IKPiArb3BlcmF0aW9uIG92ZXIgYSB0ZW1wZXJhdHVyZSByYW5nZSBvZiDigJM0MMKwQyB0
byArMTI1wrBDLgo+ICsKPiArUmVzb2x1dGlvbjogOCBCaXRzCj4gK0FjY3VyYWN5OiDCsTHCsEMg
VHlwICjigJMxMMKwQyB0byArMTAwwrBDKQo+ICsKPiArVGhlIGRyaXZlciBwcm92aWRlcyB0aGUg
Y29tbW9uIHN5c2ZzLWludGVyZmFjZSBmb3IgdGVtcGVyYXR1cmVzIChzZWUKPiArRG9jdW1lbnRh
dGlvbi9od21vbi9zeXNmcy1pbnRlcmZhY2UgdW5kZXIgVGVtcGVyYXR1cmVzKS4KPiArCj4gK3Bs
ZWFzZSByZWZlciBob3cgdG8gaW5zdGFudGlhdGUgdGhpcyBkcml2ZXI6CgpzL3BsZWFzZS9QbGVh
c2UvCgo+ICtEb2N1bWVudGF0aW9uL2kyYy9pbnN0YW50aWF0aW5nLWRldmljZXMKPiBkaWZmIC0t
Z2l0IGEvZHJpdmVycy9od21vbi9LY29uZmlnIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4gaW5k
ZXggMDAzNDMxNi4uMGY0NGRiYiAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2h3bW9uL0tjb25maWcK
PiArKysgYi9kcml2ZXJzL2h3bW9uL0tjb25maWcKPiBAQCAtMTM4MSw2ICsxMzgxLDE2IEBAIGNv
bmZpZyBTRU5TT1JTX1RNUDEwMgo+ICAgCSAgVGhpcyBkcml2ZXIgY2FuIGFsc28gYmUgYnVpbHQg
YXMgYSBtb2R1bGUuICBJZiBzbywgdGhlIG1vZHVsZQo+ICAgCSAgd2lsbCBiZSBjYWxsZWQgdG1w
MTAyLgo+Cj4gK2NvbmZpZyBTRU5TT1JTX1RNUDEwMwo+ICsJdHJpc3RhdGUgIlRleGFzIEluc3Ry
dW1lbnRzIFRNUDEwMyIKPiArCWRlcGVuZHMgb24gSTJDCj4gKwloZWxwCj4gKwkgIElmIHlvdSBz
YXkgeWVzIGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciBUZXhhcyBJbnN0cnVtZW50cyBUTVAxMDMK
PiArCSAgc2Vuc29yIGNoaXBzLgo+ICsKPiArCSAgVGhpcyBkcml2ZXIgY2FuIGFsc28gYmUgYnVp
bHQgYXMgYSBtb2R1bGUuICBJZiBzbywgdGhlIG1vZHVsZQo+ICsJICB3aWxsIGJlIGNhbGxlZCB0
bXAxMDMuCj4gKwo+ICAgY29uZmlnIFNFTlNPUlNfVE1QNDAxCj4gICAJdHJpc3RhdGUgIlRleGFz
IEluc3RydW1lbnRzIFRNUDQwMSBhbmQgY29tcGF0aWJsZXMiCj4gICAJZGVwZW5kcyBvbiBJMkMK
PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9NYWtlZmlsZSBiL2RyaXZlcnMvaHdtb24vTWFr
ZWZpbGUKPiBpbmRleCAxMTc5OGFkLi44ZTJmNmEyIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvaHdt
b24vTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4gQEAgLTEzNCw2ICsx
MzQsNyBAQCBvYmotJChDT05GSUdfU0VOU09SU19TTVNDNDdNMTkyKSs9IHNtc2M0N20xOTIubwo+
ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfQU1DNjgyMSkJKz0gYW1jNjgyMS5vCj4gICBvYmotJChD
T05GSUdfU0VOU09SU19USE1DNTApCSs9IHRobWM1MC5vCj4gICBvYmotJChDT05GSUdfU0VOU09S
U19UTVAxMDIpCSs9IHRtcDEwMi5vCj4gK29iai0kKENPTkZJR19TRU5TT1JTX1RNUDEwMykJKz0g
dG1wMTAzLm8KPiAgIG9iai0kKENPTkZJR19TRU5TT1JTX1RNUDQwMSkJKz0gdG1wNDAxLm8KPiAg
IG9iai0kKENPTkZJR19TRU5TT1JTX1RNUDQyMSkJKz0gdG1wNDIxLm8KPiAgIG9iai0kKENPTkZJ
R19TRU5TT1JTX1RXTDQwMzBfTUFEQykrPSB0d2w0MDMwLW1hZGMtaHdtb24ubwo+IGRpZmYgLS1n
aXQgYS9kcml2ZXJzL2h3bW9uL3RtcDEwMy5jIGIvZHJpdmVycy9od21vbi90bXAxMDMuYwo+IG5l
dyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uMDExMTlhNgo+IC0tLSAvZGV2L251
bGwKPiArKysgYi9kcml2ZXJzL2h3bW9uL3RtcDEwMy5jCj4gQEAgLTAsMCArMSwzMDQgQEAKPiAr
LyoKPiArICogVGV4YXMgSW5zdHJ1bWVudHMgVE1QMTAzIFNNQnVzIHRlbXBlcmF0dXJlIHNlbnNv
ciBkcml2ZXIKPiArICogQ29weXJpZ2h0IChDKSAyMDE0IEhlaWtvIFNjaG9jaGVyIDxoc0BkZW54
LmRlPgo+ICsgKgo+ICsgKiBCYXNlZCBvbjoKPiArICogVGV4YXMgSW5zdHJ1bWVudHMgVE1QMTAy
IFNNQnVzIHRlbXBlcmF0dXJlIHNlbnNvciBkcml2ZXIKPiArICoKPiArICogQ29weXJpZ2h0IChD
KSAyMDEwIFN0ZXZlbiBLaW5nIDxzZmtpbmdAZmR3ZGMuY29tPgo+ICsgKgo+ICsgKiBUaGlzIHBy
b2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1v
ZGlmeQo+ICsgKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBM
aWNlbnNlIGFzIHB1Ymxpc2hlZCBieQo+ICsgKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9u
OyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgo+ICsgKiAoYXQgeW91ciBvcHRp
b24pIGFueSBsYXRlciB2ZXJzaW9uLgo+ICsgKgo+ICsgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJp
YnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKPiArICogYnV0IFdJVEhP
VVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKPiAr
ICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAg
U2VlIHRoZQo+ICsgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxz
Lgo+ICsgKgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiArI2luY2x1
ZGUgPGxpbnV4L2luaXQuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KPiArI2luY2x1ZGUg
PGxpbnV4L2kyYy5oPgo+ICsjaW5jbHVkZSA8bGludXgvaHdtb24uaD4KPiArI2luY2x1ZGUgPGxp
bnV4L2h3bW9uLXN5c2ZzLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9lcnIuaD4KPiArI2luY2x1ZGUg
PGxpbnV4L211dGV4Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9kZXZpY2UuaD4KPiArI2luY2x1ZGUg
PGxpbnV4L2ppZmZpZXMuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPgo+ICsKPiArI2Rl
ZmluZQlEUklWRVJfTkFNRSAidG1wMTAzIgo+ICsKPiArI2RlZmluZQlUTVAxMDNfVEVNUF9SRUcJ
CQkweDAwCj4gKyNkZWZpbmUJVE1QMTAzX0NPTkZfUkVHCQkJMHgwMQo+ICsjZGVmaW5lCVRNUDEw
M19UTE9XX1JFRwkJCTB4MDIKPiArI2RlZmluZQlUTVAxMDNfVEhJR0hfUkVHCQkweDAzCj4gKwo+
ICsjZGVmaW5lCQlUTVAxMDNfQ09ORl9NMAkJMHgwMQo+ICsjZGVmaW5lCQlUTVAxMDNfQ09ORl9N
MQkJMHgwMgo+ICsjZGVmaW5lCQlUTVAxMDNfQ09ORl9MQwkJMHgwNAo+ICsjZGVmaW5lCQlUTVAx
MDNfQ09ORl9GTAkJMHgwOAo+ICsjZGVmaW5lCQlUTVAxMDNfQ09ORl9GSAkJMHgxMAo+ICsjZGVm
aW5lCQlUTVAxMDNfQ09ORl9DUjAJCTB4MjAKPiArI2RlZmluZQkJVE1QMTAzX0NPTkZfQ1IxCQkw
eDQwCj4gKyNkZWZpbmUJCVRNUDEwM19DT05GX0lECQkweDgwCj4gKyNkZWZpbmUJCVRNUDEwM19D
T05GX1NECQkoVE1QMTAzX0NPTkZfTTAgfCBUTVAxMDNfQ09ORl9NMSkKPiArCk5vIHRhYiBiZXR3
ZWVuICNkZWZpbmUgYW5kIHRoZSBhY3R1YWwgZGVmaW5pdGlvbiwgcGxlYXNlLgoKPiArc3RydWN0
IHRtcDEwMyB7Cj4gKwlzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoKTm8gbG9uZ2VyIG5lZWRl
ZC4gU2VlIGJlbG93LgoKPiArCXN0cnVjdCBkZXZpY2UgKmh3bW9uX2RldjsKPiArCXN0cnVjdCBy
ZWdtYXAgKnJlZ21hcDsKPiArCXN0cnVjdCBtdXRleCBsb2NrOwo+ICsJdW5zaWduZWQgaW50IGNv
bmZpZ19vcmlnOwo+ICsJdW5zaWduZWQgbG9uZyBsYXN0X3VwZGF0ZTsKPiArCWludCB0ZW1wWzNd
OwoKQm90aCBubyBsb25nZXIgbmVlZGVkLgoKQWN0dWFsbHksIHRoZSBlbnRpcmUgc3RydWN0dXJl
IGlzIG5vdCByZWFsbHkgbmVlZGVkIGFueW1vcmUgd2l0aCB0aGUgY2hhbmdlcyBzdWdnZXN0ZWQK
YmVsb3cuIFRoZSBvbmx5IHZhbHVlIHN0aWxsIG5lZWRlZCB3b3VsZCBiZSByZWdtYXAsIGFuZCB5
b3UgY291bGQgc3RvcmUgdGhhdCBkaXJlY3RseQppbiBkcnZkYXRhLgoKPiArfTsKPiArCj4gK3N0
YXRpYyBpbmxpbmUgaW50IHRtcDEwM19yZWdfdG9fbWMoczggdmFsKQo+ICt7Cj4gKwlyZXR1cm4g
dmFsICogMTAwMDsKPiArfQo+ICsKPiArc3RhdGljIGlubGluZSB1OCB0bXAxMDNfbWNfdG9fcmVn
KGludCB2YWwpCj4gK3sKPiArCXJldHVybiBESVZfUk9VTkRfQ0xPU0VTVCh2YWwsIDEwMDApOwo+
ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3QgdTggdG1wMTAzX3JlZ1tdID0gewo+ICsJVE1QMTAzX1RF
TVBfUkVHLAo+ICsJVE1QMTAzX1RMT1dfUkVHLAo+ICsJVE1QMTAzX1RISUdIX1JFRywKPiArfTsK
Ck5vIGxvbmdlciBuZWVkZWQ7IHlvdSBjYW4gcHV0IHRoZSByZWdpc3RlciBkaXJlY3RseSBpbnRv
IHNkYS0+aW5kZXguCgo+ICsKPiArI2RlZmluZSBUTVAxMDNfSU5WQUxJRAkweGZmZmYKPiArCj4g
K3N0YXRpYyBzc2l6ZV90IHRtcDEwM19zaG93X3RlbXAoc3RydWN0IGRldmljZSAqZGV2LAo+ICsJ
CQkJc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsCj4gKwkJCQljaGFyICpidWYpCj4gK3sK
PiArCXN0cnVjdCBzZW5zb3JfZGV2aWNlX2F0dHJpYnV0ZSAqc2RhID0gdG9fc2Vuc29yX2Rldl9h
dHRyKGF0dHIpOwo+ICsJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHRvX2kyY19jbGllbnQo
ZGV2KTsKPiArCXN0cnVjdCB0bXAxMDMgKnRtcDEwMyA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGll
bnQpOwoKVG9vIGNvbXBsaWNhdGVkLiBBdHRyaWJ1dGVzIGFyZSBub3cgYXR0YWNoZWQgdG8gdGhl
IGh3bW9uIGRldmljZSwgYW5kIHRtcDEwMwpjYW4gYmUgcmV0cmlldmVkIGZyb20gdGhlcmUuCgoJ
c3RydWN0IHRtcDEwMyAqdG1wMTAzID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cm9yLCB3aXRoIGFs
bCB0aGUgY2hhbmdlcyBJIHN1Z2dlc3RlZCwgZXZlbiBzaW1wbGVyCglzdHJ1Y3QgcmVnbWFwICpy
ZWdtYXAgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKCj4gKwl1bnNpZ25lZCBpbnQgc3RhdHVzOwo+
ICsJaW50IHJldDsKPiArCj4gKwltdXRleF9sb2NrKCZ0bXAxMDMtPmxvY2spOwo+ICsJaWYgKHRp
bWVfYWZ0ZXIoamlmZmllcywgdG1wMTAzLT5sYXN0X3VwZGF0ZSArIEhaIC8gMykpIHsKPiArCQlp
bnQgaTsKPiArCj4gKwkJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUodG1wMTAzLT50ZW1wKTsg
KytpKSB7Cj4gKwkJCXJldCA9IHJlZ21hcF9yZWFkKHRtcDEwMy0+cmVnbWFwLCB0bXAxMDNfcmVn
W2ldLAo+ICsJCQkJCSAgJnN0YXR1cyk7Cj4gKwkJCWlmIChyZXQgPCAwKQo+ICsJCQkJdG1wMTAz
LT50ZW1wW2ldID0gVE1QMTAzX0lOVkFMSUQ7CgpHb29kIGlkZWEsIGJ1dCBub3QgcmVhbGx5IHdo
YXQgd2UnZCB3YW50IHRvIHNlZS4gSW4gdGhpcyBjYXNlIHRoZSBlcnJvcgpzaG91bGQgYmUgcmVw
b3J0ZWQgdG8gdXNlIHNwYWNlLCBpZSByZXR1cm4gdGhlIHZhbHVlIG9mICdyZXQnLCBub3QgImlu
dmFsaWQiLgpBbHNvLCB5b3UgZG9uJ3QgbmVlZCB0byByZWFkIGFsbCByZWdpc3RlcnMgaGVyZSwg
YW5kIGp1c3QgZm9yZ2V0IGFib3V0CmxvY2FsIGNhY2hpbmcgKG5vdCB3b3J0aCBpdCkuCgpTdWdn
ZXN0ZWQgcmVwbGFjZW1lbnQgYmVsb3cuCgo+ICsJCQllbHNlCj4gKwkJCQl0bXAxMDMtPnRlbXBb
aV0gPSB0bXAxMDNfcmVnX3RvX21jKHN0YXR1cyk7Cj4gKwkJfQo+ICsJCXRtcDEwMy0+bGFzdF91
cGRhdGUgPSBqaWZmaWVzOwo+ICsJfQo+ICsJbXV0ZXhfdW5sb2NrKCZ0bXAxMDMtPmxvY2spOwo+
ICsKPiArCWlmICh0bXAxMDMtPnRlbXBbc2RhLT5pbmRleF0gIT0gVE1QMTAzX0lOVkFMSUQpCj4g
KwkJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIHRtcDEwMy0+dGVtcFtzZGEtPmluZGV4XSk7
Cj4gKwo+ICsJcmV0dXJuIHNwcmludGYoYnVmLCAiaW52YWxpZFxuIik7Cj4gK30KCnN0YXRpYyBz
c2l6ZV90IHRtcDEwM19zaG93X3RlbXAoc3RydWN0IGRldmljZSAqZGV2LAoJCQkJc3RydWN0IGRl
dmljZV9hdHRyaWJ1dGUgKmF0dHIsCgkJCQljaGFyICpidWYpCnsKCXN0cnVjdCBzZW5zb3JfZGV2
aWNlX2F0dHJpYnV0ZSAqc2RhID0gdG9fc2Vuc29yX2Rldl9hdHRyKGF0dHIpOwoJc3RydWN0IHRt
cDEwMyAqdG1wMTAzID0gZGV2X2dldF9kcnZkYXRhKGRldik7CS8qIG9yIHN0cnVjdCByZWdtYXAg
KnJlZ21hcCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOyAqLwoJdW5zaWduZWQgaW50IHJlZ3ZhbDsK
CWludCByZXQ7CgoJcmV0ID0gcmVnbWFwX3JlYWQodG1wMTAzLT5yZWdtYXAsIHNkYS0+aW5kZXgs
ICZyZWd2YWwpOwoJaWYgKHJldCA8IDApCgkJcmV0dXJuIHJldDsKCglyZXR1cm4gcmV0dXJuIHNw
cmludGYoYnVmLCAiJWRcbiIsIHRtcDEwM19yZWdfdG9fbWMocmVndmFsKSk7Cn0KCgo+ICsKPiAr
c3RhdGljIHNzaXplX3QgdG1wMTAzX3NldF90ZW1wKHN0cnVjdCBkZXZpY2UgKmRldiwKPiArCQkJ
ICAgICAgIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAo+ICsJCQkgICAgICAgY29uc3Qg
Y2hhciAqYnVmLCBzaXplX3QgY291bnQpCj4gK3sKPiArCXN0cnVjdCBzZW5zb3JfZGV2aWNlX2F0
dHJpYnV0ZSAqc2RhID0gdG9fc2Vuc29yX2Rldl9hdHRyKGF0dHIpOwo+ICsJc3RydWN0IGkyY19j
bGllbnQgKmNsaWVudCA9IHRvX2kyY19jbGllbnQoZGV2KTsKPiArCXN0cnVjdCB0bXAxMDMgKnRt
cDEwMyA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGllbnQpOwoKU2FtZSBhcyBhYm92ZS4KCXN0cnVj
dCB0bXAxMDMgKnRtcDEwMyA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoKCj4gKwlsb25nIHZhbDsK
PiArCWludCByZXQ7Cj4gKwo+ICsJaWYgKGtzdHJ0b2woYnVmLCAxMCwgJnZhbCkgPCAwKQo+ICsJ
CXJldHVybiAtRUlOVkFMOwo+ICsKPiArCXZhbCA9IGNsYW1wX3ZhbCh2YWwsIC01NTAwMCwgMTI3
MDAwKTsKPiArCW11dGV4X2xvY2soJnRtcDEwMy0+bG9jayk7Cj4gKwl0bXAxMDMtPnRlbXBbc2Rh
LT5pbmRleF0gPSB2YWw7Cj4gKwlyZXQgPSByZWdtYXBfd3JpdGUodG1wMTAzLT5yZWdtYXAsIHRt
cDEwM19yZWdbc2RhLT5pbmRleF0sCj4gKwkJCSAgIHRtcDEwM19tY190b19yZWcodmFsKSk7CgpB
ZnRlciBkcm9wcGluZyB0bXAxMDMtPnRlbXBbXSB5b3UgZG9uJ3QgbmVlZCB0aGUgbG9jayBhbnlt
b3JlLAp3aGljaCBtZWFucyBpdCBjYW4gZ28gYXdheSBjb21wbGV0ZWx5LgoKPiArCW11dGV4X3Vu
bG9jaygmdG1wMTAzLT5sb2NrKTsKPiArCXJldHVybiByZXQgPyA6IGNvdW50Owo+ICt9Cj4gKwo+
ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKHRlbXAxX2lucHV0LCBTX0lSVUdPLCB0bXAxMDNf
c2hvd190ZW1wLCBOVUxMICwgMCk7Cj4gKwpBcyBzdWdnZXN0ZWQgYWJvdmUsIGluc3RlYWQgb2Yg
dXNpbmcgYW4gaW5kaXJlY3QgaW5kZXgsIHVzZSBUTVAxMDNfVEVNUF9SRUcgZGlyZWN0bHkKdG8g
c2ltcGxpZnkgdGhlIGNvZGUuCgo+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKHRlbXAxX21p
biwgU19JV1VTUiB8IFNfSVJVR08sIHRtcDEwM19zaG93X3RlbXAsCj4gKwkJCSAgdG1wMTAzX3Nl
dF90ZW1wLCAxKTsKPiArCj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVtcDFfbWF4LCBT
X0lXVVNSIHwgU19JUlVHTywgdG1wMTAzX3Nob3dfdGVtcCwKPiArCQkJICB0bXAxMDNfc2V0X3Rl
bXAsIDIpOwo+ICsKPiArc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGUgKnRtcDEwM19hdHRyc1tdID0g
ewo+ICsJJnNlbnNvcl9kZXZfYXR0cl90ZW1wMV9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+ICsJJnNl
bnNvcl9kZXZfYXR0cl90ZW1wMV9taW4uZGV2X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0
dHJfdGVtcDFfbWF4LmRldl9hdHRyLmF0dHIsCj4gKwlOVUxMCj4gK307Cj4gK0FUVFJJQlVURV9H
Uk9VUFModG1wMTAzKTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgcmVnbWFwX2NvbmZpZyB0bXAxMDNf
cmVnbWFwX2NvbmZpZyA9IHsKPiArCS5yZWdfYml0cyA9IDgsCj4gKwkudmFsX2JpdHMgPSA4LAo+
ICsJLm1heF9yZWdpc3RlciA9IFRNUDEwM19USElHSF9SRUcsCgpZb3UgY2FuIGFsc28gYWRkIGEg
J3ZvbGF0aWxlJyBmdW5jdGlvbiB0byB0ZWxsIHJlZ21hcCB3aGljaCByZWdpc3RlcnMgYXJlIHZv
bGF0aWxlLgoKCS52b2xhdGlsZV9yZWcgPSB0bXAxMDNfaXNfdm9sYXRpbGUsCgp3aXRoCgpzdGF0
aWMgYm9vbCB0bXAxMDNfcmVnbWFwX2lzX3ZvbGF0aWxlKHN0cnVjdCBkZXZpY2UgKmRldiwgdW5z
aWduZWQgaW50IHJlZykKewoJcmV0dXJuIHJlZyA9PSBUTVAxMDNfVEVNUF9SRUc7Cn0KCldpdGgg
dGhpcywgb25seSB0aGUgdGVtcGVyYXR1cmUgcmVnaXN0ZXIgd2lsbCBiZSByZWFkIGFmdGVyIHRo
ZSBmaXJzdCBpbml0aWFsaXphdGlvbi4KSWYgeW91IGFkZCBhbGFybSBhdHRyaWJ1dGVzLCB5b3Un
ZCBoYXZlIHRvIGFkZCB0aGUgY29uZmlndXJhdGlvbiByZWdpc3RlciwgYnV0IG5vdApmb3Igbm93
LgoKPiArfTsKPiArCj4gKyNkZWZpbmUgVE1QMTAzX0NPTkZJRwkJKFRNUDEwM19DT05GX0NSMSB8
IFRNUDEwM19DT05GX00xKQo+ICsKQ2FuIHlvdSBtb3ZlIHRoaXMgdG8gdGhlIG90aGVyIGRlZmlu
aXRpb25zID8gVE1QMTAzX0NPTkZfU0QgaXMgYWxyZWFkeSB0aGVyZSwKc28gdGhpcyB3b3VsZCBi
ZSBtb3JlIGNvbnNpc3RlbnQuCgo+ICtzdGF0aWMgaW50IHRtcDEwM19wcm9iZShzdHJ1Y3QgaTJj
X2NsaWVudCAqY2xpZW50LAo+ICsJCQljb25zdCBzdHJ1Y3QgaTJjX2RldmljZV9pZCAqaWQpCj4g
K3sKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZjbGllbnQtPmRldjsKPiArCXN0cnVjdCBkZXZp
Y2UgKmh3bW9uX2RldjsKPiArCXN0cnVjdCB0bXAxMDMgKnRtcDEwMzsKPiArCWludCByZXQ7Cj4g
Kwl1bnNpZ25lZCBpbnQgc3RhdHVzOwo+ICsKPiArCWlmICghaTJjX2NoZWNrX2Z1bmN0aW9uYWxp
dHkoY2xpZW50LT5hZGFwdGVyLAo+ICsJCQkJICAgICBJMkNfRlVOQ19TTUJVU19CWVRFX0RBVEEp
KSB7Cj4gKwkJZGV2X2VycigmY2xpZW50LT5kZXYsCj4gKwkJCSJhZGFwdGVyIGRvZXNuJ3Qgc3Vw
cG9ydCBTTUJ1cyBieXRlIHRyYW5zYWN0aW9uc1xuIik7Cj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4g
Kwl9Cj4gKwo+ICsJdG1wMTAzID0gZGV2bV9remFsbG9jKCZjbGllbnQtPmRldiwgc2l6ZW9mKCp0
bXAxMDMpLCBHRlBfS0VSTkVMKTsKPiArCWlmICghdG1wMTAzKQo+ICsJCXJldHVybiAtRU5PTUVN
Owo+ICsKPiArCWkyY19zZXRfY2xpZW50ZGF0YShjbGllbnQsIHRtcDEwMyk7Cj4gKwl0bXAxMDMt
PmNsaWVudCA9IGNsaWVudDsKCkJvdGggbm8gbG9uZ2VyIG5lZWRlZC4KCj4gKwo+ICsJdG1wMTAz
LT5yZWdtYXAgPSBkZXZtX3JlZ21hcF9pbml0X2kyYyhjbGllbnQsICZ0bXAxMDNfcmVnbWFwX2Nv
bmZpZyk7Cj4gKwlpZiAoSVNfRVJSKHRtcDEwMy0+cmVnbWFwKSkgewo+ICsJCWRldl9lcnIoZGV2
LCAiZmFpbGVkIHRvIGFsbG9jYXRlIHJlZ2lzdGVyIG1hcFxuIik7Cj4gKwkJcmV0dXJuIFBUUl9F
UlIodG1wMTAzLT5yZWdtYXApOwo+ICsJfQo+ICsKPiArCXJldCA9IHJlZ21hcF9yZWFkKHRtcDEw
My0+cmVnbWFwLCBUTVAxMDNfQ09ORl9SRUcsICZzdGF0dXMpOwo+ICsJaWYgKHJldCA8IDApCj4g
KwkJZ290byBmYWlsX2luaXRfcmVnbWFwOwo+ICsKPiArCXRtcDEwMy0+Y29uZmlnX29yaWcgPSBz
dGF0dXM7Cj4gKwlyZXQgPSByZWdtYXBfd3JpdGUodG1wMTAzLT5yZWdtYXAsIFRNUDEwM19DT05G
X1JFRywgVE1QMTAzX0NPTkZJRyk7Cj4gKwlpZiAocmV0IDwgMCkgewo+ICsJCWRldl9lcnIoJmNs
aWVudC0+ZGV2LCAiZXJyb3Igd3JpdGluZyBjb25maWcgcmVnaXN0ZXJcbiIpOwo+ICsJCWdvdG8g
ZmFpbF9yZXN0b3JlX2NvbmZpZzsKPiArCX0KPiArCj4gKwlyZXQgPSByZWdtYXBfcmVhZCh0bXAx
MDMtPnJlZ21hcCwgVE1QMTAzX0NPTkZfUkVHLCAmc3RhdHVzKTsKPiArCWlmIChyZXQgPCAwKSB7
Cj4gKwkJZGV2X2VycigmY2xpZW50LT5kZXYsICJlcnJvciByZWFkaW5nIGNvbmZpZyByZWdpc3Rl
clxuIik7Cj4gKwkJZ290byBmYWlsX3Jlc3RvcmVfY29uZmlnOwo+ICsJfQo+ICsJaWYgKHN0YXR1
cyAhPSBUTVAxMDNfQ09ORklHKSB7Cj4gKwkJZGV2X2VycigmY2xpZW50LT5kZXYsICJjb25maWcg
c2V0dGluZ3MgZGlkIG5vdCBzdGlja1xuIik7Cj4gKwkJcmV0ID0gLUVOT0RFVjsKPiArCQlnb3Rv
IGZhaWxfcmVzdG9yZV9jb25maWc7Cj4gKwl9CgpUaGUgYWJvdmUgd3JpdGUvcmVhZCBzZXF1ZW5j
ZSBjYW4gYmUgbWFkZSBjb25kaXRpb25hbC4KSWYgKGNvbmZpZ19vcmlnICYgMHg2NykgPT0gVE1Q
MTAzX0NPTkZJRywgdGhlcmUgaXMgbm8gbmVlZCB0byB1cGRhdGUgdGhlCmNvbmZpZ3VyYXRpb24g
cmVnaXN0ZXIuCgpBbHNvLCBJIGp1c3QgcmVhbGl6ZWQgdGhhdCB0aGUgY3VycmVudCBjb2RlIHdv
bid0IHdvcms6IFRoZSBGSCBhbmQgRkwgYml0cwphcmUgbm90IGNvbnRyb2xsZWQgYnkgeW91LCBi
dXQgYnkgdGhlIGNoaXAuIFNvIHRoZSB2ZXJpZmljYXRpb24gKGFzIHdyaXR0ZW4pCndpbGwgZmFp
bCBpZiB5b3UgaGF2ZSBhbiBhbGFybSBjb25kaXRpb24uIEkgd291bGQgc3VnZ2VzdCB0byBkcm9w
IHRoZQp2ZXJpZmljYXRpb24gZW50aXJlbHk7IEkgZG9uJ3QgdGhpbmsgaXQgYWRkcyBtdWNoIGlm
IGFueSB2YWx1ZS4KQXQgdGhlIHZlcnkgbGVhc3QsIHlvdSdsbCBoYXZlIHRvIG1hc2sgdGhlIHJl
c3VsdCBhZ2FpbnN0IDB4NjcuCgpBY3R1YWxseSwgSSB3b3VsZCBzdWdnZXN0IHRvIGRyb3AgY29u
ZmlnX29yaWcgZW50aXJlbHkuIFRoZW4geW91IGNhbgp1c2UgcmVnbWFwX3VwZGF0ZV9iaXRzKCkg
dG8gc2V0IHRoZSBjb25maWd1cmF0aW9uLiBBbHNvLCB5b3UgY2FuIHRoZW4gdXNlCmRldm1faHdt
b25fZGV2aWNlX3JlZ2lzdGVyX3dpdGhfZ3JvdXBzKCksIGFuZCBkcm9wIHRoZSByZW1vdmUgZnVu
Y3Rpb24KYXMgd2VsbC4KCj4gKwl0bXAxMDMtPmxhc3RfdXBkYXRlID0gamlmZmllcyAtIEhaOwoK
Tm8gbG9uZ2VyIG5lZWRlZC4KCj4gKwltdXRleF9pbml0KCZ0bXAxMDMtPmxvY2spOwo+ICsKPiAr
CWh3bW9uX2RldiA9IGh3bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcyhkZXYsIGNsaWVu
dC0+bmFtZSwKPiArCQkJCQkJICAgICAgdG1wMTAzLCB0bXAxMDNfZ3JvdXBzKTsKPiArCWlmIChJ
U19FUlIoaHdtb25fZGV2KSkgewo+ICsJCWRldl9kYmcoZGV2LCAidW5hYmxlIHRvIHJlZ2lzdGVy
IGh3bW9uIGRldmljZVxuIik7CgoKPiArCQlzdGF0dXMgPSBQVFJfRVJSKGh3bW9uX2Rldik7Cj4g
KwkJZ290byBmYWlsX3Jlc3RvcmVfY29uZmlnOwo+ICsJfQo+ICsJdG1wMTAzLT5od21vbl9kZXYg
PSBod21vbl9kZXY7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gKwo+ICtmYWlsX3Jlc3RvcmVfY29uZmln
Ogo+ICsJcmVnbWFwX3dyaXRlKHRtcDEwMy0+cmVnbWFwLCBUTVAxMDNfQ09ORl9SRUcsIHRtcDEw
My0+Y29uZmlnX29yaWcpOwo+ICtmYWlsX2luaXRfcmVnbWFwOgo+ICsJcmVnbWFwX2V4aXQodG1w
MTAzLT5yZWdtYXApOwoKVGhpcyBpcyBub3QgbmVlZGVkIHNpbmNlIHlvdSB1c2VkIHRoZSBkZXZt
XyBpbml0aWFsaXphdGlvbiBmdW5jdGlvbiBhYm92ZS4KSW4gZmFjdCwgaXQgaXMgbGlrZWx5IHdy
b25nLgoKSWYgeW91IGRyb3AgcmVzdG9yaW5nIHRoZSBjb25maWd1cmF0aW9uIHJlZ2lzdGVyLCB0
aGUgZW50aXJlIHNlcXVlbmNlIGNhbiBiZWNvbWUKCglod21vbl9kZXYgPSBkZXZtX2h3bW9uX2Rl
dmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcyhkZXYsIGNsaWVudC0+bmFtZSwKCQkJCQkJICAgICAg
ICAgICB0bXAxMDMsIHRtcDEwM19ncm91cHMpOwoJcmV0dXJuIFBUUl9FUlJfT1JfWkVSTyhod21v
bl9kZXYpOwoKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgdG1wMTAzX3Jl
bW92ZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQo+ICt7Cj4gKwlzdHJ1Y3QgdG1wMTAzICp0
bXAxMDMgPSBpMmNfZ2V0X2NsaWVudGRhdGEoY2xpZW50KTsKPiArCWludCByZXQ7Cj4gKwo+ICsJ
cmV0ID0gcmVnbWFwX3dyaXRlKHRtcDEwMy0+cmVnbWFwLCBUTVAxMDNfQ09ORl9SRUcsCj4gKwkJ
CSAgIHRtcDEwMy0+Y29uZmlnX29yaWcpOwoKT25seSBuZWVkZWQgaWYgKGNvbmZpZ19vcmlnICYg
MHg2NykgIT0gVE1QMTAzX0NPTkZJRy4KCj4gKwlpZiAocmV0IDwgMCkKPiArCQlkZXZfZXJyKCZj
bGllbnQtPmRldiwgImVycm9yIHdyaXRpbmcgY29uZmlnIHJlZ2lzdGVyXG4iKTsKPiArCkknZCBz
dWdnZXN0IHRvIGRyb3AgdGhlIGVycm9yIG1lc3NhZ2UuIEl0IGRvZXMgbm90IHJlYWxseSBtYXR0
ZXIsCmFmdGVyIGFsbCwgYW5kIGlzIHF1aXRlIHVubGlrZWx5LgoKPiArCWh3bW9uX2RldmljZV91
bnJlZ2lzdGVyKHRtcDEwMy0+aHdtb25fZGV2KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK
PiArI2lmZGVmIENPTkZJR19QTQo+ICtzdGF0aWMgaW50IHRtcDEwM19zdXNwZW5kKHN0cnVjdCBk
ZXZpY2UgKmRldikKPiArewo+ICsJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHRvX2kyY19j
bGllbnQoZGV2KTsKPiArCXN0cnVjdCB0bXAxMDMgKnRtcDEwMyA9IGkyY19nZXRfY2xpZW50ZGF0
YShjbGllbnQpOwo+ICsJdW5zaWduZWQgaW50IGNvbmZpZzsKPiArCWludCByZXQ7Cj4gKwo+ICsJ
cmV0ID0gcmVnbWFwX3JlYWQodG1wMTAzLT5yZWdtYXAsIFRNUDEwM19DT05GX1JFRywgJmNvbmZp
Zyk7Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCWNvbmZpZyAmPSB+
VE1QMTAzX0NPTkZfU0Q7Cj4gKwlyZXR1cm4gcmVnbWFwX3dyaXRlKHRtcDEwMy0+cmVnbWFwLCBU
TVAxMDNfQ09ORl9SRUcsIGNvbmZpZyk7CgpZb3UgY2FuIHVzZSByZWdtYXBfdXBkYXRlX2JpdHMo
KSBoZXJlLgoKPiArfQo+ICsKPiArc3RhdGljIGludCB0bXAxMDNfcmVzdW1lKHN0cnVjdCBkZXZp
Y2UgKmRldikKPiArewo+ICsJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHRvX2kyY19jbGll
bnQoZGV2KTsKPiArCXN0cnVjdCB0bXAxMDMgKnRtcDEwMyA9IGkyY19nZXRfY2xpZW50ZGF0YShj
bGllbnQpOwo+ICsJdW5zaWduZWQgaW50IGNvbmZpZzsKPiArCWludCByZXQ7Cj4gKwo+ICsJcmV0
ID0gcmVnbWFwX3JlYWQodG1wMTAzLT5yZWdtYXAsIFRNUDEwM19DT05GX1JFRywgJmNvbmZpZyk7
Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCWNvbmZpZyB8PSBUTVAx
MDNfQ09ORl9TRDsKPiArCXJldHVybiByZWdtYXBfd3JpdGUodG1wMTAzLT5yZWdtYXAsIFRNUDEw
M19DT05GX1JFRywgY29uZmlnKTsKCllvdSBjYW4gdXNlIHJlZ21hcF91cGRhdGVfYml0cygpIGhl
cmUuCgo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGRldl9wbV9vcHMgdG1wMTAzX2Rl
dl9wbV9vcHMgPSB7Cj4gKwkuc3VzcGVuZAk9IHRtcDEwM19zdXNwZW5kLAo+ICsJLnJlc3VtZQkJ
PSB0bXAxMDNfcmVzdW1lLAo+ICt9Owo+ICsKPiArI2RlZmluZSBUTVAxMDNfREVWX1BNX09QUyAo
JnRtcDEwM19kZXZfcG1fb3BzKQo+ICsjZWxzZQo+ICsjZGVmaW5lCVRNUDEwM19ERVZfUE1fT1BT
IE5VTEwKPiArI2VuZGlmIC8qIENPTkZJR19QTSAqLwo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVj
dCBpMmNfZGV2aWNlX2lkIHRtcDEwM19pZFtdID0gewo+ICsJeyBEUklWRVJfTkFNRSwgMCB9LAo+
ICsJeyB9Cj4gK307Cj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUoaTJjLCB0bXAxMDNfaWQpOwo+ICsK
PiArc3RhdGljIHN0cnVjdCBpMmNfZHJpdmVyIHRtcDEwM19kcml2ZXIgPSB7Cj4gKwkuZHJpdmVy
ID0gewo+ICsJCS5uYW1lCT0gRFJJVkVSX05BTUUsCj4gKwkJLnBtCT0gVE1QMTAzX0RFVl9QTV9P
UFMsCj4gKwl9LAo+ICsJLnByb2JlCQk9IHRtcDEwM19wcm9iZSwKPiArCS5yZW1vdmUJCT0gdG1w
MTAzX3JlbW92ZSwKPiArCS5pZF90YWJsZQk9IHRtcDEwM19pZCwKPiArfTsKPiArCj4gK21vZHVs
ZV9pMmNfZHJpdmVyKHRtcDEwM19kcml2ZXIpOwo+ICsKPiArTU9EVUxFX0FVVEhPUigiSGVpa28g
U2Nob2NoZXIgPGhzQGRlbnguZGU+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiVGV4YXMgSW5z
dHJ1bWVudHMgVE1QMTAzIHRlbXBlcmF0dXJlIHNlbnNvciBkcml2ZXIiKTsKPiArTU9EVUxFX0xJ
Q0VOU0UoIkdQTCIpOwo+CgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX18KbG0tc2Vuc29ycyBtYWlsaW5nIGxpc3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9y
ZwpodHRwOi8vbGlzdHMubG0tc2Vuc29ycy5vcmcvbWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz

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

end of thread, other threads:[~2014-06-13 16:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-13  7:10 [PATCH v2] hwmon: Driver for TI TMP103 temperature sensor Heiko Schocher
2014-06-13  7:10 ` [lm-sensors] " Heiko Schocher
2014-06-13 16:03 ` Guenter Roeck
2014-06-13 16:03   ` [lm-sensors] " Guenter Roeck
2014-06-13 16:03   ` Guenter Roeck

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.