aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch528
1 files changed, 0 insertions, 528 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch b/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch
deleted file mode 100644
index 142560c6da..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch
+++ /dev/null
@@ -1,528 +0,0 @@
-From 23769ad113407ceb21a4285a8194c7d788149269 Mon Sep 17 00:00:00 2001
-From: Akira Shimahara <akira215corp@gmail.com>
-Date: Mon, 11 May 2020 22:37:42 +0200
-Subject: [PATCH] w1_therm: optimizing temperature read timings
-
-commit 67b392f7b8edfa6f427fecd98722acab34c1c99f upstream.
-
-Optimizing temperature reading by reducing waiting conversion time
-according to device resolution settings, as per device specification.
-This is device dependent as not all the devices supports resolution
-setting, so it has been added in device family structures.
-
-The process to read the temperature on the device has been adapted in a
-new function 'convert_t()', which replace the former 'read_therm()', is
-introduce to deal with this timing. Strong pull up is also applied during
-the required time, according to device power status needs and
-'strong_pullup' module parameter.
-
-'temperature_from_RAM()' function is introduced to get the correct
-temperature computation (device dependent) from device RAM data.
-
-An new sysfs entry has been added to ouptut only temperature. The old
-entry w1_slave has been kept for compatibility, without changing its
-output format.
-
-Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly.
-
-Signed-off-by: Akira Shimahara <akira215corp@gmail.com>
-Link: https://lore.kernel.org/r/20200511203742.411039-1-akira215corp@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- .../ABI/testing/sysfs-driver-w1_therm | 12 +
- drivers/w1/slaves/w1_therm.c | 286 +++++++++++-------
- 2 files changed, 197 insertions(+), 101 deletions(-)
-
---- a/Documentation/ABI/testing/sysfs-driver-w1_therm
-+++ b/Documentation/ABI/testing/sysfs-driver-w1_therm
-@@ -41,6 +41,18 @@ Users: any user space application which
- w1_term device
-
-
-+What: /sys/bus/w1/devices/.../temperature
-+Date: May 2020
-+Contact: Akira Shimahara <akira215corp@gmail.com>
-+Description:
-+ (RO) return the temperature in 1/1000 degC.
-+ Note that the conversion duration depend on the resolution (if
-+ device support this feature). It takes 94ms in 9bits
-+ resolution, 750ms for 12bits.
-+Users: any user space application which wants to communicate with
-+ w1_term device
-+
-+
- What: /sys/bus/w1/devices/.../w1_slave
- Date: May 2020
- Contact: Akira Shimahara <akira215corp@gmail.com>
---- a/drivers/w1/slaves/w1_therm.c
-+++ b/drivers/w1/slaves/w1_therm.c
-@@ -93,6 +93,7 @@ module_param_named(strong_pullup, w1_str
- * @reserved: not used here
- * @f: pointer to the device binding structure
- * @convert: pointer to the device conversion function
-+ * @get_conversion_time: pointer to the device conversion time function
- * @set_resolution: pointer to the device set_resolution function
- * @get_resolution: pointer to the device get_resolution function
- */
-@@ -101,6 +102,7 @@ struct w1_therm_family_converter {
- u16 reserved;
- struct w1_family *f;
- int (*convert)(u8 rom[9]);
-+ int (*get_conversion_time)(struct w1_slave *sl);
- int (*set_resolution)(struct w1_slave *sl, int val);
- int (*get_resolution)(struct w1_slave *sl);
- };
-@@ -154,6 +156,15 @@ struct therm_info {
- static int reset_select_slave(struct w1_slave *sl);
-
- /**
-+ * convert_t() - Query the device for temperature conversion and read
-+ * @sl: pointer to the slave to read
-+ * @info: pointer to a structure to store the read results
-+ *
-+ * Return: 0 if success, -kernel error code otherwise
-+ */
-+static int convert_t(struct w1_slave *sl, struct therm_info *info);
-+
-+/**
- * read_scratchpad() - read the data in device RAM
- * @sl: pointer to the slave to read
- * @info: pointer to a structure to store the read results
-@@ -213,6 +224,9 @@ static ssize_t w1_slave_store(struct dev
- static ssize_t w1_seq_show(struct device *device,
- struct device_attribute *attr, char *buf);
-
-+static ssize_t temperature_show(struct device *device,
-+ struct device_attribute *attr, char *buf);
-+
- static ssize_t ext_power_show(struct device *device,
- struct device_attribute *attr, char *buf);
-
-@@ -229,6 +243,7 @@ static ssize_t eeprom_store(struct devic
-
- static DEVICE_ATTR_RW(w1_slave);
- static DEVICE_ATTR_RO(w1_seq);
-+static DEVICE_ATTR_RO(temperature);
- static DEVICE_ATTR_RO(ext_power);
- static DEVICE_ATTR_RW(resolution);
- static DEVICE_ATTR_WO(eeprom);
-@@ -259,6 +274,7 @@ static void w1_therm_remove_slave(struct
-
- static struct attribute *w1_therm_attrs[] = {
- &dev_attr_w1_slave.attr,
-+ &dev_attr_temperature.attr,
- &dev_attr_ext_power.attr,
- &dev_attr_resolution.attr,
- &dev_attr_eeprom.attr,
-@@ -267,6 +283,7 @@ static struct attribute *w1_therm_attrs[
-
- static struct attribute *w1_ds18s20_attrs[] = {
- &dev_attr_w1_slave.attr,
-+ &dev_attr_temperature.attr,
- &dev_attr_ext_power.attr,
- &dev_attr_eeprom.attr,
- NULL,
-@@ -275,6 +292,7 @@ static struct attribute *w1_ds18s20_attr
- static struct attribute *w1_ds28ea00_attrs[] = {
- &dev_attr_w1_slave.attr,
- &dev_attr_w1_seq.attr,
-+ &dev_attr_temperature.attr,
- &dev_attr_ext_power.attr,
- &dev_attr_resolution.attr,
- &dev_attr_eeprom.attr,
-@@ -389,6 +407,37 @@ static struct w1_family w1_therm_family_
-
- /* Device dependent func */
-
-+static inline int w1_DS18B20_convert_time(struct w1_slave *sl)
-+{
-+ int ret;
-+
-+ if (!sl->family_data)
-+ return -ENODEV; /* device unknown */
-+
-+ /* return time in ms for conversion operation */
-+ switch (SLAVE_RESOLUTION(sl)) {
-+ case 9:
-+ ret = 95;
-+ break;
-+ case 10:
-+ ret = 190;
-+ break;
-+ case 11:
-+ ret = 375;
-+ break;
-+ case 12:
-+ default:
-+ ret = 750;
-+ }
-+ return ret;
-+}
-+
-+static inline int w1_DS18S20_convert_time(struct w1_slave *sl)
-+{
-+ (void)(sl);
-+ return 750; /* always 750ms for DS18S20 */
-+}
-+
- static inline int w1_DS18B20_write_data(struct w1_slave *sl,
- const u8 *data)
- {
-@@ -480,8 +529,10 @@ static inline int w1_DS18S20_convert_tem
- {
- int t, h;
-
-- if (!rom[7])
-+ if (!rom[7]) {
-+ pr_debug("%s: Invalid argument for conversion\n", __func__);
- return 0;
-+ }
-
- if (rom[1] == 0)
- t = ((s32)rom[0] >> 1)*1000;
-@@ -500,34 +551,39 @@ static inline int w1_DS18S20_convert_tem
-
- static struct w1_therm_family_converter w1_therm_families[] = {
- {
-- .f = &w1_therm_family_DS18S20,
-- .convert = w1_DS18S20_convert_temp,
-- .set_resolution = NULL, /* no config register */
-- .get_resolution = NULL, /* no config register */
-+ .f = &w1_therm_family_DS18S20,
-+ .convert = w1_DS18S20_convert_temp,
-+ .get_conversion_time = w1_DS18S20_convert_time,
-+ .set_resolution = NULL, /* no config register */
-+ .get_resolution = NULL, /* no config register */
- },
- {
-- .f = &w1_therm_family_DS1822,
-- .convert = w1_DS18B20_convert_temp,
-- .set_resolution = w1_DS18B20_set_resolution,
-- .get_resolution = w1_DS18B20_get_resolution,
-+ .f = &w1_therm_family_DS1822,
-+ .convert = w1_DS18B20_convert_temp,
-+ .get_conversion_time = w1_DS18B20_convert_time,
-+ .set_resolution = w1_DS18B20_set_resolution,
-+ .get_resolution = w1_DS18B20_get_resolution,
- },
- {
-- .f = &w1_therm_family_DS18B20,
-- .convert = w1_DS18B20_convert_temp,
-- .set_resolution = w1_DS18B20_set_resolution,
-- .get_resolution = w1_DS18B20_get_resolution,
-+ .f = &w1_therm_family_DS18B20,
-+ .convert = w1_DS18B20_convert_temp,
-+ .get_conversion_time = w1_DS18B20_convert_time,
-+ .set_resolution = w1_DS18B20_set_resolution,
-+ .get_resolution = w1_DS18B20_get_resolution,
- },
- {
-- .f = &w1_therm_family_DS28EA00,
-- .convert = w1_DS18B20_convert_temp,
-- .set_resolution = w1_DS18B20_set_resolution,
-- .get_resolution = w1_DS18B20_get_resolution,
-+ .f = &w1_therm_family_DS28EA00,
-+ .convert = w1_DS18B20_convert_temp,
-+ .get_conversion_time = w1_DS18B20_convert_time,
-+ .set_resolution = w1_DS18B20_set_resolution,
-+ .get_resolution = w1_DS18B20_get_resolution,
- },
- {
-- .f = &w1_therm_family_DS1825,
-- .convert = w1_DS18B20_convert_temp,
-- .set_resolution = w1_DS18B20_set_resolution,
-- .get_resolution = w1_DS18B20_get_resolution,
-+ .f = &w1_therm_family_DS1825,
-+ .convert = w1_DS18B20_convert_temp,
-+ .get_conversion_time = w1_DS18B20_convert_time,
-+ .set_resolution = w1_DS18B20_set_resolution,
-+ .get_resolution = w1_DS18B20_get_resolution,
- }
- };
-
-@@ -582,24 +638,44 @@ static inline bool bus_mutex_lock(struct
- }
-
- /**
-- * w1_convert_temp() - temperature conversion binding function
-- * @rom: data read from device RAM (8 data bytes + 1 CRC byte)
-- * @fid: device family id
-+ * conversion_time() - get the Tconv for the slave
-+ * @sl: device to get the conversion time
- *
-- * The function call the temperature computation function according to
-- * device family.
-+ * On device supporting resolution settings, conversion time depend
-+ * on the resolution setting. This helper function get the slave timing,
-+ * depending on its current setting.
- *
-- * Return: value in millidegrees Celsius.
-+ * Return: conversion time in ms, negative values are kernel error code
- */
--static inline int w1_convert_temp(u8 rom[9], u8 fid)
-+static inline int conversion_time(struct w1_slave *sl)
- {
-- int i;
-+ if (SLAVE_SPECIFIC_FUNC(sl))
-+ return SLAVE_SPECIFIC_FUNC(sl)->get_conversion_time(sl);
-
-- for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i)
-- if (w1_therm_families[i].f->fid == fid)
-- return w1_therm_families[i].convert(rom);
-+ dev_info(&sl->dev,
-+ "%s: Device not supported by the driver\n", __func__);
-
-- return 0;
-+ return -ENODEV; /* No device family */
-+}
-+
-+/**
-+ * temperature_from_RAM() - Convert the read info to temperature
-+ * @sl: device that sent the RAM data
-+ * @rom: read value on the slave device RAM
-+ *
-+ * Device dependent, the function bind the correct computation method.
-+ *
-+ * Return: temperature in 1/1000degC, 0 on error.
-+ */
-+static inline int temperature_from_RAM(struct w1_slave *sl, u8 rom[9])
-+{
-+ if (SLAVE_SPECIFIC_FUNC(sl))
-+ return SLAVE_SPECIFIC_FUNC(sl)->convert(rom);
-+
-+ dev_info(&sl->dev,
-+ "%s: Device not supported by the driver\n", __func__);
-+
-+ return 0; /* No device family */
- }
-
- /* Interface Functions */
-@@ -679,96 +755,74 @@ static int reset_select_slave(struct w1_
- return 0;
- }
-
--static ssize_t read_therm(struct device *device,
-- struct w1_slave *sl, struct therm_info *info)
-+static int convert_t(struct w1_slave *sl, struct therm_info *info)
- {
-- struct w1_master *dev = sl->master;
-- u8 external_power;
-- int ret, max_trying = 10;
-- u8 *family_data = sl->family_data;
-+ struct w1_master *dev_master = sl->master;
-+ int max_trying = W1_THERM_MAX_TRY;
-+ int t_conv;
-+ int ret = -ENODEV;
-+ bool strong_pullup;
-
-- if (!family_data) {
-- ret = -ENODEV;
-+ if (!sl->family_data)
- goto error;
-- }
-
-- /* prevent the slave from going away in sleep */
-- atomic_inc(THERM_REFCNT(family_data));
-+ strong_pullup = (w1_strong_pullup == 2 ||
-+ (!SLAVE_POWERMODE(sl) &&
-+ w1_strong_pullup));
-
-- ret = mutex_lock_interruptible(&dev->bus_mutex);
-- if (ret != 0)
-- goto dec_refcnt;
-+ /* get conversion duration device and id dependent */
-+ t_conv = conversion_time(sl);
-
- memset(info->rom, 0, sizeof(info->rom));
-
-- while (max_trying--) {
-+ /* prevent the slave from going away in sleep */
-+ atomic_inc(THERM_REFCNT(sl->family_data));
-+
-+ if (!bus_mutex_lock(&dev_master->bus_mutex)) {
-+ ret = -EAGAIN; /* Didn't acquire the mutex */
-+ goto dec_refcnt;
-+ }
-+
-+ while (max_trying-- && ret) { /* ret should be 0 */
-
- info->verdict = 0;
- info->crc = 0;
--
-+ /* safe version to select slave */
- if (!reset_select_slave(sl)) {
-- int count = 0;
-- unsigned int tm = 750;
- unsigned long sleep_rem;
-
-- w1_write_8(dev, W1_READ_PSUPPLY);
-- external_power = w1_read_8(dev);
--
-- if (reset_select_slave(sl))
-- continue;
--
- /* 750ms strong pullup (or delay) after the convert */
-- if (w1_strong_pullup == 2 ||
-- (!external_power && w1_strong_pullup))
-- w1_next_pullup(dev, tm);
--
-- w1_write_8(dev, W1_CONVERT_TEMP);
-+ if (strong_pullup)
-+ w1_next_pullup(dev_master, t_conv);
-
-- if (external_power) {
-- mutex_unlock(&dev->bus_mutex);
-+ w1_write_8(dev_master, W1_CONVERT_TEMP);
-
-- sleep_rem = msleep_interruptible(tm);
-+ if (strong_pullup) { /*some device need pullup */
-+ sleep_rem = msleep_interruptible(t_conv);
- if (sleep_rem != 0) {
- ret = -EINTR;
-- goto dec_refcnt;
-+ goto mt_unlock;
- }
-+ mutex_unlock(&dev_master->bus_mutex);
-+ } else { /*no device need pullup */
-+ mutex_unlock(&dev_master->bus_mutex);
-
-- ret = mutex_lock_interruptible(&dev->bus_mutex);
-- if (ret != 0)
-- goto dec_refcnt;
-- } else if (!w1_strong_pullup) {
-- sleep_rem = msleep_interruptible(tm);
-+ sleep_rem = msleep_interruptible(t_conv);
- if (sleep_rem != 0) {
- ret = -EINTR;
-- goto mt_unlock;
-+ goto dec_refcnt;
- }
- }
--
-- if (!reset_select_slave(sl)) {
--
-- w1_write_8(dev, W1_READ_SCRATCHPAD);
-- count = w1_read_block(dev, info->rom, 9);
-- if (count != 9) {
-- dev_warn(device, "w1_read_block() "
-- "returned %u instead of 9.\n",
-- count);
-- }
--
-- info->crc = w1_calc_crc8(info->rom, 8);
--
-- if (info->rom[8] == info->crc)
-- info->verdict = 1;
-- }
-+ ret = read_scratchpad(sl, info);
-+ goto dec_refcnt;
- }
-
-- if (info->verdict)
-- break;
- }
-
- mt_unlock:
-- mutex_unlock(&dev->bus_mutex);
-+ mutex_unlock(&dev_master->bus_mutex);
- dec_refcnt:
-- atomic_dec(THERM_REFCNT(family_data));
-+ atomic_dec(THERM_REFCNT(sl->family_data));
- error:
- return ret;
- }
-@@ -1000,27 +1054,33 @@ static ssize_t w1_slave_show(struct devi
- u8 *family_data = sl->family_data;
- int ret, i;
- ssize_t c = PAGE_SIZE;
-- u8 fid = sl->family->fid;
-
-- ret = read_therm(device, sl, &info);
-- if (ret)
-- return ret;
-+ ret = convert_t(sl, &info);
-+
-+ if (ret < 0) {
-+ dev_dbg(device,
-+ "%s: Temperature data may be corrupted. err=%d\n",
-+ __func__, ret);
-+ return 0;
-+ }
-
- for (i = 0; i < 9; ++i)
- c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", info.rom[i]);
- c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
- info.crc, (info.verdict) ? "YES" : "NO");
-+
- if (info.verdict)
- memcpy(family_data, info.rom, sizeof(info.rom));
- else
-- dev_warn(device, "Read failed CRC check\n");
-+ dev_warn(device, "%s:Read failed CRC check\n", __func__);
-
- for (i = 0; i < 9; ++i)
- c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ",
- ((u8 *)family_data)[i]);
-
- c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
-- w1_convert_temp(info.rom, fid));
-+ temperature_from_RAM(sl, info.rom));
-+
- ret = PAGE_SIZE - c;
- return ret;
- }
-@@ -1063,6 +1123,31 @@ static ssize_t w1_slave_store(struct dev
- return size; /* always return size to avoid infinite calling */
- }
-
-+static ssize_t temperature_show(struct device *device,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct w1_slave *sl = dev_to_w1_slave(device);
-+ struct therm_info info;
-+ int ret = 0;
-+
-+ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) {
-+ dev_info(device,
-+ "%s: Device not supported by the driver\n", __func__);
-+ return 0; /* No device family */
-+ }
-+
-+ ret = convert_t(sl, &info);
-+
-+ if (ret < 0) {
-+ dev_dbg(device,
-+ "%s: Temperature data may be corrupted. err=%d\n",
-+ __func__, ret);
-+ return 0;
-+ }
-+
-+ return sprintf(buf, "%d\n", temperature_from_RAM(sl, info.rom));
-+}
-+
- static ssize_t ext_power_show(struct device *device,
- struct device_attribute *attr, char *buf)
- {
-@@ -1172,12 +1257,11 @@ static int w1_read_temp(struct device *d
- {
- struct w1_slave *sl = dev_get_drvdata(device);
- struct therm_info info;
-- u8 fid = sl->family->fid;
- int ret;
-
- switch (attr) {
- case hwmon_temp_input:
-- ret = read_therm(device, sl, &info);
-+ ret = convert_t(sl, &info);
- if (ret)
- return ret;
-
-@@ -1186,7 +1270,7 @@ static int w1_read_temp(struct device *d
- return ret;
- }
-
-- *val = w1_convert_temp(info.rom, fid);
-+ *val = temperature_from_RAM(sl, info.rom);
- ret = 0;
- break;
- default: