diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch | 372 |
1 files changed, 0 insertions, 372 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch deleted file mode 100644 index 58467a00c3..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch +++ /dev/null @@ -1,372 +0,0 @@ -From 855a8d82506c7c2428e13beebe8dbf7739ea6176 Mon Sep 17 00:00:00 2001 -From: Akira Shimahara <akira215corp@gmail.com> -Date: Mon, 11 May 2020 22:37:25 +0200 -Subject: [PATCH] w1_therm: adding eeprom sysfs entry - -commit 45d457a4cf24455eefd076a01a3d86414fc2ff1e upstream. - -The driver implement 2 hardware functions to access device RAM: - * copy_scratchpad - * recall_scratchpad -They act according to device specifications. - -As EEPROM operations are not device dependent (all w1_therm can perform -EEPROM read/write operation following the same protocol), it is removed -from device families structures. - -Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly. - -Signed-off-by: Akira Shimahara <akira215corp@gmail.com> -Link: https://lore.kernel.org/r/20200511203725.410844-1-akira215corp@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - .../ABI/testing/sysfs-driver-w1_therm | 14 ++ - drivers/w1/slaves/w1_therm.c | 175 ++++++++++++------ - 2 files changed, 132 insertions(+), 57 deletions(-) - ---- a/Documentation/ABI/testing/sysfs-driver-w1_therm -+++ b/Documentation/ABI/testing/sysfs-driver-w1_therm -@@ -1,3 +1,17 @@ -+What: /sys/bus/w1/devices/.../eeprom -+Date: May 2020 -+Contact: Akira Shimahara <akira215corp@gmail.com> -+Description: -+ (WO) writing that file will either trigger a save of the -+ device data to its embedded EEPROM, either restore data -+ embedded in device EEPROM. Be aware that devices support -+ limited EEPROM writing cycles (typical 50k) -+ * 'save': save device RAM to EEPROM -+ * 'restore': restore EEPROM data in device RAM -+Users: any user space application which wants to communicate with -+ w1_term device -+ -+ - What: /sys/bus/w1/devices/.../ext_power - Date: May 2020 - Contact: Akira Shimahara <akira215corp@gmail.com> ---- a/drivers/w1/slaves/w1_therm.c -+++ b/drivers/w1/slaves/w1_therm.c -@@ -43,12 +43,21 @@ - static int w1_strong_pullup = 1; - module_param_named(strong_pullup, w1_strong_pullup, int, 0); - -+/* This command should be in public header w1.h but is not */ -+#define W1_RECALL_EEPROM 0xB8 -+ - /* Nb of try for an operation */ - #define W1_THERM_MAX_TRY 5 - - /* ms delay to retry bus mutex */ - #define W1_THERM_RETRY_DELAY 20 - -+/* delay in ms to write in EEPROM */ -+#define W1_THERM_EEPROM_WRITE_DELAY 10 -+ -+#define EEPROM_CMD_WRITE "save" /* cmd for write eeprom sysfs */ -+#define EEPROM_CMD_READ "restore" /* cmd for read eeprom sysfs */ -+ - /* Helpers Macros */ - - /* -@@ -86,7 +95,6 @@ module_param_named(strong_pullup, w1_str - * @convert: pointer to the device conversion function - * @set_resolution: pointer to the device set_resolution function - * @get_resolution: pointer to the device get_resolution function -- * @eeprom: pointer to eeprom function - */ - struct w1_therm_family_converter { - u8 broken; -@@ -95,7 +103,6 @@ struct w1_therm_family_converter { - int (*convert)(u8 rom[9]); - int (*set_resolution)(struct w1_slave *sl, int val); - int (*get_resolution)(struct w1_slave *sl); -- int (*eeprom)(struct device *device); - }; - - /** -@@ -166,6 +173,22 @@ static int read_scratchpad(struct w1_sla - static int write_scratchpad(struct w1_slave *sl, const u8 *data, u8 nb_bytes); - - /** -+ * copy_scratchpad() - Copy the content of scratchpad in device EEPROM -+ * @sl: slave involved -+ * -+ * Return: 0 if success, -kernel error code otherwise -+ */ -+static int copy_scratchpad(struct w1_slave *sl); -+ -+/** -+ * recall_eeprom() - Restore EEPROM data to device RAM -+ * @sl: slave involved -+ * -+ * Return: 0 if success, -kernel error code otherwise -+ */ -+static int recall_eeprom(struct w1_slave *sl); -+ -+/** - * read_powermode() - Query the power mode of the slave - * @sl: slave to retrieve the power mode - * -@@ -199,12 +222,16 @@ static ssize_t resolution_show(struct de - static ssize_t resolution_store(struct device *device, - struct device_attribute *attr, const char *buf, size_t size); - -+static ssize_t eeprom_store(struct device *device, -+ struct device_attribute *attr, const char *buf, size_t size); -+ - /* Attributes declarations */ - - static DEVICE_ATTR_RW(w1_slave); - static DEVICE_ATTR_RO(w1_seq); - static DEVICE_ATTR_RO(ext_power); - static DEVICE_ATTR_RW(resolution); -+static DEVICE_ATTR_WO(eeprom); - - /* Interface Functions declaration */ - -@@ -234,12 +261,14 @@ static struct attribute *w1_therm_attrs[ - &dev_attr_w1_slave.attr, - &dev_attr_ext_power.attr, - &dev_attr_resolution.attr, -+ &dev_attr_eeprom.attr, - NULL, - }; - - static struct attribute *w1_ds18s20_attrs[] = { - &dev_attr_w1_slave.attr, - &dev_attr_ext_power.attr, -+ &dev_attr_eeprom.attr, - NULL, - }; - -@@ -248,6 +277,7 @@ static struct attribute *w1_ds28ea00_att - &dev_attr_w1_seq.attr, - &dev_attr_ext_power.attr, - &dev_attr_resolution.attr, -+ &dev_attr_eeprom.attr, - NULL, - }; - -@@ -359,9 +389,6 @@ static struct w1_family w1_therm_family_ - - /* Device dependent func */ - --/* write configuration to eeprom */ --static inline int w1_therm_eeprom(struct device *device); -- - static inline int w1_DS18B20_write_data(struct w1_slave *sl, - const u8 *data) - { -@@ -477,35 +504,30 @@ static struct w1_therm_family_converter - .convert = w1_DS18S20_convert_temp, - .set_resolution = NULL, /* no config register */ - .get_resolution = NULL, /* no config register */ -- .eeprom = w1_therm_eeprom - }, - { - .f = &w1_therm_family_DS1822, - .convert = w1_DS18B20_convert_temp, - .set_resolution = w1_DS18B20_set_resolution, - .get_resolution = w1_DS18B20_get_resolution, -- .eeprom = w1_therm_eeprom - }, - { - .f = &w1_therm_family_DS18B20, - .convert = w1_DS18B20_convert_temp, - .set_resolution = w1_DS18B20_set_resolution, - .get_resolution = w1_DS18B20_get_resolution, -- .eeprom = w1_therm_eeprom - }, - { - .f = &w1_therm_family_DS28EA00, - .convert = w1_DS18B20_convert_temp, - .set_resolution = w1_DS18B20_set_resolution, - .get_resolution = w1_DS18B20_get_resolution, -- .eeprom = w1_therm_eeprom - }, - { - .f = &w1_therm_family_DS1825, - .convert = w1_DS18B20_convert_temp, - .set_resolution = w1_DS18B20_set_resolution, - .get_resolution = w1_DS18B20_get_resolution, -- .eeprom = w1_therm_eeprom - } - }; - -@@ -838,75 +860,94 @@ error: - return ret; - } - --static inline int w1_therm_eeprom(struct device *device) -+static int copy_scratchpad(struct w1_slave *sl) - { -- struct w1_slave *sl = dev_to_w1_slave(device); -- struct w1_master *dev = sl->master; -- u8 rom[9], 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_write, ret = -ENODEV; -+ bool strong_pullup; - -- if (!sl->family_data) { -- ret = -ENODEV; -+ if (!sl->family_data) - goto error; -- } -+ -+ t_write = W1_THERM_EEPROM_WRITE_DELAY; -+ strong_pullup = (w1_strong_pullup == 2 || -+ (!SLAVE_POWERMODE(sl) && -+ w1_strong_pullup)); - - /* prevent the slave from going away in sleep */ -- atomic_inc(THERM_REFCNT(family_data)); -+ atomic_inc(THERM_REFCNT(sl->family_data)); - -- ret = mutex_lock_interruptible(&dev->bus_mutex); -- if (ret != 0) -+ if (!bus_mutex_lock(&dev_master->bus_mutex)) { -+ ret = -EAGAIN; /* Didn't acquire the mutex */ - goto dec_refcnt; -+ } - -- memset(rom, 0, sizeof(rom)); -- -- while (max_trying--) { -+ while (max_trying-- && ret) { /* ret should be 0 */ -+ /* safe version to select slave */ - if (!reset_select_slave(sl)) { -- unsigned int tm = 10; - unsigned long sleep_rem; - -- /* check if in parasite mode */ -- w1_write_8(dev, W1_READ_PSUPPLY); -- external_power = w1_read_8(dev); -- -- if (reset_select_slave(sl)) -- continue; -- -- /* 10ms strong pullup/delay after the copy command */ -- if (w1_strong_pullup == 2 || -- (!external_power && w1_strong_pullup)) -- w1_next_pullup(dev, tm); -- -- w1_write_8(dev, W1_COPY_SCRATCHPAD); -- -- if (external_power) { -- mutex_unlock(&dev->bus_mutex); -+ /* 10ms strong pullup (or delay) after the convert */ -+ if (strong_pullup) -+ w1_next_pullup(dev_master, t_write); - -- sleep_rem = msleep_interruptible(tm); -- if (sleep_rem != 0) { -- ret = -EINTR; -- goto dec_refcnt; -- } -+ w1_write_8(dev_master, W1_COPY_SCRATCHPAD); - -- ret = mutex_lock_interruptible(&dev->bus_mutex); -- if (ret != 0) -- goto dec_refcnt; -- } else if (!w1_strong_pullup) { -- sleep_rem = msleep_interruptible(tm); -+ if (strong_pullup) { -+ sleep_rem = msleep_interruptible(t_write); - if (sleep_rem != 0) { - ret = -EINTR; - goto mt_unlock; - } - } -- -- break; -+ ret = 0; - } -+ - } - - 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; -+} -+ -+static int recall_eeprom(struct w1_slave *sl) -+{ -+ struct w1_master *dev_master = sl->master; -+ int max_trying = W1_THERM_MAX_TRY; -+ int ret = -ENODEV; -+ -+ if (!sl->family_data) -+ goto error; -+ -+ /* 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 */ -+ /* safe version to select slave */ -+ if (!reset_select_slave(sl)) { -+ -+ w1_write_8(dev_master, W1_RECALL_EEPROM); -+ -+ ret = 1; /* Slave will pull line to 0 */ -+ while (ret) -+ ret = 1 - w1_touch_bit(dev_master, 1); -+ } -+ -+ } -+ -+ mutex_unlock(&dev_master->bus_mutex); -+ -+dec_refcnt: -+ atomic_dec(THERM_REFCNT(sl->family_data)); - error: - return ret; - } -@@ -1006,7 +1047,7 @@ static ssize_t w1_slave_store(struct dev - } - - if (val == 0) /* val=0 : trigger a EEPROM save */ -- ret = SLAVE_SPECIFIC_FUNC(sl)->eeprom(device); -+ ret = copy_scratchpad(sl); - else { - if (SLAVE_SPECIFIC_FUNC(sl)->set_resolution) - ret = SLAVE_SPECIFIC_FUNC(sl)->set_resolution(sl, val); -@@ -1104,6 +1145,26 @@ static ssize_t resolution_store(struct d - - return size; - } -+ -+static ssize_t eeprom_store(struct device *device, -+ struct device_attribute *attr, const char *buf, size_t size) -+{ -+ struct w1_slave *sl = dev_to_w1_slave(device); -+ int ret = -EINVAL; /* Invalid argument */ -+ -+ if (size == sizeof(EEPROM_CMD_WRITE)) { -+ if (!strncmp(buf, EEPROM_CMD_WRITE, sizeof(EEPROM_CMD_WRITE)-1)) -+ ret = copy_scratchpad(sl); -+ } else if (size == sizeof(EEPROM_CMD_READ)) { -+ if (!strncmp(buf, EEPROM_CMD_READ, sizeof(EEPROM_CMD_READ)-1)) -+ ret = recall_eeprom(sl); -+ } -+ -+ if (ret) -+ dev_info(device, "%s: error in process %d\n", __func__, ret); -+ -+ return size; -+} - - #if IS_REACHABLE(CONFIG_HWMON) - static int w1_read_temp(struct device *device, u32 attr, int channel, |