Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (bt1-pvt) Test sensor power supply on probe

Baikal-T1 PVT sensor has got a dedicated power supply domain (feed up by
the external GPVT/VPVT_18 pins). In case if it isn't powered up, the
registers will be accessible, but the sensor conversion just won't happen.
Due to that an attempt to read data from any PVT sensor will cause the
task hanging up. For instance that will happen if XP11 jumper isn't
installed on the Baikal-T1-based BFK3.1 board. Let's at least test whether
the conversion work on the device probe procedure. By doing so will make
sure that the PVT sensor is powered up at least at boot time.

Fixes: 87976ce2825d ("hwmon: Add Baikal-T1 PVT sensor driver")
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Link: https://lore.kernel.org/r/20200920110924.19741-2-Sergey.Semin@baikalelectronics.ru
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Serge Semin and committed by
Guenter Roeck
a6db1561 707d151b

+40
+40
drivers/hwmon/bt1-pvt.c
··· 13 13 #include <linux/bitops.h> 14 14 #include <linux/clk.h> 15 15 #include <linux/completion.h> 16 + #include <linux/delay.h> 16 17 #include <linux/device.h> 17 18 #include <linux/hwmon-sysfs.h> 18 19 #include <linux/hwmon.h> ··· 983 982 return 0; 984 983 } 985 984 985 + static int pvt_check_pwr(struct pvt_hwmon *pvt) 986 + { 987 + unsigned long tout; 988 + int ret = 0; 989 + u32 data; 990 + 991 + /* 992 + * Test out the sensor conversion functionality. If it is not done on 993 + * time then the domain must have been unpowered and we won't be able 994 + * to use the device later in this driver. 995 + * Note If the power source is lost during the normal driver work the 996 + * data read procedure will either return -ETIMEDOUT (for the 997 + * alarm-less driver configuration) or just stop the repeated 998 + * conversion. In the later case alas we won't be able to detect the 999 + * problem. 1000 + */ 1001 + pvt_update(pvt->regs + PVT_INTR_MASK, PVT_INTR_ALL, PVT_INTR_ALL); 1002 + pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, PVT_CTRL_EN); 1003 + pvt_set_tout(pvt, 0); 1004 + readl(pvt->regs + PVT_DATA); 1005 + 1006 + tout = PVT_TOUT_MIN / NSEC_PER_USEC; 1007 + usleep_range(tout, 2 * tout); 1008 + 1009 + data = readl(pvt->regs + PVT_DATA); 1010 + if (!(data & PVT_DATA_VALID)) { 1011 + ret = -ENODEV; 1012 + dev_err(pvt->dev, "Sensor is powered down\n"); 1013 + } 1014 + 1015 + pvt_update(pvt->regs + PVT_CTRL, PVT_CTRL_EN, 0); 1016 + 1017 + return ret; 1018 + } 1019 + 986 1020 static void pvt_init_iface(struct pvt_hwmon *pvt) 987 1021 { 988 1022 u32 trim, temp; ··· 1142 1106 return ret; 1143 1107 1144 1108 ret = pvt_request_clks(pvt); 1109 + if (ret) 1110 + return ret; 1111 + 1112 + ret = pvt_check_pwr(pvt); 1145 1113 if (ret) 1146 1114 return ret; 1147 1115