aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ntb/hw/idt/Kconfig1
-rw-r--r--drivers/ntb/hw/idt/ntb_hw_idt.c182
-rw-r--r--drivers/ntb/hw/idt/ntb_hw_idt.h24
3 files changed, 206 insertions, 1 deletions
diff --git a/drivers/ntb/hw/idt/Kconfig b/drivers/ntb/hw/idt/Kconfig
index b360e5613b9f..2ed147368fa8 100644
--- a/drivers/ntb/hw/idt/Kconfig
+++ b/drivers/ntb/hw/idt/Kconfig
@@ -1,6 +1,7 @@
1config NTB_IDT 1config NTB_IDT
2 tristate "IDT PCIe-switch Non-Transparent Bridge support" 2 tristate "IDT PCIe-switch Non-Transparent Bridge support"
3 depends on PCI 3 depends on PCI
4 select HWMON
4 help 5 help
5 This driver supports NTB of cappable IDT PCIe-switches. 6 This driver supports NTB of cappable IDT PCIe-switches.
6 7
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c
index adb71f7c1043..19425a2c60cd 100644
--- a/drivers/ntb/hw/idt/ntb_hw_idt.c
+++ b/drivers/ntb/hw/idt/ntb_hw_idt.c
@@ -49,11 +49,14 @@
49#include <linux/init.h> 49#include <linux/init.h>
50#include <linux/interrupt.h> 50#include <linux/interrupt.h>
51#include <linux/spinlock.h> 51#include <linux/spinlock.h>
52#include <linux/mutex.h>
52#include <linux/pci.h> 53#include <linux/pci.h>
53#include <linux/aer.h> 54#include <linux/aer.h>
54#include <linux/slab.h> 55#include <linux/slab.h>
55#include <linux/list.h> 56#include <linux/list.h>
56#include <linux/debugfs.h> 57#include <linux/debugfs.h>
58#include <linux/hwmon.h>
59#include <linux/hwmon-sysfs.h>
57#include <linux/ntb.h> 60#include <linux/ntb.h>
58 61
59#include "ntb_hw_idt.h" 62#include "ntb_hw_idt.h"
@@ -1925,6 +1928,153 @@ static void idt_read_temp(struct idt_ntb_dev *ndev,
1925} 1928}
1926 1929
1927/* 1930/*
1931 * idt_write_temp() - write temperature to the chip sensor register
1932 * @ntb: NTB device context.
1933 * @type: IN - type of the temperature value to change
1934 * @val: IN - integer value of temperature in millidegree Celsius
1935 */
1936static void idt_write_temp(struct idt_ntb_dev *ndev,
1937 const enum idt_temp_val type, const long val)
1938{
1939 unsigned int reg;
1940 u32 data;
1941 u8 fmt;
1942
1943 /* Retrieve the properly formatted temperature value */
1944 fmt = idt_temp_get_fmt(val);
1945
1946 mutex_lock(&ndev->hwmon_mtx);
1947 switch (type) {
1948 case IDT_TEMP_LOW:
1949 reg = IDT_SW_TMPALARM;
1950 data = SET_FIELD(TMPALARM_LTEMP, idt_sw_read(ndev, reg), fmt) &
1951 ~IDT_TMPALARM_IRQ_MASK;
1952 break;
1953 case IDT_TEMP_HIGH:
1954 reg = IDT_SW_TMPALARM;
1955 data = SET_FIELD(TMPALARM_HTEMP, idt_sw_read(ndev, reg), fmt) &
1956 ~IDT_TMPALARM_IRQ_MASK;
1957 break;
1958 case IDT_TEMP_OFFSET:
1959 reg = IDT_SW_TMPADJ;
1960 data = SET_FIELD(TMPADJ_OFFSET, idt_sw_read(ndev, reg), fmt);
1961 break;
1962 default:
1963 goto inval_spin_unlock;
1964 }
1965
1966 idt_sw_write(ndev, reg, data);
1967
1968inval_spin_unlock:
1969 mutex_unlock(&ndev->hwmon_mtx);
1970}
1971
1972/*
1973 * idt_sysfs_show_temp() - printout corresponding temperature value
1974 * @dev: Pointer to the NTB device structure
1975 * @da: Sensor device attribute structure
1976 * @buf: Buffer to print temperature out
1977 *
1978 * Return: Number of written symbols or negative error
1979 */
1980static ssize_t idt_sysfs_show_temp(struct device *dev,
1981 struct device_attribute *da, char *buf)
1982{
1983 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1984 struct idt_ntb_dev *ndev = dev_get_drvdata(dev);
1985 enum idt_temp_val type = attr->index;
1986 long mdeg;
1987
1988 idt_read_temp(ndev, type, &mdeg);
1989 return sprintf(buf, "%ld\n", mdeg);
1990}
1991
1992/*
1993 * idt_sysfs_set_temp() - set corresponding temperature value
1994 * @dev: Pointer to the NTB device structure
1995 * @da: Sensor device attribute structure
1996 * @buf: Buffer to print temperature out
1997 * @count: Size of the passed buffer
1998 *
1999 * Return: Number of written symbols or negative error
2000 */
2001static ssize_t idt_sysfs_set_temp(struct device *dev,
2002 struct device_attribute *da, const char *buf,
2003 size_t count)
2004{
2005 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
2006 struct idt_ntb_dev *ndev = dev_get_drvdata(dev);
2007 enum idt_temp_val type = attr->index;
2008 long mdeg;
2009 int ret;
2010
2011 ret = kstrtol(buf, 10, &mdeg);
2012 if (ret)
2013 return ret;
2014
2015 /* Clamp the passed value in accordance with the type */
2016 if (type == IDT_TEMP_OFFSET)
2017 mdeg = clamp_val(mdeg, IDT_TEMP_MIN_OFFSET,
2018 IDT_TEMP_MAX_OFFSET);
2019 else
2020 mdeg = clamp_val(mdeg, IDT_TEMP_MIN_MDEG, IDT_TEMP_MAX_MDEG);
2021
2022 idt_write_temp(ndev, type, mdeg);
2023
2024 return count;
2025}
2026
2027/*
2028 * idt_sysfs_reset_hist() - reset temperature history
2029 * @dev: Pointer to the NTB device structure
2030 * @da: Sensor device attribute structure
2031 * @buf: Buffer to print temperature out
2032 * @count: Size of the passed buffer
2033 *
2034 * Return: Number of written symbols or negative error
2035 */
2036static ssize_t idt_sysfs_reset_hist(struct device *dev,
2037 struct device_attribute *da,
2038 const char *buf, size_t count)
2039{
2040 struct idt_ntb_dev *ndev = dev_get_drvdata(dev);
2041
2042 /* Just set the maximal value to the lowest temperature field and
2043 * minimal value to the highest temperature field
2044 */
2045 idt_write_temp(ndev, IDT_TEMP_LOW, IDT_TEMP_MAX_MDEG);
2046 idt_write_temp(ndev, IDT_TEMP_HIGH, IDT_TEMP_MIN_MDEG);
2047
2048 return count;
2049}
2050
2051/*
2052 * Hwmon IDT sysfs attributes
2053 */
2054static SENSOR_DEVICE_ATTR(temp1_input, 0444, idt_sysfs_show_temp, NULL,
2055 IDT_TEMP_CUR);
2056static SENSOR_DEVICE_ATTR(temp1_lowest, 0444, idt_sysfs_show_temp, NULL,
2057 IDT_TEMP_LOW);
2058static SENSOR_DEVICE_ATTR(temp1_highest, 0444, idt_sysfs_show_temp, NULL,
2059 IDT_TEMP_HIGH);
2060static SENSOR_DEVICE_ATTR(temp1_offset, 0644, idt_sysfs_show_temp,
2061 idt_sysfs_set_temp, IDT_TEMP_OFFSET);
2062static DEVICE_ATTR(temp1_reset_history, 0200, NULL, idt_sysfs_reset_hist);
2063
2064/*
2065 * Hwmon IDT sysfs attributes group
2066 */
2067static struct attribute *idt_temp_attrs[] = {
2068 &sensor_dev_attr_temp1_input.dev_attr.attr,
2069 &sensor_dev_attr_temp1_lowest.dev_attr.attr,
2070 &sensor_dev_attr_temp1_highest.dev_attr.attr,
2071 &sensor_dev_attr_temp1_offset.dev_attr.attr,
2072 &dev_attr_temp1_reset_history.attr,
2073 NULL
2074};
2075ATTRIBUTE_GROUPS(idt_temp);
2076
2077/*
1928 * idt_temp_isr() - temperature sensor alarm events ISR 2078 * idt_temp_isr() - temperature sensor alarm events ISR
1929 * @ndev: IDT NTB hardware driver descriptor 2079 * @ndev: IDT NTB hardware driver descriptor
1930 * @ntint_sts: NT-function interrupt status 2080 * @ntint_sts: NT-function interrupt status
@@ -1956,6 +2106,35 @@ static void idt_temp_isr(struct idt_ntb_dev *ndev, u32 ntint_sts)
1956 idt_get_deg(mdeg), idt_get_deg_frac(mdeg)); 2106 idt_get_deg(mdeg), idt_get_deg_frac(mdeg));
1957} 2107}
1958 2108
2109/*
2110 * idt_init_temp() - initialize temperature sensor interface
2111 * @ndev: IDT NTB hardware driver descriptor
2112 *
2113 * Simple sensor initializarion method is responsible for device switching
2114 * on and resource management based hwmon interface registration. Note, that
2115 * since the device is shared we won't disable it on remove, but leave it
2116 * working until the system is powered off.
2117 */
2118static void idt_init_temp(struct idt_ntb_dev *ndev)
2119{
2120 struct device *hwmon;
2121
2122 /* Enable sensor if it hasn't been already */
2123 idt_sw_write(ndev, IDT_SW_TMPCTL, 0x0);
2124
2125 /* Initialize hwmon interface fields */
2126 mutex_init(&ndev->hwmon_mtx);
2127
2128 hwmon = devm_hwmon_device_register_with_groups(&ndev->ntb.pdev->dev,
2129 ndev->swcfg->name, ndev, idt_temp_groups);
2130 if (IS_ERR(hwmon)) {
2131 dev_err(&ndev->ntb.pdev->dev, "Couldn't create hwmon device");
2132 return;
2133 }
2134
2135 dev_dbg(&ndev->ntb.pdev->dev, "Temperature HWmon interface registered");
2136}
2137
1959/*============================================================================= 2138/*=============================================================================
1960 * 8. ISRs related operations 2139 * 8. ISRs related operations
1961 * 2140 *
@@ -2650,6 +2829,9 @@ static int idt_pci_probe(struct pci_dev *pdev,
2650 /* Initialize Messaging subsystem */ 2829 /* Initialize Messaging subsystem */
2651 idt_init_msg(ndev); 2830 idt_init_msg(ndev);
2652 2831
2832 /* Initialize hwmon interface */
2833 idt_init_temp(ndev);
2834
2653 /* Initialize IDT interrupts handler */ 2835 /* Initialize IDT interrupts handler */
2654 ret = idt_init_isr(ndev); 2836 ret = idt_init_isr(ndev);
2655 if (ret != 0) 2837 if (ret != 0)
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.h b/drivers/ntb/hw/idt/ntb_hw_idt.h
index 9dfd6b11a621..032f81cb4d44 100644
--- a/drivers/ntb/hw/idt/ntb_hw_idt.h
+++ b/drivers/ntb/hw/idt/ntb_hw_idt.h
@@ -47,9 +47,9 @@
47#include <linux/pci_ids.h> 47#include <linux/pci_ids.h>
48#include <linux/interrupt.h> 48#include <linux/interrupt.h>
49#include <linux/spinlock.h> 49#include <linux/spinlock.h>
50#include <linux/mutex.h>
50#include <linux/ntb.h> 51#include <linux/ntb.h>
51 52
52
53/* 53/*
54 * Macro is used to create the struct pci_device_id that matches 54 * Macro is used to create the struct pci_device_id that matches
55 * the supported IDT PCIe-switches 55 * the supported IDT PCIe-switches
@@ -907,6 +907,10 @@
907 * TMPSTS register fields related constants 907 * TMPSTS register fields related constants
908 * @IDT_TMPSTS_TEMP_MASK: Current temperature field mask 908 * @IDT_TMPSTS_TEMP_MASK: Current temperature field mask
909 * @IDT_TMPSTS_TEMP_FLD: Current temperature field offset 909 * @IDT_TMPSTS_TEMP_FLD: Current temperature field offset
910 * @IDT_TMPSTS_LTEMP_MASK: Lowest temperature field mask
911 * @IDT_TMPSTS_LTEMP_FLD: Lowest temperature field offset
912 * @IDT_TMPSTS_HTEMP_MASK: Highest temperature field mask
913 * @IDT_TMPSTS_HTEMP_FLD: Highest temperature field offset
910 */ 914 */
911#define IDT_TMPSTS_TEMP_MASK 0x000000FFU 915#define IDT_TMPSTS_TEMP_MASK 0x000000FFU
912#define IDT_TMPSTS_TEMP_FLD 0 916#define IDT_TMPSTS_TEMP_FLD 0
@@ -916,6 +920,20 @@
916#define IDT_TMPSTS_HTEMP_FLD 16 920#define IDT_TMPSTS_HTEMP_FLD 16
917 921
918/* 922/*
923 * TMPALARM register fields related constants
924 * @IDT_TMPALARM_LTEMP_MASK: Lowest temperature field mask
925 * @IDT_TMPALARM_LTEMP_FLD: Lowest temperature field offset
926 * @IDT_TMPALARM_HTEMP_MASK: Highest temperature field mask
927 * @IDT_TMPALARM_HTEMP_FLD: Highest temperature field offset
928 * @IDT_TMPALARM_IRQ_MASK: Alarm IRQ status mask
929 */
930#define IDT_TMPALARM_LTEMP_MASK 0x0000FF00U
931#define IDT_TMPALARM_LTEMP_FLD 8
932#define IDT_TMPALARM_HTEMP_MASK 0x00FF0000U
933#define IDT_TMPALARM_HTEMP_FLD 16
934#define IDT_TMPALARM_IRQ_MASK 0x3F000000U
935
936/*
919 * TMPADJ register fields related constants 937 * TMPADJ register fields related constants
920 * @IDT_TMPADJ_OFFSET_MASK: Temperature value offset field mask 938 * @IDT_TMPADJ_OFFSET_MASK: Temperature value offset field mask
921 * @IDT_TMPADJ_OFFSET_FLD: Temperature value offset field offset 939 * @IDT_TMPADJ_OFFSET_FLD: Temperature value offset field offset
@@ -1100,6 +1118,8 @@ struct idt_ntb_peer {
1100 * @msg_mask_lock: Message mask register lock 1118 * @msg_mask_lock: Message mask register lock
1101 * @gasa_lock: GASA registers access lock 1119 * @gasa_lock: GASA registers access lock
1102 * 1120 *
1121 * @hwmon_mtx: Temperature sensor interface update mutex
1122 *
1103 * @dbgfs_info: DebugFS info node 1123 * @dbgfs_info: DebugFS info node
1104 */ 1124 */
1105struct idt_ntb_dev { 1125struct idt_ntb_dev {
@@ -1127,6 +1147,8 @@ struct idt_ntb_dev {
1127 spinlock_t msg_mask_lock; 1147 spinlock_t msg_mask_lock;
1128 spinlock_t gasa_lock; 1148 spinlock_t gasa_lock;
1129 1149
1150 struct mutex hwmon_mtx;
1151
1130 struct dentry *dbgfs_info; 1152 struct dentry *dbgfs_info;
1131}; 1153};
1132#define to_ndev_ntb(__ntb) container_of(__ntb, struct idt_ntb_dev, ntb) 1154#define to_ndev_ntb(__ntb) container_of(__ntb, struct idt_ntb_dev, ntb)