aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2018-07-17 05:24:34 -0400
committerJon Mason <jdmason@kudzu.us>2018-11-01 10:33:12 -0400
commit40070408f54e76896d75ddccaabdd0c0714600f1 (patch)
tree08f17cf8deb2a95e4fa9d42971e616ed998752df /drivers
parent906e86b22dba61cb1baaed9be7fdcbf0afd74d7b (diff)
ntb: idt: Alter temperature read method
In order to create a hwmon interface for the IDT PCIe-switch temperature sensor the already available reader method should be improved. Particularly we need to redesign it so one would be able to read temperature/offset values from registers of the passed types. Since IDT sensor interface provides temperature in unsigned format 0:7:1 (7 bits for real value and one for fraction) we also need to have helpers for the typical sysfs temperature data type conversion to and from this format. Even though the IDT PCIe-switch provided temperature offset got the same but signed type it can be translated by these methods too. Signed-off-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Jon Mason <jdmason@kudzu.us>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ntb/hw/idt/ntb_hw_idt.c113
-rw-r--r--drivers/ntb/hw/idt/ntb_hw_idt.h56
2 files changed, 152 insertions, 17 deletions
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c
index 54485a8d2d7f..adb71f7c1043 100644
--- a/drivers/ntb/hw/idt/ntb_hw_idt.c
+++ b/drivers/ntb/hw/idt/ntb_hw_idt.c
@@ -1829,22 +1829,99 @@ static int idt_ntb_peer_msg_write(struct ntb_dev *ntb, int pidx, int midx,
1829 */ 1829 */
1830 1830
1831/* 1831/*
1832 * idt_get_deg() - convert millidegree Celsius value to just degree
1833 * @mdegC: IN - millidegree Celsius value
1834 *
1835 * Return: Degree corresponding to the passed millidegree value
1836 */
1837static inline s8 idt_get_deg(long mdegC)
1838{
1839 return mdegC / 1000;
1840}
1841
1842/*
1843 * idt_get_frac() - retrieve 0/0.5 fraction of the millidegree Celsius value
1844 * @mdegC: IN - millidegree Celsius value
1845 *
1846 * Return: 0/0.5 degree fraction of the passed millidegree value
1847 */
1848static inline u8 idt_get_deg_frac(long mdegC)
1849{
1850 return (mdegC % 1000) >= 500 ? 5 : 0;
1851}
1852
1853/*
1854 * idt_get_temp_fmt() - convert millidegree Celsius value to 0:7:1 format
1855 * @mdegC: IN - millidegree Celsius value
1856 *
1857 * Return: 0:7:1 format acceptable by the IDT temperature sensor
1858 */
1859static inline u8 idt_temp_get_fmt(long mdegC)
1860{
1861 return (idt_get_deg(mdegC) << 1) | (idt_get_deg_frac(mdegC) ? 1 : 0);
1862}
1863
1864/*
1865 * idt_get_temp_sval() - convert temp sample to signed millidegree Celsius
1866 * @data: IN - shifted to LSB 8-bits temperature sample
1867 *
1868 * Return: signed millidegree Celsius
1869 */
1870static inline long idt_get_temp_sval(u32 data)
1871{
1872 return ((s8)data / 2) * 1000 + (data & 0x1 ? 500 : 0);
1873}
1874
1875/*
1876 * idt_get_temp_sval() - convert temp sample to unsigned millidegree Celsius
1877 * @data: IN - shifted to LSB 8-bits temperature sample
1878 *
1879 * Return: unsigned millidegree Celsius
1880 */
1881static inline long idt_get_temp_uval(u32 data)
1882{
1883 return (data / 2) * 1000 + (data & 0x1 ? 500 : 0);
1884}
1885
1886/*
1832 * idt_read_temp() - read temperature from chip sensor 1887 * idt_read_temp() - read temperature from chip sensor
1833 * @ntb: NTB device context. 1888 * @ntb: NTB device context.
1834 * @val: OUT - integer value of temperature 1889 * @type: IN - type of the temperature value to read
1835 * @frac: OUT - fraction 1890 * @val: OUT - integer value of temperature in millidegree Celsius
1836 */ 1891 */
1837static void idt_read_temp(struct idt_ntb_dev *ndev, unsigned char *val, 1892static void idt_read_temp(struct idt_ntb_dev *ndev,
1838 unsigned char *frac) 1893 const enum idt_temp_val type, long *val)
1839{ 1894{
1840 u32 data; 1895 u32 data;
1841 1896
1842 /* Read the data from TEMP field of the TMPSTS register */ 1897 /* Alter the temperature field in accordance with the passed type */
1843 data = idt_sw_read(ndev, IDT_SW_TMPSTS); 1898 switch (type) {
1844 data = GET_FIELD(TMPSTS_TEMP, data); 1899 case IDT_TEMP_CUR:
1845 /* TEMP field has one fractional bit and seven integer bits */ 1900 data = GET_FIELD(TMPSTS_TEMP,
1846 *val = data >> 1; 1901 idt_sw_read(ndev, IDT_SW_TMPSTS));
1847 *frac = ((data & 0x1) ? 5 : 0); 1902 break;
1903 case IDT_TEMP_LOW:
1904 data = GET_FIELD(TMPSTS_LTEMP,
1905 idt_sw_read(ndev, IDT_SW_TMPSTS));
1906 break;
1907 case IDT_TEMP_HIGH:
1908 data = GET_FIELD(TMPSTS_HTEMP,
1909 idt_sw_read(ndev, IDT_SW_TMPSTS));
1910 break;
1911 case IDT_TEMP_OFFSET:
1912 /* This is the only field with signed 0:7:1 format */
1913 data = GET_FIELD(TMPADJ_OFFSET,
1914 idt_sw_read(ndev, IDT_SW_TMPADJ));
1915 *val = idt_get_temp_sval(data);
1916 return;
1917 default:
1918 data = GET_FIELD(TMPSTS_TEMP,
1919 idt_sw_read(ndev, IDT_SW_TMPSTS));
1920 break;
1921 }
1922
1923 /* The rest of the fields accept unsigned 0:7:1 format */
1924 *val = idt_get_temp_uval(data);
1848} 1925}
1849 1926
1850/* 1927/*
@@ -1860,10 +1937,10 @@ static void idt_read_temp(struct idt_ntb_dev *ndev, unsigned char *val,
1860 */ 1937 */
1861static void idt_temp_isr(struct idt_ntb_dev *ndev, u32 ntint_sts) 1938static void idt_temp_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1862{ 1939{
1863 unsigned char val, frac; 1940 unsigned long mdeg;
1864 1941
1865 /* Read the current temperature value */ 1942 /* Read the current temperature value */
1866 idt_read_temp(ndev, &val, &frac); 1943 idt_read_temp(ndev, IDT_TEMP_CUR, &mdeg);
1867 1944
1868 /* Read the temperature alarm to clean the alarm status out */ 1945 /* Read the temperature alarm to clean the alarm status out */
1869 /*(void)idt_sw_read(ndev, IDT_SW_TMPALARM);*/ 1946 /*(void)idt_sw_read(ndev, IDT_SW_TMPALARM);*/
@@ -1875,7 +1952,8 @@ static void idt_temp_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1875 "Temp sensor IRQ detected %#08x", ntint_sts); 1952 "Temp sensor IRQ detected %#08x", ntint_sts);
1876 1953
1877 /* Print temperature value to log */ 1954 /* Print temperature value to log */
1878 dev_warn(&ndev->ntb.pdev->dev, "Temperature %hhu.%hhu", val, frac); 1955 dev_warn(&ndev->ntb.pdev->dev, "Temperature %hhd.%hhuC",
1956 idt_get_deg(mdeg), idt_get_deg_frac(mdeg));
1879} 1957}
1880 1958
1881/*============================================================================= 1959/*=============================================================================
@@ -2123,9 +2201,9 @@ static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf,
2123 size_t count, loff_t *offp) 2201 size_t count, loff_t *offp)
2124{ 2202{
2125 struct idt_ntb_dev *ndev = filp->private_data; 2203 struct idt_ntb_dev *ndev = filp->private_data;
2126 unsigned char temp, frac, idx, pidx, cnt; 2204 unsigned char idx, pidx, cnt;
2205 unsigned long irqflags, mdeg;
2127 ssize_t ret = 0, off = 0; 2206 ssize_t ret = 0, off = 0;
2128 unsigned long irqflags;
2129 enum ntb_speed speed; 2207 enum ntb_speed speed;
2130 enum ntb_width width; 2208 enum ntb_width width;
2131 char *strbuf; 2209 char *strbuf;
@@ -2274,9 +2352,10 @@ static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf,
2274 off += scnprintf(strbuf + off, size - off, "\n"); 2352 off += scnprintf(strbuf + off, size - off, "\n");
2275 2353
2276 /* Current temperature */ 2354 /* Current temperature */
2277 idt_read_temp(ndev, &temp, &frac); 2355 idt_read_temp(ndev, IDT_TEMP_CUR, &mdeg);
2278 off += scnprintf(strbuf + off, size - off, 2356 off += scnprintf(strbuf + off, size - off,
2279 "Switch temperature\t\t- %hhu.%hhuC\n", temp, frac); 2357 "Switch temperature\t\t- %hhd.%hhuC\n",
2358 idt_get_deg(mdeg), idt_get_deg_frac(mdeg));
2280 2359
2281 /* Copy the buffer to the User Space */ 2360 /* Copy the buffer to the User Space */
2282 ret = simple_read_from_buffer(ubuf, count, offp, strbuf, off); 2361 ret = simple_read_from_buffer(ubuf, count, offp, strbuf, off);
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.h b/drivers/ntb/hw/idt/ntb_hw_idt.h
index 856fd182f6f4..9dfd6b11a621 100644
--- a/drivers/ntb/hw/idt/ntb_hw_idt.h
+++ b/drivers/ntb/hw/idt/ntb_hw_idt.h
@@ -886,12 +886,42 @@
886#define IDT_SWPxMSGCTL_PART_FLD 4 886#define IDT_SWPxMSGCTL_PART_FLD 4
887 887
888/* 888/*
889 * TMPCTL register fields related constants
890 * @IDT_TMPCTL_LTH_MASK: Low temperature threshold field mask
891 * @IDT_TMPCTL_LTH_FLD: Low temperature threshold field offset
892 * @IDT_TMPCTL_MTH_MASK: Middle temperature threshold field mask
893 * @IDT_TMPCTL_MTH_FLD: Middle temperature threshold field offset
894 * @IDT_TMPCTL_HTH_MASK: High temperature threshold field mask
895 * @IDT_TMPCTL_HTH_FLD: High temperature threshold field offset
896 * @IDT_TMPCTL_PDOWN: Temperature sensor power down
897 */
898#define IDT_TMPCTL_LTH_MASK 0x000000FFU
899#define IDT_TMPCTL_LTH_FLD 0
900#define IDT_TMPCTL_MTH_MASK 0x0000FF00U
901#define IDT_TMPCTL_MTH_FLD 8
902#define IDT_TMPCTL_HTH_MASK 0x00FF0000U
903#define IDT_TMPCTL_HTH_FLD 16
904#define IDT_TMPCTL_PDOWN 0x80000000U
905
906/*
889 * TMPSTS register fields related constants 907 * TMPSTS register fields related constants
890 * @IDT_TMPSTS_TEMP_MASK: Current temperature field mask 908 * @IDT_TMPSTS_TEMP_MASK: Current temperature field mask
891 * @IDT_TMPSTS_TEMP_FLD: Current temperature field offset 909 * @IDT_TMPSTS_TEMP_FLD: Current temperature field offset
892 */ 910 */
893#define IDT_TMPSTS_TEMP_MASK 0x000000FFU 911#define IDT_TMPSTS_TEMP_MASK 0x000000FFU
894#define IDT_TMPSTS_TEMP_FLD 0 912#define IDT_TMPSTS_TEMP_FLD 0
913#define IDT_TMPSTS_LTEMP_MASK 0x0000FF00U
914#define IDT_TMPSTS_LTEMP_FLD 8
915#define IDT_TMPSTS_HTEMP_MASK 0x00FF0000U
916#define IDT_TMPSTS_HTEMP_FLD 16
917
918/*
919 * TMPADJ register fields related constants
920 * @IDT_TMPADJ_OFFSET_MASK: Temperature value offset field mask
921 * @IDT_TMPADJ_OFFSET_FLD: Temperature value offset field offset
922 */
923#define IDT_TMPADJ_OFFSET_MASK 0x000000FFU
924#define IDT_TMPADJ_OFFSET_FLD 0
895 925
896/* 926/*
897 * Helper macro to get/set the corresponding field value 927 * Helper macro to get/set the corresponding field value
@@ -951,6 +981,32 @@
951#define IDT_DIR_SIZE_ALIGN 1 981#define IDT_DIR_SIZE_ALIGN 1
952 982
953/* 983/*
984 * IDT PCIe-switch temperature sensor value limits
985 * @IDT_TEMP_MIN_MDEG: Minimal integer value of temperature
986 * @IDT_TEMP_MAX_MDEG: Maximal integer value of temperature
987 * @IDT_TEMP_MIN_OFFSET:Minimal integer value of temperature offset
988 * @IDT_TEMP_MAX_OFFSET:Maximal integer value of temperature offset
989 */
990#define IDT_TEMP_MIN_MDEG 0
991#define IDT_TEMP_MAX_MDEG 127500
992#define IDT_TEMP_MIN_OFFSET -64000
993#define IDT_TEMP_MAX_OFFSET 63500
994
995/*
996 * Temperature sensor values enumeration
997 * @IDT_TEMP_CUR: Current temperature
998 * @IDT_TEMP_LOW: Lowest historical temperature
999 * @IDT_TEMP_HIGH: Highest historical temperature
1000 * @IDT_TEMP_OFFSET: Current temperature offset
1001 */
1002enum idt_temp_val {
1003 IDT_TEMP_CUR,
1004 IDT_TEMP_LOW,
1005 IDT_TEMP_HIGH,
1006 IDT_TEMP_OFFSET
1007};
1008
1009/*
954 * IDT Memory Windows type. Depending on the device settings, IDT supports 1010 * IDT Memory Windows type. Depending on the device settings, IDT supports
955 * Direct Address Translation MW registers and Lookup Table registers 1011 * Direct Address Translation MW registers and Lookup Table registers
956 * @IDT_MW_DIR: Direct address translation 1012 * @IDT_MW_DIR: Direct address translation