diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-11-04 11:12:44 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-11-04 11:12:44 -0500 |
| commit | 04578e8441c5420259a71eff9fede535858bfc6a (patch) | |
| tree | dddc3123bffdd48c872ed05af5cbad80368b4029 | |
| parent | 71e56028173bc84f01456a5679d8be9d681b49f1 (diff) | |
| parent | a662315d8ad9e687fe648b6eea9bd35017f565dd (diff) | |
Merge tag 'ntb-4.20' of git://github.com/jonmason/ntb
Pull NTB updates from Jon Mason:
"Fairly minor changes and bug fixes:
NTB IDT thermal changes and hook into hwmon, ntb_netdev clean-up of
private struct, and a few bug fixes"
* tag 'ntb-4.20' of git://github.com/jonmason/ntb:
ntb: idt: Alter the driver info comments
ntb: idt: Discard temperature sensor IRQ handler
ntb: idt: Add basic hwmon sysfs interface
ntb: idt: Alter temperature read method
ntb_netdev: Simplify remove with client device drvdata
NTB: transport: Try harder to alloc an aligned MW buffer
ntb: ntb_transport: Mark expected switch fall-throughs
ntb: idt: Set PCIe bus address to BARLIMITx
NTB: ntb_hw_idt: replace IS_ERR_OR_NULL with regular NULL checks
ntb: intel: fix return value for ndev_vec_mask()
ntb_netdev: fix sleep time mismatch
| -rw-r--r-- | drivers/net/ntb_netdev.c | 30 | ||||
| -rw-r--r-- | drivers/ntb/hw/idt/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/ntb/hw/idt/ntb_hw_idt.c | 327 | ||||
| -rw-r--r-- | drivers/ntb/hw/idt/ntb_hw_idt.h | 87 | ||||
| -rw-r--r-- | drivers/ntb/hw/intel/ntb_hw_gen1.c | 2 | ||||
| -rw-r--r-- | drivers/ntb/ntb_transport.c | 88 |
6 files changed, 429 insertions, 110 deletions
diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c index b12023bc2cab..a5bab614ff84 100644 --- a/drivers/net/ntb_netdev.c +++ b/drivers/net/ntb_netdev.c | |||
| @@ -71,7 +71,6 @@ static unsigned int tx_start = 10; | |||
| 71 | static unsigned int tx_stop = 5; | 71 | static unsigned int tx_stop = 5; |
| 72 | 72 | ||
| 73 | struct ntb_netdev { | 73 | struct ntb_netdev { |
| 74 | struct list_head list; | ||
| 75 | struct pci_dev *pdev; | 74 | struct pci_dev *pdev; |
| 76 | struct net_device *ndev; | 75 | struct net_device *ndev; |
| 77 | struct ntb_transport_qp *qp; | 76 | struct ntb_transport_qp *qp; |
| @@ -81,8 +80,6 @@ struct ntb_netdev { | |||
| 81 | #define NTB_TX_TIMEOUT_MS 1000 | 80 | #define NTB_TX_TIMEOUT_MS 1000 |
| 82 | #define NTB_RXQ_SIZE 100 | 81 | #define NTB_RXQ_SIZE 100 |
| 83 | 82 | ||
| 84 | static LIST_HEAD(dev_list); | ||
| 85 | |||
| 86 | static void ntb_netdev_event_handler(void *data, int link_is_up) | 83 | static void ntb_netdev_event_handler(void *data, int link_is_up) |
| 87 | { | 84 | { |
| 88 | struct net_device *ndev = data; | 85 | struct net_device *ndev = data; |
| @@ -236,7 +233,7 @@ static void ntb_netdev_tx_timer(struct timer_list *t) | |||
| 236 | struct net_device *ndev = dev->ndev; | 233 | struct net_device *ndev = dev->ndev; |
| 237 | 234 | ||
| 238 | if (ntb_transport_tx_free_entry(dev->qp) < tx_stop) { | 235 | if (ntb_transport_tx_free_entry(dev->qp) < tx_stop) { |
| 239 | mod_timer(&dev->tx_timer, jiffies + msecs_to_jiffies(tx_time)); | 236 | mod_timer(&dev->tx_timer, jiffies + usecs_to_jiffies(tx_time)); |
| 240 | } else { | 237 | } else { |
| 241 | /* Make sure anybody stopping the queue after this sees the new | 238 | /* Make sure anybody stopping the queue after this sees the new |
| 242 | * value of ntb_transport_tx_free_entry() | 239 | * value of ntb_transport_tx_free_entry() |
| @@ -452,7 +449,7 @@ static int ntb_netdev_probe(struct device *client_dev) | |||
| 452 | if (rc) | 449 | if (rc) |
| 453 | goto err1; | 450 | goto err1; |
| 454 | 451 | ||
| 455 | list_add(&dev->list, &dev_list); | 452 | dev_set_drvdata(client_dev, ndev); |
| 456 | dev_info(&pdev->dev, "%s created\n", ndev->name); | 453 | dev_info(&pdev->dev, "%s created\n", ndev->name); |
| 457 | return 0; | 454 | return 0; |
| 458 | 455 | ||
| @@ -465,27 +462,8 @@ err: | |||
| 465 | 462 | ||
| 466 | static void ntb_netdev_remove(struct device *client_dev) | 463 | static void ntb_netdev_remove(struct device *client_dev) |
| 467 | { | 464 | { |
| 468 | struct ntb_dev *ntb; | 465 | struct net_device *ndev = dev_get_drvdata(client_dev); |
| 469 | struct net_device *ndev; | 466 | struct ntb_netdev *dev = netdev_priv(ndev); |
| 470 | struct pci_dev *pdev; | ||
| 471 | struct ntb_netdev *dev; | ||
| 472 | bool found = false; | ||
| 473 | |||
| 474 | ntb = dev_ntb(client_dev->parent); | ||
| 475 | pdev = ntb->pdev; | ||
| 476 | |||
| 477 | list_for_each_entry(dev, &dev_list, list) { | ||
| 478 | if (dev->pdev == pdev) { | ||
| 479 | found = true; | ||
| 480 | break; | ||
| 481 | } | ||
| 482 | } | ||
| 483 | if (!found) | ||
| 484 | return; | ||
| 485 | |||
| 486 | list_del(&dev->list); | ||
| 487 | |||
| 488 | ndev = dev->ndev; | ||
| 489 | 467 | ||
| 490 | unregister_netdev(ndev); | 468 | unregister_netdev(ndev); |
| 491 | ntb_transport_free_queue(dev->qp); | 469 | ntb_transport_free_queue(dev->qp); |
diff --git a/drivers/ntb/hw/idt/Kconfig b/drivers/ntb/hw/idt/Kconfig index b360e5613b9f..f8948cf515ce 100644 --- a/drivers/ntb/hw/idt/Kconfig +++ b/drivers/ntb/hw/idt/Kconfig | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | config NTB_IDT | 1 | config 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 | ||
| @@ -23,9 +24,7 @@ config NTB_IDT | |||
| 23 | BAR settings of peer NT-functions, the BAR setups can't be done over | 24 | BAR settings of peer NT-functions, the BAR setups can't be done over |
| 24 | kernel PCI fixups. That's why the alternative pre-initialization | 25 | kernel PCI fixups. That's why the alternative pre-initialization |
| 25 | techniques like BIOS using SMBus interface or EEPROM should be | 26 | techniques like BIOS using SMBus interface or EEPROM should be |
| 26 | utilized. Additionally if one needs to have temperature sensor | 27 | utilized. |
| 27 | information printed to system log, the corresponding registers must | ||
| 28 | be initialized within BIOS/EEPROM as well. | ||
| 29 | 28 | ||
| 30 | If unsure, say N. | 29 | If unsure, say N. |
| 31 | 30 | ||
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c index dbe72f116017..1dede87dd54f 100644 --- a/drivers/ntb/hw/idt/ntb_hw_idt.c +++ b/drivers/ntb/hw/idt/ntb_hw_idt.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * GPL LICENSE SUMMARY | 5 | * GPL LICENSE SUMMARY |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 2016 T-Platforms All Rights Reserved. | 7 | * Copyright (C) 2016-2018 T-Platforms JSC All Rights Reserved. |
| 8 | * | 8 | * |
| 9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
| 10 | * under the terms and conditions of the GNU General Public License, | 10 | * under the terms and conditions of the GNU General Public License, |
| @@ -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" |
| @@ -1105,9 +1108,9 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port, | |||
| 1105 | } | 1108 | } |
| 1106 | 1109 | ||
| 1107 | /* Allocate memory for memory window descriptors */ | 1110 | /* Allocate memory for memory window descriptors */ |
| 1108 | ret_mws = devm_kcalloc(&ndev->ntb.pdev->dev, *mw_cnt, | 1111 | ret_mws = devm_kcalloc(&ndev->ntb.pdev->dev, *mw_cnt, sizeof(*ret_mws), |
| 1109 | sizeof(*ret_mws), GFP_KERNEL); | 1112 | GFP_KERNEL); |
| 1110 | if (IS_ERR_OR_NULL(ret_mws)) | 1113 | if (!ret_mws) |
| 1111 | return ERR_PTR(-ENOMEM); | 1114 | return ERR_PTR(-ENOMEM); |
| 1112 | 1115 | ||
| 1113 | /* Copy the info of detected memory windows */ | 1116 | /* Copy the info of detected memory windows */ |
| @@ -1320,7 +1323,7 @@ static int idt_ntb_peer_mw_set_trans(struct ntb_dev *ntb, int pidx, int widx, | |||
| 1320 | idt_nt_write(ndev, bar->ltbase, (u32)addr); | 1323 | idt_nt_write(ndev, bar->ltbase, (u32)addr); |
| 1321 | idt_nt_write(ndev, bar->utbase, (u32)(addr >> 32)); | 1324 | idt_nt_write(ndev, bar->utbase, (u32)(addr >> 32)); |
| 1322 | /* Set the custom BAR aperture limit */ | 1325 | /* Set the custom BAR aperture limit */ |
| 1323 | limit = pci_resource_start(ntb->pdev, mw_cfg->bar) + size; | 1326 | limit = pci_bus_address(ntb->pdev, mw_cfg->bar) + size; |
| 1324 | idt_nt_write(ndev, bar->limit, (u32)limit); | 1327 | idt_nt_write(ndev, bar->limit, (u32)limit); |
| 1325 | if (IS_FLD_SET(BARSETUP_TYPE, data, 64)) | 1328 | if (IS_FLD_SET(BARSETUP_TYPE, data, 64)) |
| 1326 | idt_nt_write(ndev, (bar + 1)->limit, (limit >> 32)); | 1329 | idt_nt_write(ndev, (bar + 1)->limit, (limit >> 32)); |
| @@ -1821,61 +1824,284 @@ static int idt_ntb_peer_msg_write(struct ntb_dev *ntb, int pidx, int midx, | |||
| 1821 | * 7. Temperature sensor operations | 1824 | * 7. Temperature sensor operations |
| 1822 | * | 1825 | * |
| 1823 | * IDT PCIe-switch has an embedded temperature sensor, which can be used to | 1826 | * IDT PCIe-switch has an embedded temperature sensor, which can be used to |
| 1824 | * warn a user-space of possible chip overheating. Since workload temperature | 1827 | * check current chip core temperature. Since a workload environment can be |
| 1825 | * can be different on different platforms, temperature thresholds as well as | 1828 | * different on different platforms, an offset and ADC/filter settings can be |
| 1826 | * general sensor settings must be setup in the framework of BIOS/EEPROM | 1829 | * specified. Although the offset configuration is only exposed to the sysfs |
| 1827 | * initializations. It includes the actual sensor enabling as well. | 1830 | * hwmon interface at the moment. The rest of the settings can be adjusted |
| 1831 | * for instance by the BIOS/EEPROM firmware. | ||
| 1828 | *============================================================================= | 1832 | *============================================================================= |
| 1829 | */ | 1833 | */ |
| 1830 | 1834 | ||
| 1831 | /* | 1835 | /* |
| 1836 | * idt_get_deg() - convert millidegree Celsius value to just degree | ||
| 1837 | * @mdegC: IN - millidegree Celsius value | ||
| 1838 | * | ||
| 1839 | * Return: Degree corresponding to the passed millidegree value | ||
| 1840 | */ | ||
| 1841 | static inline s8 idt_get_deg(long mdegC) | ||
| 1842 | { | ||
| 1843 | return mdegC / 1000; | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | /* | ||
| 1847 | * idt_get_frac() - retrieve 0/0.5 fraction of the millidegree Celsius value | ||
| 1848 | * @mdegC: IN - millidegree Celsius value | ||
| 1849 | * | ||
| 1850 | * Return: 0/0.5 degree fraction of the passed millidegree value | ||
| 1851 | */ | ||
| 1852 | static inline u8 idt_get_deg_frac(long mdegC) | ||
| 1853 | { | ||
| 1854 | return (mdegC % 1000) >= 500 ? 5 : 0; | ||
| 1855 | } | ||
| 1856 | |||
| 1857 | /* | ||
| 1858 | * idt_get_temp_fmt() - convert millidegree Celsius value to 0:7:1 format | ||
| 1859 | * @mdegC: IN - millidegree Celsius value | ||
| 1860 | * | ||
| 1861 | * Return: 0:7:1 format acceptable by the IDT temperature sensor | ||
| 1862 | */ | ||
| 1863 | static inline u8 idt_temp_get_fmt(long mdegC) | ||
| 1864 | { | ||
| 1865 | return (idt_get_deg(mdegC) << 1) | (idt_get_deg_frac(mdegC) ? 1 : 0); | ||
| 1866 | } | ||
| 1867 | |||
| 1868 | /* | ||
| 1869 | * idt_get_temp_sval() - convert temp sample to signed millidegree Celsius | ||
| 1870 | * @data: IN - shifted to LSB 8-bits temperature sample | ||
| 1871 | * | ||
| 1872 | * Return: signed millidegree Celsius | ||
| 1873 | */ | ||
| 1874 | static inline long idt_get_temp_sval(u32 data) | ||
| 1875 | { | ||
| 1876 | return ((s8)data / 2) * 1000 + (data & 0x1 ? 500 : 0); | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | /* | ||
| 1880 | * idt_get_temp_sval() - convert temp sample to unsigned millidegree Celsius | ||
| 1881 | * @data: IN - shifted to LSB 8-bits temperature sample | ||
| 1882 | * | ||
| 1883 | * Return: unsigned millidegree Celsius | ||
| 1884 | */ | ||
| 1885 | static inline long idt_get_temp_uval(u32 data) | ||
| 1886 | { | ||
| 1887 | return (data / 2) * 1000 + (data & 0x1 ? 500 : 0); | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | /* | ||
| 1832 | * idt_read_temp() - read temperature from chip sensor | 1891 | * idt_read_temp() - read temperature from chip sensor |
| 1833 | * @ntb: NTB device context. | 1892 | * @ntb: NTB device context. |
| 1834 | * @val: OUT - integer value of temperature | 1893 | * @type: IN - type of the temperature value to read |
| 1835 | * @frac: OUT - fraction | 1894 | * @val: OUT - integer value of temperature in millidegree Celsius |
| 1836 | */ | 1895 | */ |
| 1837 | static void idt_read_temp(struct idt_ntb_dev *ndev, unsigned char *val, | 1896 | static void idt_read_temp(struct idt_ntb_dev *ndev, |
| 1838 | unsigned char *frac) | 1897 | const enum idt_temp_val type, long *val) |
| 1839 | { | 1898 | { |
| 1840 | u32 data; | 1899 | u32 data; |
| 1841 | 1900 | ||
| 1842 | /* Read the data from TEMP field of the TMPSTS register */ | 1901 | /* Alter the temperature field in accordance with the passed type */ |
| 1843 | data = idt_sw_read(ndev, IDT_SW_TMPSTS); | 1902 | switch (type) { |
| 1844 | data = GET_FIELD(TMPSTS_TEMP, data); | 1903 | case IDT_TEMP_CUR: |
| 1845 | /* TEMP field has one fractional bit and seven integer bits */ | 1904 | data = GET_FIELD(TMPSTS_TEMP, |
| 1846 | *val = data >> 1; | 1905 | idt_sw_read(ndev, IDT_SW_TMPSTS)); |
| 1847 | *frac = ((data & 0x1) ? 5 : 0); | 1906 | break; |
| 1907 | case IDT_TEMP_LOW: | ||
| 1908 | data = GET_FIELD(TMPSTS_LTEMP, | ||
| 1909 | idt_sw_read(ndev, IDT_SW_TMPSTS)); | ||
| 1910 | break; | ||
| 1911 | case IDT_TEMP_HIGH: | ||
| 1912 | data = GET_FIELD(TMPSTS_HTEMP, | ||
| 1913 | idt_sw_read(ndev, IDT_SW_TMPSTS)); | ||
| 1914 | break; | ||
| 1915 | case IDT_TEMP_OFFSET: | ||
| 1916 | /* This is the only field with signed 0:7:1 format */ | ||
| 1917 | data = GET_FIELD(TMPADJ_OFFSET, | ||
| 1918 | idt_sw_read(ndev, IDT_SW_TMPADJ)); | ||
| 1919 | *val = idt_get_temp_sval(data); | ||
| 1920 | return; | ||
| 1921 | default: | ||
| 1922 | data = GET_FIELD(TMPSTS_TEMP, | ||
| 1923 | idt_sw_read(ndev, IDT_SW_TMPSTS)); | ||
| 1924 | break; | ||
| 1925 | } | ||
| 1926 | |||
| 1927 | /* The rest of the fields accept unsigned 0:7:1 format */ | ||
| 1928 | *val = idt_get_temp_uval(data); | ||
| 1848 | } | 1929 | } |
| 1849 | 1930 | ||
| 1850 | /* | 1931 | /* |
| 1851 | * idt_temp_isr() - temperature sensor alarm events ISR | 1932 | * idt_write_temp() - write temperature to the chip sensor register |
| 1852 | * @ndev: IDT NTB hardware driver descriptor | 1933 | * @ntb: NTB device context. |
| 1853 | * @ntint_sts: NT-function interrupt status | 1934 | * @type: IN - type of the temperature value to change |
| 1935 | * @val: IN - integer value of temperature in millidegree Celsius | ||
| 1936 | */ | ||
| 1937 | static void idt_write_temp(struct idt_ntb_dev *ndev, | ||
| 1938 | const enum idt_temp_val type, const long val) | ||
| 1939 | { | ||
| 1940 | unsigned int reg; | ||
| 1941 | u32 data; | ||
| 1942 | u8 fmt; | ||
| 1943 | |||
| 1944 | /* Retrieve the properly formatted temperature value */ | ||
| 1945 | fmt = idt_temp_get_fmt(val); | ||
| 1946 | |||
| 1947 | mutex_lock(&ndev->hwmon_mtx); | ||
| 1948 | switch (type) { | ||
| 1949 | case IDT_TEMP_LOW: | ||
| 1950 | reg = IDT_SW_TMPALARM; | ||
| 1951 | data = SET_FIELD(TMPALARM_LTEMP, idt_sw_read(ndev, reg), fmt) & | ||
| 1952 | ~IDT_TMPALARM_IRQ_MASK; | ||
| 1953 | break; | ||
| 1954 | case IDT_TEMP_HIGH: | ||
| 1955 | reg = IDT_SW_TMPALARM; | ||
| 1956 | data = SET_FIELD(TMPALARM_HTEMP, idt_sw_read(ndev, reg), fmt) & | ||
| 1957 | ~IDT_TMPALARM_IRQ_MASK; | ||
| 1958 | break; | ||
| 1959 | case IDT_TEMP_OFFSET: | ||
| 1960 | reg = IDT_SW_TMPADJ; | ||
| 1961 | data = SET_FIELD(TMPADJ_OFFSET, idt_sw_read(ndev, reg), fmt); | ||
| 1962 | break; | ||
| 1963 | default: | ||
| 1964 | goto inval_spin_unlock; | ||
| 1965 | } | ||
| 1966 | |||
| 1967 | idt_sw_write(ndev, reg, data); | ||
| 1968 | |||
| 1969 | inval_spin_unlock: | ||
| 1970 | mutex_unlock(&ndev->hwmon_mtx); | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | /* | ||
| 1974 | * idt_sysfs_show_temp() - printout corresponding temperature value | ||
| 1975 | * @dev: Pointer to the NTB device structure | ||
| 1976 | * @da: Sensor device attribute structure | ||
| 1977 | * @buf: Buffer to print temperature out | ||
| 1854 | * | 1978 | * |
| 1855 | * It handles events of temperature crossing alarm thresholds. Since reading | 1979 | * Return: Number of written symbols or negative error |
| 1856 | * of TMPALARM register clears it up, the function doesn't analyze the | ||
| 1857 | * read value, instead the current temperature value just warningly printed to | ||
| 1858 | * log. | ||
| 1859 | * The method is called from PCIe ISR bottom-half routine. | ||
| 1860 | */ | 1980 | */ |
| 1861 | static void idt_temp_isr(struct idt_ntb_dev *ndev, u32 ntint_sts) | 1981 | static ssize_t idt_sysfs_show_temp(struct device *dev, |
| 1982 | struct device_attribute *da, char *buf) | ||
| 1862 | { | 1983 | { |
| 1863 | unsigned char val, frac; | 1984 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 1985 | struct idt_ntb_dev *ndev = dev_get_drvdata(dev); | ||
| 1986 | enum idt_temp_val type = attr->index; | ||
| 1987 | long mdeg; | ||
| 1864 | 1988 | ||
| 1865 | /* Read the current temperature value */ | 1989 | idt_read_temp(ndev, type, &mdeg); |
| 1866 | idt_read_temp(ndev, &val, &frac); | 1990 | return sprintf(buf, "%ld\n", mdeg); |
| 1991 | } | ||
| 1867 | 1992 | ||
| 1868 | /* Read the temperature alarm to clean the alarm status out */ | 1993 | /* |
| 1869 | /*(void)idt_sw_read(ndev, IDT_SW_TMPALARM);*/ | 1994 | * idt_sysfs_set_temp() - set corresponding temperature value |
| 1995 | * @dev: Pointer to the NTB device structure | ||
| 1996 | * @da: Sensor device attribute structure | ||
| 1997 | * @buf: Buffer to print temperature out | ||
| 1998 | * @count: Size of the passed buffer | ||
| 1999 | * | ||
| 2000 | * Return: Number of written symbols or negative error | ||
| 2001 | */ | ||
| 2002 | static ssize_t idt_sysfs_set_temp(struct device *dev, | ||
| 2003 | struct device_attribute *da, const char *buf, | ||
| 2004 | size_t count) | ||
| 2005 | { | ||
| 2006 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 2007 | struct idt_ntb_dev *ndev = dev_get_drvdata(dev); | ||
| 2008 | enum idt_temp_val type = attr->index; | ||
| 2009 | long mdeg; | ||
| 2010 | int ret; | ||
| 1870 | 2011 | ||
| 1871 | /* Clean the corresponding interrupt bit */ | 2012 | ret = kstrtol(buf, 10, &mdeg); |
| 1872 | idt_nt_write(ndev, IDT_NT_NTINTSTS, IDT_NTINTSTS_TMPSENSOR); | 2013 | if (ret) |
| 2014 | return ret; | ||
| 2015 | |||
| 2016 | /* Clamp the passed value in accordance with the type */ | ||
| 2017 | if (type == IDT_TEMP_OFFSET) | ||
| 2018 | mdeg = clamp_val(mdeg, IDT_TEMP_MIN_OFFSET, | ||
| 2019 | IDT_TEMP_MAX_OFFSET); | ||
| 2020 | else | ||
| 2021 | mdeg = clamp_val(mdeg, IDT_TEMP_MIN_MDEG, IDT_TEMP_MAX_MDEG); | ||
| 2022 | |||
| 2023 | idt_write_temp(ndev, type, mdeg); | ||
| 2024 | |||
| 2025 | return count; | ||
| 2026 | } | ||
| 2027 | |||
| 2028 | /* | ||
| 2029 | * idt_sysfs_reset_hist() - reset temperature history | ||
| 2030 | * @dev: Pointer to the NTB device structure | ||
| 2031 | * @da: Sensor device attribute structure | ||
| 2032 | * @buf: Buffer to print temperature out | ||
| 2033 | * @count: Size of the passed buffer | ||
| 2034 | * | ||
| 2035 | * Return: Number of written symbols or negative error | ||
| 2036 | */ | ||
| 2037 | static ssize_t idt_sysfs_reset_hist(struct device *dev, | ||
| 2038 | struct device_attribute *da, | ||
| 2039 | const char *buf, size_t count) | ||
| 2040 | { | ||
| 2041 | struct idt_ntb_dev *ndev = dev_get_drvdata(dev); | ||
| 2042 | |||
| 2043 | /* Just set the maximal value to the lowest temperature field and | ||
| 2044 | * minimal value to the highest temperature field | ||
| 2045 | */ | ||
| 2046 | idt_write_temp(ndev, IDT_TEMP_LOW, IDT_TEMP_MAX_MDEG); | ||
| 2047 | idt_write_temp(ndev, IDT_TEMP_HIGH, IDT_TEMP_MIN_MDEG); | ||
| 1873 | 2048 | ||
| 1874 | dev_dbg(&ndev->ntb.pdev->dev, | 2049 | return count; |
| 1875 | "Temp sensor IRQ detected %#08x", ntint_sts); | 2050 | } |
| 2051 | |||
| 2052 | /* | ||
| 2053 | * Hwmon IDT sysfs attributes | ||
| 2054 | */ | ||
| 2055 | static SENSOR_DEVICE_ATTR(temp1_input, 0444, idt_sysfs_show_temp, NULL, | ||
| 2056 | IDT_TEMP_CUR); | ||
| 2057 | static SENSOR_DEVICE_ATTR(temp1_lowest, 0444, idt_sysfs_show_temp, NULL, | ||
| 2058 | IDT_TEMP_LOW); | ||
| 2059 | static SENSOR_DEVICE_ATTR(temp1_highest, 0444, idt_sysfs_show_temp, NULL, | ||
| 2060 | IDT_TEMP_HIGH); | ||
| 2061 | static SENSOR_DEVICE_ATTR(temp1_offset, 0644, idt_sysfs_show_temp, | ||
| 2062 | idt_sysfs_set_temp, IDT_TEMP_OFFSET); | ||
| 2063 | static DEVICE_ATTR(temp1_reset_history, 0200, NULL, idt_sysfs_reset_hist); | ||
| 1876 | 2064 | ||
| 1877 | /* Print temperature value to log */ | 2065 | /* |
| 1878 | dev_warn(&ndev->ntb.pdev->dev, "Temperature %hhu.%hhu", val, frac); | 2066 | * Hwmon IDT sysfs attributes group |
| 2067 | */ | ||
| 2068 | static struct attribute *idt_temp_attrs[] = { | ||
| 2069 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
| 2070 | &sensor_dev_attr_temp1_lowest.dev_attr.attr, | ||
| 2071 | &sensor_dev_attr_temp1_highest.dev_attr.attr, | ||
| 2072 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | ||
| 2073 | &dev_attr_temp1_reset_history.attr, | ||
| 2074 | NULL | ||
| 2075 | }; | ||
| 2076 | ATTRIBUTE_GROUPS(idt_temp); | ||
| 2077 | |||
| 2078 | /* | ||
| 2079 | * idt_init_temp() - initialize temperature sensor interface | ||
| 2080 | * @ndev: IDT NTB hardware driver descriptor | ||
| 2081 | * | ||
| 2082 | * Simple sensor initializarion method is responsible for device switching | ||
| 2083 | * on and resource management based hwmon interface registration. Note, that | ||
| 2084 | * since the device is shared we won't disable it on remove, but leave it | ||
| 2085 | * working until the system is powered off. | ||
| 2086 | */ | ||
| 2087 | static void idt_init_temp(struct idt_ntb_dev *ndev) | ||
| 2088 | { | ||
| 2089 | struct device *hwmon; | ||
| 2090 | |||
| 2091 | /* Enable sensor if it hasn't been already */ | ||
| 2092 | idt_sw_write(ndev, IDT_SW_TMPCTL, 0x0); | ||
| 2093 | |||
| 2094 | /* Initialize hwmon interface fields */ | ||
| 2095 | mutex_init(&ndev->hwmon_mtx); | ||
| 2096 | |||
| 2097 | hwmon = devm_hwmon_device_register_with_groups(&ndev->ntb.pdev->dev, | ||
| 2098 | ndev->swcfg->name, ndev, idt_temp_groups); | ||
| 2099 | if (IS_ERR(hwmon)) { | ||
| 2100 | dev_err(&ndev->ntb.pdev->dev, "Couldn't create hwmon device"); | ||
| 2101 | return; | ||
| 2102 | } | ||
| 2103 | |||
| 2104 | dev_dbg(&ndev->ntb.pdev->dev, "Temperature HWmon interface registered"); | ||
| 1879 | } | 2105 | } |
| 1880 | 2106 | ||
| 1881 | /*============================================================================= | 2107 | /*============================================================================= |
| @@ -1931,7 +2157,7 @@ static int idt_init_isr(struct idt_ntb_dev *ndev) | |||
| 1931 | goto err_free_vectors; | 2157 | goto err_free_vectors; |
| 1932 | } | 2158 | } |
| 1933 | 2159 | ||
| 1934 | /* Unmask Message/Doorbell/SE/Temperature interrupts */ | 2160 | /* Unmask Message/Doorbell/SE interrupts */ |
| 1935 | ntint_mask = idt_nt_read(ndev, IDT_NT_NTINTMSK) & ~IDT_NTINTMSK_ALL; | 2161 | ntint_mask = idt_nt_read(ndev, IDT_NT_NTINTMSK) & ~IDT_NTINTMSK_ALL; |
| 1936 | idt_nt_write(ndev, IDT_NT_NTINTMSK, ntint_mask); | 2162 | idt_nt_write(ndev, IDT_NT_NTINTMSK, ntint_mask); |
| 1937 | 2163 | ||
| @@ -1946,7 +2172,6 @@ err_free_vectors: | |||
| 1946 | return ret; | 2172 | return ret; |
| 1947 | } | 2173 | } |
| 1948 | 2174 | ||
| 1949 | |||
| 1950 | /* | 2175 | /* |
| 1951 | * idt_deinit_ist() - deinitialize PCIe interrupt handler | 2176 | * idt_deinit_ist() - deinitialize PCIe interrupt handler |
| 1952 | * @ndev: IDT NTB hardware driver descriptor | 2177 | * @ndev: IDT NTB hardware driver descriptor |
| @@ -2007,12 +2232,6 @@ static irqreturn_t idt_thread_isr(int irq, void *devid) | |||
| 2007 | handled = true; | 2232 | handled = true; |
| 2008 | } | 2233 | } |
| 2009 | 2234 | ||
| 2010 | /* Handle temperature sensor interrupt */ | ||
| 2011 | if (ntint_sts & IDT_NTINTSTS_TMPSENSOR) { | ||
| 2012 | idt_temp_isr(ndev, ntint_sts); | ||
| 2013 | handled = true; | ||
| 2014 | } | ||
| 2015 | |||
| 2016 | dev_dbg(&ndev->ntb.pdev->dev, "IDT IRQs 0x%08x handled", ntint_sts); | 2235 | dev_dbg(&ndev->ntb.pdev->dev, "IDT IRQs 0x%08x handled", ntint_sts); |
| 2017 | 2236 | ||
| 2018 | return handled ? IRQ_HANDLED : IRQ_NONE; | 2237 | return handled ? IRQ_HANDLED : IRQ_NONE; |
| @@ -2123,9 +2342,9 @@ static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf, | |||
| 2123 | size_t count, loff_t *offp) | 2342 | size_t count, loff_t *offp) |
| 2124 | { | 2343 | { |
| 2125 | struct idt_ntb_dev *ndev = filp->private_data; | 2344 | struct idt_ntb_dev *ndev = filp->private_data; |
| 2126 | unsigned char temp, frac, idx, pidx, cnt; | 2345 | unsigned char idx, pidx, cnt; |
| 2346 | unsigned long irqflags, mdeg; | ||
| 2127 | ssize_t ret = 0, off = 0; | 2347 | ssize_t ret = 0, off = 0; |
| 2128 | unsigned long irqflags; | ||
| 2129 | enum ntb_speed speed; | 2348 | enum ntb_speed speed; |
| 2130 | enum ntb_width width; | 2349 | enum ntb_width width; |
| 2131 | char *strbuf; | 2350 | char *strbuf; |
| @@ -2274,9 +2493,10 @@ static ssize_t idt_dbgfs_info_read(struct file *filp, char __user *ubuf, | |||
| 2274 | off += scnprintf(strbuf + off, size - off, "\n"); | 2493 | off += scnprintf(strbuf + off, size - off, "\n"); |
| 2275 | 2494 | ||
| 2276 | /* Current temperature */ | 2495 | /* Current temperature */ |
| 2277 | idt_read_temp(ndev, &temp, &frac); | 2496 | idt_read_temp(ndev, IDT_TEMP_CUR, &mdeg); |
| 2278 | off += scnprintf(strbuf + off, size - off, | 2497 | off += scnprintf(strbuf + off, size - off, |
| 2279 | "Switch temperature\t\t- %hhu.%hhuC\n", temp, frac); | 2498 | "Switch temperature\t\t- %hhd.%hhuC\n", |
| 2499 | idt_get_deg(mdeg), idt_get_deg_frac(mdeg)); | ||
| 2280 | 2500 | ||
| 2281 | /* Copy the buffer to the User Space */ | 2501 | /* Copy the buffer to the User Space */ |
| 2282 | ret = simple_read_from_buffer(ubuf, count, offp, strbuf, off); | 2502 | ret = simple_read_from_buffer(ubuf, count, offp, strbuf, off); |
| @@ -2390,7 +2610,7 @@ static struct idt_ntb_dev *idt_create_dev(struct pci_dev *pdev, | |||
| 2390 | 2610 | ||
| 2391 | /* Allocate memory for the IDT PCIe-device descriptor */ | 2611 | /* Allocate memory for the IDT PCIe-device descriptor */ |
| 2392 | ndev = devm_kzalloc(&pdev->dev, sizeof(*ndev), GFP_KERNEL); | 2612 | ndev = devm_kzalloc(&pdev->dev, sizeof(*ndev), GFP_KERNEL); |
| 2393 | if (IS_ERR_OR_NULL(ndev)) { | 2613 | if (!ndev) { |
| 2394 | dev_err(&pdev->dev, "Memory allocation failed for descriptor"); | 2614 | dev_err(&pdev->dev, "Memory allocation failed for descriptor"); |
| 2395 | return ERR_PTR(-ENOMEM); | 2615 | return ERR_PTR(-ENOMEM); |
| 2396 | } | 2616 | } |
| @@ -2571,6 +2791,9 @@ static int idt_pci_probe(struct pci_dev *pdev, | |||
| 2571 | /* Initialize Messaging subsystem */ | 2791 | /* Initialize Messaging subsystem */ |
| 2572 | idt_init_msg(ndev); | 2792 | idt_init_msg(ndev); |
| 2573 | 2793 | ||
| 2794 | /* Initialize hwmon interface */ | ||
| 2795 | idt_init_temp(ndev); | ||
| 2796 | |||
| 2574 | /* Initialize IDT interrupts handler */ | 2797 | /* Initialize IDT interrupts handler */ |
| 2575 | ret = idt_init_isr(ndev); | 2798 | ret = idt_init_isr(ndev); |
| 2576 | if (ret != 0) | 2799 | if (ret != 0) |
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.h b/drivers/ntb/hw/idt/ntb_hw_idt.h index 856fd182f6f4..2f1aa121b0cf 100644 --- a/drivers/ntb/hw/idt/ntb_hw_idt.h +++ b/drivers/ntb/hw/idt/ntb_hw_idt.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * GPL LICENSE SUMMARY | 5 | * GPL LICENSE SUMMARY |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 2016 T-Platforms All Rights Reserved. | 7 | * Copyright (C) 2016-2018 T-Platforms JSC All Rights Reserved. |
| 8 | * | 8 | * |
| 9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
| 10 | * under the terms and conditions of the GNU General Public License, | 10 | * under the terms and conditions of the GNU General Public License, |
| @@ -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 |
| @@ -688,15 +688,14 @@ | |||
| 688 | * @IDT_NTINTMSK_DBELL: Doorbell interrupt mask bit | 688 | * @IDT_NTINTMSK_DBELL: Doorbell interrupt mask bit |
| 689 | * @IDT_NTINTMSK_SEVENT: Switch Event interrupt mask bit | 689 | * @IDT_NTINTMSK_SEVENT: Switch Event interrupt mask bit |
| 690 | * @IDT_NTINTMSK_TMPSENSOR: Temperature sensor interrupt mask bit | 690 | * @IDT_NTINTMSK_TMPSENSOR: Temperature sensor interrupt mask bit |
| 691 | * @IDT_NTINTMSK_ALL: All the useful interrupts mask | 691 | * @IDT_NTINTMSK_ALL: NTB-related interrupts mask |
| 692 | */ | 692 | */ |
| 693 | #define IDT_NTINTMSK_MSG 0x00000001U | 693 | #define IDT_NTINTMSK_MSG 0x00000001U |
| 694 | #define IDT_NTINTMSK_DBELL 0x00000002U | 694 | #define IDT_NTINTMSK_DBELL 0x00000002U |
| 695 | #define IDT_NTINTMSK_SEVENT 0x00000008U | 695 | #define IDT_NTINTMSK_SEVENT 0x00000008U |
| 696 | #define IDT_NTINTMSK_TMPSENSOR 0x00000080U | 696 | #define IDT_NTINTMSK_TMPSENSOR 0x00000080U |
| 697 | #define IDT_NTINTMSK_ALL \ | 697 | #define IDT_NTINTMSK_ALL \ |
| 698 | (IDT_NTINTMSK_MSG | IDT_NTINTMSK_DBELL | \ | 698 | (IDT_NTINTMSK_MSG | IDT_NTINTMSK_DBELL | IDT_NTINTMSK_SEVENT) |
| 699 | IDT_NTINTMSK_SEVENT | IDT_NTINTMSK_TMPSENSOR) | ||
| 700 | 699 | ||
| 701 | /* | 700 | /* |
| 702 | * NTGSIGNAL register fields related constants | 701 | * NTGSIGNAL register fields related constants |
| @@ -886,12 +885,60 @@ | |||
| 886 | #define IDT_SWPxMSGCTL_PART_FLD 4 | 885 | #define IDT_SWPxMSGCTL_PART_FLD 4 |
| 887 | 886 | ||
| 888 | /* | 887 | /* |
| 888 | * TMPCTL register fields related constants | ||
| 889 | * @IDT_TMPCTL_LTH_MASK: Low temperature threshold field mask | ||
| 890 | * @IDT_TMPCTL_LTH_FLD: Low temperature threshold field offset | ||
| 891 | * @IDT_TMPCTL_MTH_MASK: Middle temperature threshold field mask | ||
| 892 | * @IDT_TMPCTL_MTH_FLD: Middle temperature threshold field offset | ||
| 893 | * @IDT_TMPCTL_HTH_MASK: High temperature threshold field mask | ||
| 894 | * @IDT_TMPCTL_HTH_FLD: High temperature threshold field offset | ||
| 895 | * @IDT_TMPCTL_PDOWN: Temperature sensor power down | ||
| 896 | */ | ||
| 897 | #define IDT_TMPCTL_LTH_MASK 0x000000FFU | ||
| 898 | #define IDT_TMPCTL_LTH_FLD 0 | ||
| 899 | #define IDT_TMPCTL_MTH_MASK 0x0000FF00U | ||
| 900 | #define IDT_TMPCTL_MTH_FLD 8 | ||
| 901 | #define IDT_TMPCTL_HTH_MASK 0x00FF0000U | ||
| 902 | #define IDT_TMPCTL_HTH_FLD 16 | ||
| 903 | #define IDT_TMPCTL_PDOWN 0x80000000U | ||
| 904 | |||
| 905 | /* | ||
| 889 | * TMPSTS register fields related constants | 906 | * TMPSTS register fields related constants |
| 890 | * @IDT_TMPSTS_TEMP_MASK: Current temperature field mask | 907 | * @IDT_TMPSTS_TEMP_MASK: Current temperature field mask |
| 891 | * @IDT_TMPSTS_TEMP_FLD: Current temperature field offset | 908 | * @IDT_TMPSTS_TEMP_FLD: Current temperature field offset |
| 909 | * @IDT_TMPSTS_LTEMP_MASK: Lowest temperature field mask | ||
| 910 | * @IDT_TMPSTS_LTEMP_FLD: Lowest temperature field offset | ||
| 911 | * @IDT_TMPSTS_HTEMP_MASK: Highest temperature field mask | ||
| 912 | * @IDT_TMPSTS_HTEMP_FLD: Highest temperature field offset | ||
| 892 | */ | 913 | */ |
| 893 | #define IDT_TMPSTS_TEMP_MASK 0x000000FFU | 914 | #define IDT_TMPSTS_TEMP_MASK 0x000000FFU |
| 894 | #define IDT_TMPSTS_TEMP_FLD 0 | 915 | #define IDT_TMPSTS_TEMP_FLD 0 |
| 916 | #define IDT_TMPSTS_LTEMP_MASK 0x0000FF00U | ||
| 917 | #define IDT_TMPSTS_LTEMP_FLD 8 | ||
| 918 | #define IDT_TMPSTS_HTEMP_MASK 0x00FF0000U | ||
| 919 | #define IDT_TMPSTS_HTEMP_FLD 16 | ||
| 920 | |||
| 921 | /* | ||
| 922 | * TMPALARM register fields related constants | ||
| 923 | * @IDT_TMPALARM_LTEMP_MASK: Lowest temperature field mask | ||
| 924 | * @IDT_TMPALARM_LTEMP_FLD: Lowest temperature field offset | ||
| 925 | * @IDT_TMPALARM_HTEMP_MASK: Highest temperature field mask | ||
| 926 | * @IDT_TMPALARM_HTEMP_FLD: Highest temperature field offset | ||
| 927 | * @IDT_TMPALARM_IRQ_MASK: Alarm IRQ status mask | ||
| 928 | */ | ||
| 929 | #define IDT_TMPALARM_LTEMP_MASK 0x0000FF00U | ||
| 930 | #define IDT_TMPALARM_LTEMP_FLD 8 | ||
| 931 | #define IDT_TMPALARM_HTEMP_MASK 0x00FF0000U | ||
| 932 | #define IDT_TMPALARM_HTEMP_FLD 16 | ||
| 933 | #define IDT_TMPALARM_IRQ_MASK 0x3F000000U | ||
| 934 | |||
| 935 | /* | ||
| 936 | * TMPADJ register fields related constants | ||
| 937 | * @IDT_TMPADJ_OFFSET_MASK: Temperature value offset field mask | ||
| 938 | * @IDT_TMPADJ_OFFSET_FLD: Temperature value offset field offset | ||
| 939 | */ | ||
| 940 | #define IDT_TMPADJ_OFFSET_MASK 0x000000FFU | ||
| 941 | #define IDT_TMPADJ_OFFSET_FLD 0 | ||
| 895 | 942 | ||
| 896 | /* | 943 | /* |
| 897 | * Helper macro to get/set the corresponding field value | 944 | * Helper macro to get/set the corresponding field value |
| @@ -951,6 +998,32 @@ | |||
| 951 | #define IDT_DIR_SIZE_ALIGN 1 | 998 | #define IDT_DIR_SIZE_ALIGN 1 |
| 952 | 999 | ||
| 953 | /* | 1000 | /* |
| 1001 | * IDT PCIe-switch temperature sensor value limits | ||
| 1002 | * @IDT_TEMP_MIN_MDEG: Minimal integer value of temperature | ||
| 1003 | * @IDT_TEMP_MAX_MDEG: Maximal integer value of temperature | ||
| 1004 | * @IDT_TEMP_MIN_OFFSET:Minimal integer value of temperature offset | ||
| 1005 | * @IDT_TEMP_MAX_OFFSET:Maximal integer value of temperature offset | ||
| 1006 | */ | ||
| 1007 | #define IDT_TEMP_MIN_MDEG 0 | ||
| 1008 | #define IDT_TEMP_MAX_MDEG 127500 | ||
| 1009 | #define IDT_TEMP_MIN_OFFSET -64000 | ||
| 1010 | #define IDT_TEMP_MAX_OFFSET 63500 | ||
| 1011 | |||
| 1012 | /* | ||
| 1013 | * Temperature sensor values enumeration | ||
| 1014 | * @IDT_TEMP_CUR: Current temperature | ||
| 1015 | * @IDT_TEMP_LOW: Lowest historical temperature | ||
| 1016 | * @IDT_TEMP_HIGH: Highest historical temperature | ||
| 1017 | * @IDT_TEMP_OFFSET: Current temperature offset | ||
| 1018 | */ | ||
| 1019 | enum idt_temp_val { | ||
| 1020 | IDT_TEMP_CUR, | ||
| 1021 | IDT_TEMP_LOW, | ||
| 1022 | IDT_TEMP_HIGH, | ||
| 1023 | IDT_TEMP_OFFSET | ||
| 1024 | }; | ||
| 1025 | |||
| 1026 | /* | ||
| 954 | * IDT Memory Windows type. Depending on the device settings, IDT supports | 1027 | * IDT Memory Windows type. Depending on the device settings, IDT supports |
| 955 | * Direct Address Translation MW registers and Lookup Table registers | 1028 | * Direct Address Translation MW registers and Lookup Table registers |
| 956 | * @IDT_MW_DIR: Direct address translation | 1029 | * @IDT_MW_DIR: Direct address translation |
| @@ -1044,6 +1117,8 @@ struct idt_ntb_peer { | |||
| 1044 | * @msg_mask_lock: Message mask register lock | 1117 | * @msg_mask_lock: Message mask register lock |
| 1045 | * @gasa_lock: GASA registers access lock | 1118 | * @gasa_lock: GASA registers access lock |
| 1046 | * | 1119 | * |
| 1120 | * @hwmon_mtx: Temperature sensor interface update mutex | ||
| 1121 | * | ||
| 1047 | * @dbgfs_info: DebugFS info node | 1122 | * @dbgfs_info: DebugFS info node |
| 1048 | */ | 1123 | */ |
| 1049 | struct idt_ntb_dev { | 1124 | struct idt_ntb_dev { |
| @@ -1071,6 +1146,8 @@ struct idt_ntb_dev { | |||
| 1071 | spinlock_t msg_mask_lock; | 1146 | spinlock_t msg_mask_lock; |
| 1072 | spinlock_t gasa_lock; | 1147 | spinlock_t gasa_lock; |
| 1073 | 1148 | ||
| 1149 | struct mutex hwmon_mtx; | ||
| 1150 | |||
| 1074 | struct dentry *dbgfs_info; | 1151 | struct dentry *dbgfs_info; |
| 1075 | }; | 1152 | }; |
| 1076 | #define to_ndev_ntb(__ntb) container_of(__ntb, struct idt_ntb_dev, ntb) | 1153 | #define to_ndev_ntb(__ntb) container_of(__ntb, struct idt_ntb_dev, ntb) |
diff --git a/drivers/ntb/hw/intel/ntb_hw_gen1.c b/drivers/ntb/hw/intel/ntb_hw_gen1.c index 6aa573227279..2ad263f708da 100644 --- a/drivers/ntb/hw/intel/ntb_hw_gen1.c +++ b/drivers/ntb/hw/intel/ntb_hw_gen1.c | |||
| @@ -265,7 +265,7 @@ static inline int ndev_db_clear_mask(struct intel_ntb_dev *ndev, u64 db_bits, | |||
| 265 | return 0; | 265 | return 0; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | static inline int ndev_vec_mask(struct intel_ntb_dev *ndev, int db_vector) | 268 | static inline u64 ndev_vec_mask(struct intel_ntb_dev *ndev, int db_vector) |
| 269 | { | 269 | { |
| 270 | u64 shift, mask; | 270 | u64 shift, mask; |
| 271 | 271 | ||
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index 939895966476..3bfdb4562408 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c | |||
| @@ -194,6 +194,8 @@ struct ntb_transport_mw { | |||
| 194 | void __iomem *vbase; | 194 | void __iomem *vbase; |
| 195 | size_t xlat_size; | 195 | size_t xlat_size; |
| 196 | size_t buff_size; | 196 | size_t buff_size; |
| 197 | size_t alloc_size; | ||
| 198 | void *alloc_addr; | ||
| 197 | void *virt_addr; | 199 | void *virt_addr; |
| 198 | dma_addr_t dma_addr; | 200 | dma_addr_t dma_addr; |
| 199 | }; | 201 | }; |
| @@ -672,13 +674,59 @@ static void ntb_free_mw(struct ntb_transport_ctx *nt, int num_mw) | |||
| 672 | return; | 674 | return; |
| 673 | 675 | ||
| 674 | ntb_mw_clear_trans(nt->ndev, PIDX, num_mw); | 676 | ntb_mw_clear_trans(nt->ndev, PIDX, num_mw); |
| 675 | dma_free_coherent(&pdev->dev, mw->buff_size, | 677 | dma_free_coherent(&pdev->dev, mw->alloc_size, |
| 676 | mw->virt_addr, mw->dma_addr); | 678 | mw->alloc_addr, mw->dma_addr); |
| 677 | mw->xlat_size = 0; | 679 | mw->xlat_size = 0; |
| 678 | mw->buff_size = 0; | 680 | mw->buff_size = 0; |
| 681 | mw->alloc_size = 0; | ||
| 682 | mw->alloc_addr = NULL; | ||
| 679 | mw->virt_addr = NULL; | 683 | mw->virt_addr = NULL; |
| 680 | } | 684 | } |
| 681 | 685 | ||
| 686 | static int ntb_alloc_mw_buffer(struct ntb_transport_mw *mw, | ||
| 687 | struct device *dma_dev, size_t align) | ||
| 688 | { | ||
| 689 | dma_addr_t dma_addr; | ||
| 690 | void *alloc_addr, *virt_addr; | ||
| 691 | int rc; | ||
| 692 | |||
| 693 | alloc_addr = dma_alloc_coherent(dma_dev, mw->alloc_size, | ||
| 694 | &dma_addr, GFP_KERNEL); | ||
| 695 | if (!alloc_addr) { | ||
| 696 | dev_err(dma_dev, "Unable to alloc MW buff of size %zu\n", | ||
| 697 | mw->alloc_size); | ||
| 698 | return -ENOMEM; | ||
| 699 | } | ||
| 700 | virt_addr = alloc_addr; | ||
| 701 | |||
| 702 | /* | ||
| 703 | * we must ensure that the memory address allocated is BAR size | ||
| 704 | * aligned in order for the XLAT register to take the value. This | ||
| 705 | * is a requirement of the hardware. It is recommended to setup CMA | ||
| 706 | * for BAR sizes equal or greater than 4MB. | ||
| 707 | */ | ||
| 708 | if (!IS_ALIGNED(dma_addr, align)) { | ||
| 709 | if (mw->alloc_size > mw->buff_size) { | ||
| 710 | virt_addr = PTR_ALIGN(alloc_addr, align); | ||
| 711 | dma_addr = ALIGN(dma_addr, align); | ||
| 712 | } else { | ||
| 713 | rc = -ENOMEM; | ||
| 714 | goto err; | ||
| 715 | } | ||
| 716 | } | ||
| 717 | |||
| 718 | mw->alloc_addr = alloc_addr; | ||
| 719 | mw->virt_addr = virt_addr; | ||
| 720 | mw->dma_addr = dma_addr; | ||
| 721 | |||
| 722 | return 0; | ||
| 723 | |||
| 724 | err: | ||
| 725 | dma_free_coherent(dma_dev, mw->alloc_size, alloc_addr, dma_addr); | ||
| 726 | |||
| 727 | return rc; | ||
| 728 | } | ||
| 729 | |||
| 682 | static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw, | 730 | static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw, |
| 683 | resource_size_t size) | 731 | resource_size_t size) |
| 684 | { | 732 | { |
| @@ -710,28 +758,20 @@ static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw, | |||
| 710 | /* Alloc memory for receiving data. Must be aligned */ | 758 | /* Alloc memory for receiving data. Must be aligned */ |
| 711 | mw->xlat_size = xlat_size; | 759 | mw->xlat_size = xlat_size; |
| 712 | mw->buff_size = buff_size; | 760 | mw->buff_size = buff_size; |
| 761 | mw->alloc_size = buff_size; | ||
| 713 | 762 | ||
| 714 | mw->virt_addr = dma_alloc_coherent(&pdev->dev, buff_size, | 763 | rc = ntb_alloc_mw_buffer(mw, &pdev->dev, xlat_align); |
| 715 | &mw->dma_addr, GFP_KERNEL); | 764 | if (rc) { |
| 716 | if (!mw->virt_addr) { | 765 | mw->alloc_size *= 2; |
| 717 | mw->xlat_size = 0; | 766 | rc = ntb_alloc_mw_buffer(mw, &pdev->dev, xlat_align); |
| 718 | mw->buff_size = 0; | 767 | if (rc) { |
| 719 | dev_err(&pdev->dev, "Unable to alloc MW buff of size %zu\n", | 768 | dev_err(&pdev->dev, |
| 720 | buff_size); | 769 | "Unable to alloc aligned MW buff\n"); |
| 721 | return -ENOMEM; | 770 | mw->xlat_size = 0; |
| 722 | } | 771 | mw->buff_size = 0; |
| 723 | 772 | mw->alloc_size = 0; | |
| 724 | /* | 773 | return rc; |
| 725 | * we must ensure that the memory address allocated is BAR size | 774 | } |
| 726 | * aligned in order for the XLAT register to take the value. This | ||
| 727 | * is a requirement of the hardware. It is recommended to setup CMA | ||
| 728 | * for BAR sizes equal or greater than 4MB. | ||
| 729 | */ | ||
| 730 | if (!IS_ALIGNED(mw->dma_addr, xlat_align)) { | ||
| 731 | dev_err(&pdev->dev, "DMA memory %pad is not aligned\n", | ||
| 732 | &mw->dma_addr); | ||
| 733 | ntb_free_mw(nt, num_mw); | ||
| 734 | return -ENOMEM; | ||
| 735 | } | 775 | } |
| 736 | 776 | ||
| 737 | /* Notify HW the memory location of the receive buffer */ | 777 | /* Notify HW the memory location of the receive buffer */ |
| @@ -1278,6 +1318,7 @@ static void ntb_rx_copy_callback(void *data, | |||
| 1278 | case DMA_TRANS_READ_FAILED: | 1318 | case DMA_TRANS_READ_FAILED: |
| 1279 | case DMA_TRANS_WRITE_FAILED: | 1319 | case DMA_TRANS_WRITE_FAILED: |
| 1280 | entry->errors++; | 1320 | entry->errors++; |
| 1321 | /* fall through */ | ||
| 1281 | case DMA_TRANS_ABORTED: | 1322 | case DMA_TRANS_ABORTED: |
| 1282 | { | 1323 | { |
| 1283 | struct ntb_transport_qp *qp = entry->qp; | 1324 | struct ntb_transport_qp *qp = entry->qp; |
| @@ -1533,6 +1574,7 @@ static void ntb_tx_copy_callback(void *data, | |||
| 1533 | case DMA_TRANS_READ_FAILED: | 1574 | case DMA_TRANS_READ_FAILED: |
| 1534 | case DMA_TRANS_WRITE_FAILED: | 1575 | case DMA_TRANS_WRITE_FAILED: |
| 1535 | entry->errors++; | 1576 | entry->errors++; |
| 1577 | /* fall through */ | ||
| 1536 | case DMA_TRANS_ABORTED: | 1578 | case DMA_TRANS_ABORTED: |
| 1537 | { | 1579 | { |
| 1538 | void __iomem *offset = | 1580 | void __iomem *offset = |
