diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch | 293 |
1 files changed, 0 insertions, 293 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch deleted file mode 100644 index b2e8195b64..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch +++ /dev/null @@ -1,293 +0,0 @@ -From 5737e27d3c5e2f743421e68f926c05e8581ae21f Mon Sep 17 00:00:00 2001 -From: Akira Shimahara <akira215corp@gmail.com> -Date: Mon, 11 May 2020 22:36:50 +0200 -Subject: [PATCH] w1_therm: adding ext_power sysfs entry - -commit b7bb6ca17a90f47c2fe2848531b5bbaf27a65ba7 upstream. - -Adding ext_power sysfs entry (RO). Return the power status of the device: - - 0: device parasite powered - - 1: device externally powered - - xx: xx is kernel error - -The power status of each device is check when the device is -discover by the bus master, in 'w1_therm_add_slave(struct w1_slave *)'. -The status is stored in the device structure w1_therm_family_data so -that the driver always knows the power state of each device, which could -be used later to determine the required strong pull up to apply on the -line. - -The power status is re evaluate each time the sysfs ext_power read by -a user. - -The hardware function 'read_powermode(struct w1_slave *sl)' act just as -per device specifications, sending W1_READ_PSUPPLY command on the bus, -and issue a read time slot, reading only one bit. - -A helper function 'bool bus_mutex_lock(struct mutex *lock)' is introduced. -It try to aquire the bus mutex several times (W1_THERM_MAX_TRY), waiting -W1_THERM_RETRY_DELAY between two attempt. - -Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly. - -Signed-off-by: Akira Shimahara <akira215corp@gmail.com> -Link: https://lore.kernel.org/r/20200511203650.410439-1-akira215corp@gmail.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - .../ABI/testing/sysfs-driver-w1_therm | 29 ++++ - drivers/w1/slaves/w1_therm.c | 137 ++++++++++++++++++ - 2 files changed, 166 insertions(+) - create mode 100644 Documentation/ABI/testing/sysfs-driver-w1_therm - ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-driver-w1_therm -@@ -0,0 +1,29 @@ -+What: /sys/bus/w1/devices/.../ext_power -+Date: May 2020 -+Contact: Akira Shimahara <akira215corp@gmail.com> -+Description: -+ (RO) return the power status by asking the device -+ * '0': device parasite powered -+ * '1': device externally powered -+ * '-xx': xx is kernel error when reading power status -+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> -+Description: -+ (RW) return the temperature in 1/1000 degC. -+ *read*: return 2 lines with the hexa output data sent on the -+ bus, return the CRC check and temperature in 1/1000 degC -+ *write* : -+ * '0' : save the 2 or 3 bytes to the device EEPROM -+ (i.e. TH, TL and config register) -+ * '9..12' : set the device resolution in RAM -+ (if supported) -+ * Anything else: do nothing -+ refer to Documentation/w1/slaves/w1_therm.rst for detailed -+ information. -+Users: any user space application which wants to communicate with -+ w1_term device -\ No newline at end of file ---- a/drivers/w1/slaves/w1_therm.c -+++ b/drivers/w1/slaves/w1_therm.c -@@ -43,8 +43,21 @@ - static int w1_strong_pullup = 1; - module_param_named(strong_pullup, w1_strong_pullup, int, 0); - -+/* Nb of try for an operation */ -+#define W1_THERM_MAX_TRY 5 -+ -+/* ms delay to retry bus mutex */ -+#define W1_THERM_RETRY_DELAY 20 -+ - /* Helpers Macros */ - -+/* -+ * return the power mode of the sl slave : 1-ext, 0-parasite, <0 unknown -+ * always test family data existence before using this macro -+ */ -+#define SLAVE_POWERMODE(sl) \ -+ (((struct w1_therm_family_data *)(sl->family_data))->external_powered) -+ - /* return the address of the refcnt in the family data */ - #define THERM_REFCNT(family_data) \ - (&((struct w1_therm_family_data *)family_data)->refcnt) -@@ -73,10 +86,14 @@ struct w1_therm_family_converter { - * struct w1_therm_family_data - device data - * @rom: ROM device id (64bit Lasered ROM code + 1 CRC byte) - * @refcnt: ref count -+ * @external_powered: 1 device powered externally, -+ * 0 device parasite powered, -+ * -x error or undefined - */ - struct w1_therm_family_data { - uint8_t rom[9]; - atomic_t refcnt; -+ int external_powered; - }; - - /** -@@ -109,6 +126,20 @@ struct therm_info { - */ - static int reset_select_slave(struct w1_slave *sl); - -+/** -+ * read_powermode() - Query the power mode of the slave -+ * @sl: slave to retrieve the power mode -+ * -+ * Ask the device to get its power mode (external or parasite) -+ * and store the power status in the &struct w1_therm_family_data. -+ * -+ * Return: -+ * * 0 parasite powered device -+ * * 1 externally powered device -+ * * <0 kernel error code -+ */ -+static int read_powermode(struct w1_slave *sl); -+ - /* Sysfs interface declaration */ - - static ssize_t w1_slave_show(struct device *device, -@@ -120,10 +151,14 @@ 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 ext_power_show(struct device *device, -+ struct device_attribute *attr, char *buf); -+ - /* Attributes declarations */ - - static DEVICE_ATTR_RW(w1_slave); - static DEVICE_ATTR_RO(w1_seq); -+static DEVICE_ATTR_RO(ext_power); - - /* Interface Functions declaration */ - -@@ -151,12 +186,14 @@ static void w1_therm_remove_slave(struct - - static struct attribute *w1_therm_attrs[] = { - &dev_attr_w1_slave.attr, -+ &dev_attr_ext_power.attr, - NULL, - }; - - static struct attribute *w1_ds28ea00_attrs[] = { - &dev_attr_w1_slave.attr, - &dev_attr_w1_seq.attr, -+ &dev_attr_ext_power.attr, - NULL, - }; - -@@ -433,6 +470,34 @@ static struct w1_therm_family_converter - /* Helpers Functions */ - - /** -+ * bus_mutex_lock() - Acquire the mutex -+ * @lock: w1 bus mutex to acquire -+ * -+ * It try to acquire the mutex W1_THERM_MAX_TRY times and wait -+ * W1_THERM_RETRY_DELAY between 2 attempts. -+ * -+ * Return: true is mutex is acquired and lock, false otherwise -+ */ -+static inline bool bus_mutex_lock(struct mutex *lock) -+{ -+ int max_trying = W1_THERM_MAX_TRY; -+ -+ /* try to acquire the mutex, if not, sleep retry_delay before retry) */ -+ while (mutex_lock_interruptible(lock) != 0 && max_trying > 0) { -+ unsigned long sleep_rem; -+ -+ sleep_rem = msleep_interruptible(W1_THERM_RETRY_DELAY); -+ if (!sleep_rem) -+ max_trying--; -+ } -+ -+ if (!max_trying) -+ return false; /* Didn't acquire the bus mutex */ -+ -+ return true; -+} -+ -+/** - * w1_convert_temp() - temperature conversion binding function - * @rom: data read from device RAM (8 data bytes + 1 CRC byte) - * @fid: device family id -@@ -461,7 +526,19 @@ static int w1_therm_add_slave(struct w1_ - GFP_KERNEL); - if (!sl->family_data) - return -ENOMEM; -+ - atomic_set(THERM_REFCNT(sl->family_data), 1); -+ -+ /* Getting the power mode of the device {external, parasite} */ -+ SLAVE_POWERMODE(sl) = read_powermode(sl); -+ -+ if (SLAVE_POWERMODE(sl) < 0) { -+ /* no error returned as device has been added */ -+ dev_warn(&sl->dev, -+ "%s: Device has been added, but power_mode may be corrupted. err=%d\n", -+ __func__, SLAVE_POWERMODE(sl)); -+ } -+ - return 0; - } - -@@ -661,6 +738,44 @@ error: - return ret; - } - -+static int read_powermode(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 < 0)) { -+ /* safe version to select slave */ -+ if (!reset_select_slave(sl)) { -+ w1_write_8(dev_master, W1_READ_PSUPPLY); -+ /* -+ * Emit a read time slot and read only one bit, -+ * 1 is externally powered, -+ * 0 is parasite powered -+ */ -+ ret = w1_touch_bit(dev_master, 1); -+ /* ret should be either 1 either 0 */ -+ } -+ } -+ mutex_unlock(&dev_master->bus_mutex); -+ -+dec_refcnt: -+ atomic_dec(THERM_REFCNT(sl->family_data)); -+error: -+ return ret; -+} -+ - /* Sysfs Interface definition */ - - static ssize_t w1_slave_show(struct device *device, -@@ -722,6 +837,28 @@ static ssize_t w1_slave_store(struct dev - return ret ? : size; - } - -+static ssize_t ext_power_show(struct device *device, -+ struct device_attribute *attr, char *buf) -+{ -+ struct w1_slave *sl = dev_to_w1_slave(device); -+ -+ if (!sl->family_data) { -+ dev_info(device, -+ "%s: Device not supported by the driver\n", __func__); -+ return 0; /* No device family */ -+ } -+ -+ /* Getting the power mode of the device {external, parasite} */ -+ SLAVE_POWERMODE(sl) = read_powermode(sl); -+ -+ if (SLAVE_POWERMODE(sl) < 0) { -+ dev_dbg(device, -+ "%s: Power_mode may be corrupted. err=%d\n", -+ __func__, SLAVE_POWERMODE(sl)); -+ } -+ return sprintf(buf, "%d\n", SLAVE_POWERMODE(sl)); -+} -+ - #if IS_REACHABLE(CONFIG_HWMON) - static int w1_read_temp(struct device *device, u32 attr, int channel, - long *val) |