diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch | 149 |
1 files changed, 0 insertions, 149 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch b/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch deleted file mode 100644 index 9881f81de4..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch +++ /dev/null @@ -1,149 +0,0 @@ -From dfc9fd0060f9103ca1f9335d529401ee8a105737 Mon Sep 17 00:00:00 2001 -From: Akira Shimahara <akira215corp@gmail.com> -Date: Mon, 11 May 2020 22:36:10 +0200 -Subject: [PATCH] w1_therm: fix reset_select_slave during discovery - -commit c8ad65f6fbfdcb9b620674ef456020eef2bfeb36 upstream. - -Fix reset_select_slave issue during devices discovery by the master on -bus. The w1_reset_select_slave() from w1_io.c, which was previously used, -assume that if the slave count is 1 there is only one slave attached on -the bus. This is not always true. For example when discovering devices, -when the first device is discover by the bus master, its slave count is -1, but some other slaves may be on the bus. - -In that case instead of adressing command to the attached slave the -master throw a SKIP ROM command so that all slaves attached on the bus -will answer simultenaously causing data collision. - -A dedicated reset_select_slave() function is implemented here, -it always perform an adressing to each slave using the MATCH ROM -command. - -Signed-off-by: Akira Shimahara <akira215corp@gmail.com> -Link: https://lore.kernel.org/r/20200511203610.409975-1-akira215corp@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/w1/slaves/w1_therm.c | 48 ++++++++++++++++++++++++++++++------ - 1 file changed, 41 insertions(+), 7 deletions(-) - ---- a/drivers/w1/slaves/w1_therm.c -+++ b/drivers/w1/slaves/w1_therm.c -@@ -16,6 +16,7 @@ - #include <linux/slab.h> - #include <linux/delay.h> - #include <linux/hwmon.h> -+#include <linux/string.h> - - #include <linux/w1.h> - -@@ -90,6 +91,24 @@ struct therm_info { - u8 verdict; - }; - -+/* Hardware Functions declaration */ -+ -+/** -+ * reset_select_slave() - reset and select a slave -+ * @sl: the slave to select -+ * -+ * Resets the bus and select the slave by sending a ROM MATCH cmd -+ * w1_reset_select_slave() from w1_io.c could not be used here because -+ * it sent a SKIP ROM command if only one device is on the line. -+ * At the beginning of the such process, sl->master->slave_count is 1 even if -+ * more devices are on the line, causing collision on the line. -+ * -+ * Context: The w1 master lock must be held. -+ * -+ * Return: 0 if success, negative kernel error code otherwise. -+ */ -+static int reset_select_slave(struct w1_slave *sl); -+ - /* Sysfs interface declaration */ - - static ssize_t w1_slave_show(struct device *device, -@@ -301,7 +320,7 @@ static inline int w1_DS18B20_precision(s - while (max_trying--) { - crc = 0; - -- if (!w1_reset_select_slave(sl)) { -+ if (!reset_select_slave(sl)) { - int count = 0; - - /* read values to only alter precision bits */ -@@ -314,7 +333,7 @@ static inline int w1_DS18B20_precision(s - if (rom[8] == crc) { - rom[4] = (rom[4] & ~mask) | (precision_bits & mask); - -- if (!w1_reset_select_slave(sl)) { -+ if (!reset_select_slave(sl)) { - w1_write_8(dev, W1_WRITE_SCRATCHPAD); - w1_write_8(dev, rom[2]); - w1_write_8(dev, rom[3]); -@@ -460,6 +479,21 @@ static void w1_therm_remove_slave(struct - - /* Hardware Functions */ - -+/* Safe version of reset_select_slave - avoid using the one in w_io.c */ -+static int reset_select_slave(struct w1_slave *sl) -+{ -+ u8 match[9] = { W1_MATCH_ROM, }; -+ u64 rn = le64_to_cpu(*((u64 *)&sl->reg_num)); -+ -+ if (w1_reset_bus(sl->master)) -+ return -ENODEV; -+ -+ memcpy(&match[1], &rn, 8); -+ w1_write_block(sl->master, match, 9); -+ -+ return 0; -+} -+ - static ssize_t read_therm(struct device *device, - struct w1_slave *sl, struct therm_info *info) - { -@@ -487,7 +521,7 @@ static ssize_t read_therm(struct device - info->verdict = 0; - info->crc = 0; - -- if (!w1_reset_select_slave(sl)) { -+ if (!reset_select_slave(sl)) { - int count = 0; - unsigned int tm = 750; - unsigned long sleep_rem; -@@ -495,7 +529,7 @@ static ssize_t read_therm(struct device - w1_write_8(dev, W1_READ_PSUPPLY); - external_power = w1_read_8(dev); - -- if (w1_reset_select_slave(sl)) -+ if (reset_select_slave(sl)) - continue; - - /* 750ms strong pullup (or delay) after the convert */ -@@ -525,7 +559,7 @@ static ssize_t read_therm(struct device - } - } - -- if (!w1_reset_select_slave(sl)) { -+ if (!reset_select_slave(sl)) { - - w1_write_8(dev, W1_READ_SCRATCHPAD); - count = w1_read_block(dev, info->rom, 9); -@@ -577,7 +611,7 @@ static inline int w1_therm_eeprom(struct - memset(rom, 0, sizeof(rom)); - - while (max_trying--) { -- if (!w1_reset_select_slave(sl)) { -+ if (!reset_select_slave(sl)) { - unsigned int tm = 10; - unsigned long sleep_rem; - -@@ -585,7 +619,7 @@ static inline int w1_therm_eeprom(struct - w1_write_8(dev, W1_READ_PSUPPLY); - external_power = w1_read_8(dev); - -- if (w1_reset_select_slave(sl)) -+ if (reset_select_slave(sl)) - continue; - - /* 10ms strong pullup/delay after the copy command */ |