forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request sonic-net#233 from keboliu/hw-mgmt-3134
[Mellanox] Backport kernel patches coming along with Mellanox hw-mgmt package release V.7.0010.3134 Backport kernel patches come along with Mellanox hw-mgmt package release V.7.0010.3134: V5.14-rc1 includes all following patches. | Patch name | Commit hash | | -----------------------------------------------------| ------------------------------------------------------------------------------------------ | |0033-i2c-mlxcpld-Update-module-license.patch | torvalds/linux@f069291 | |0034-i2c-mlxcpld-Add-support-for-I2C-bus-frequency-settin.patch | torvalds/linux@66b0c28 | |0035-i2c-mux-mlxcpld-Update-module-license.patch | torvalds/linux@337bc68 | |0036-i2c-mux-mlxcpld-Move-header-file-out-of-x86-realm.patch | torvalds/linux@98d29c4 | |0037-platform-x86-mlxcpld-Update-module-license.patch | torvalds/linux@9ff0c6d | |0038-i2c-mux-mlxcpld-Convert-driver-to-platform-driver.patch | torvalds/linux@84af1b1 | |0039-i2c-mux-mlxcpld-Prepare-mux-selection-infrastructure.patch | torvalds/linux@8156693 | |0040-i2c-mux-mlxcpld-Get-rid-of-adapter-numbers-enforceme.patch | torvalds/linux@cae5216 | |0041-i2c-mux-mlxcpld-Extend-driver-to-support-word-addres.patch | torvalds/linux@c52a1c5 | |0042-i2c-mux-mlxcpld-Extend-supported-mux-number.patch | torvalds/linux@699c050 | |0043-i2c-mux-mlxcpld-Add-callback-to-notify-mux-creation-.patch | torvalds/linux@a39bd92 | |0044-platform-x86-mlx-platform-remove-an-unused-variable.patch | torvalds/linux@eca6ba2 | |0045-platform-x86-mlx-platform-Fix-item-counter-assignmen.patch | torvalds/linux@ba4939f | |0046-platform-x86-mlx-platform-Fix-item-counter-assignmen.patch | torvalds/linux@cf79177 | |0047-mlxsw-core-Set-thermal-zone-polling-delay-argument-t.patch | torvalds/linux@2fd8d84 | |0048-mlxsw-reg-Extend-MTMP-register-with-new-threshold-fi.patch | torvalds/linux@314dbb1 | |0049-mlxsw-core_env-Read-module-temperature-thresholds-us.patch | torvalds/linux@befc204 | |0050-mlxsw-thermal-Add-function-for-reading-module-temper.patch | torvalds/linux@e57977b | |0051-mlxsw-thermal-Read-module-temperature-thresholds-usi.patch | torvalds/linux@72a64c2 | Full regression tests have been run on Mellanox platforms
Showing
20 changed files
with
1,623 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
From 9df799e9857cf0cdd04f7709793078cbd1a4d9bb Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Thu, 10 Dec 2020 18:51:11 +0200 | ||
Subject: [PATCH backport 4.19 01/11] i2c: mlxcpld: Update module license | ||
|
||
commit f069291bd5fcb85c6eb53f9b1ab23bcfcaad93f2 upstream | ||
|
||
Update license to SPDX-License. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Signed-off-by: Wolfram Sang <wsa@kernel.org> | ||
--- | ||
drivers/i2c/busses/i2c-mlxcpld.c | 32 +++----------------------------- | ||
1 file changed, 3 insertions(+), 29 deletions(-) | ||
|
||
diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c | ||
index 6da4b58eee4f..ae0d17513422 100644 | ||
--- a/drivers/i2c/busses/i2c-mlxcpld.c | ||
+++ b/drivers/i2c/busses/i2c-mlxcpld.c | ||
@@ -1,34 +1,8 @@ | ||
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 | ||
/* | ||
- * Copyright (c) 2016 Mellanox Technologies. All rights reserved. | ||
- * Copyright (c) 2016 Michael Shych <michaels@mellanox.com> | ||
+ * Mellanox i2c driver | ||
* | ||
- * Redistribution and use in source and binary forms, with or without | ||
- * modification, are permitted provided that the following conditions are met: | ||
- * | ||
- * 1. Redistributions of source code must retain the above copyright | ||
- * notice, this list of conditions and the following disclaimer. | ||
- * 2. Redistributions in binary form must reproduce the above copyright | ||
- * notice, this list of conditions and the following disclaimer in the | ||
- * documentation and/or other materials provided with the distribution. | ||
- * 3. Neither the names of the copyright holders nor the names of its | ||
- * contributors may be used to endorse or promote products derived from | ||
- * this software without specific prior written permission. | ||
- * | ||
- * Alternatively, this software may be distributed under the terms of the | ||
- * GNU General Public License ("GPL") version 2 as published by the Free | ||
- * Software Foundation. | ||
- * | ||
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
- * POSSIBILITY OF SUCH DAMAGE. | ||
+ * Copyright (C) 2016-2020 Mellanox Technologies | ||
*/ | ||
|
||
#include <linux/delay.h> | ||
-- | ||
2.11.0 | ||
|
131 changes: 131 additions & 0 deletions
131
patch/0034-i2c-mlxcpld-Add-support-for-I2C-bus-frequency-settin.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
From cb4de56f5b1551eb925329beb4277048a8ba821f Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Wed, 6 Jan 2021 01:33:47 +0200 | ||
|
||
commit 66b0c2846ba8de569026a067bb5a34ea5768408c upstream | ||
|
||
Subject: [PATCH backport 4.19 02/11] i2c: mlxcpld: Add support for I2C bus | ||
frequency setting | ||
|
||
Add support for I2C bus frequency setting according to the specific | ||
system capability. This capability is obtained from CPLD frequency | ||
setting register, which could be provided through the platform data. | ||
If such register is provided, it specifies minimal I2C bus frequency | ||
to be used for the devices attached to the I2C bus. Supported | ||
freqeuncies are 100KHz, 400KHz, 1MHz, while 100KHz is the default. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Signed-off-by: Wolfram Sang <wsa@kernel.org> | ||
--- | ||
drivers/i2c/busses/i2c-mlxcpld.c | 63 +++++++++++++++++++++++++++++++++++++++- | ||
1 file changed, 62 insertions(+), 1 deletion(-) | ||
|
||
diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c | ||
index ae0d17513422..fa8cc0b71531 100644 | ||
--- a/drivers/i2c/busses/i2c-mlxcpld.c | ||
+++ b/drivers/i2c/busses/i2c-mlxcpld.c | ||
@@ -11,7 +11,9 @@ | ||
#include <linux/io.h> | ||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
+#include <linux/platform_data/mlxreg.h> | ||
#include <linux/platform_device.h> | ||
+#include <linux/regmap.h> | ||
|
||
/* General defines */ | ||
#define MLXPLAT_CPLD_LPC_I2C_BASE_ADDR 0x2000 | ||
@@ -46,6 +48,16 @@ | ||
#define MLXCPLD_LPCI2C_ACK_IND 1 | ||
#define MLXCPLD_LPCI2C_NACK_IND 2 | ||
|
||
+#define MLXCPLD_I2C_FREQ_1000KHZ_SET 0x04 | ||
+#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0f | ||
+#define MLXCPLD_I2C_FREQ_100KHZ_SET 0x42 | ||
+ | ||
+enum mlxcpld_i2c_frequency { | ||
+ MLXCPLD_I2C_FREQ_1000KHZ = 1, | ||
+ MLXCPLD_I2C_FREQ_400KHZ = 2, | ||
+ MLXCPLD_I2C_FREQ_100KHZ = 3, | ||
+}; | ||
+ | ||
struct mlxcpld_i2c_curr_xfer { | ||
u8 cmd; | ||
u8 addr_width; | ||
@@ -463,8 +475,45 @@ static struct i2c_adapter mlxcpld_i2c_adapter = { | ||
.nr = MLXCPLD_I2C_BUS_NUM, | ||
}; | ||
|
||
+static int | ||
+mlxcpld_i2c_set_frequency(struct mlxcpld_i2c_priv *priv, | ||
+ struct mlxreg_core_hotplug_platform_data *pdata) | ||
+{ | ||
+ struct mlxreg_core_item *item = pdata->items; | ||
+ struct mlxreg_core_data *data; | ||
+ u32 regval; | ||
+ u8 freq; | ||
+ int err; | ||
+ | ||
+ if (!item) | ||
+ return 0; | ||
+ | ||
+ /* Read frequency setting. */ | ||
+ data = item->data; | ||
+ err = regmap_read(pdata->regmap, data->reg, ®val); | ||
+ if (err) | ||
+ return err; | ||
+ | ||
+ /* Set frequency only if it is not 100KHz, which is default. */ | ||
+ switch ((data->reg & data->mask) >> data->bit) { | ||
+ case MLXCPLD_I2C_FREQ_1000KHZ: | ||
+ freq = MLXCPLD_I2C_FREQ_1000KHZ_SET; | ||
+ break; | ||
+ case MLXCPLD_I2C_FREQ_400KHZ: | ||
+ freq = MLXCPLD_I2C_FREQ_400KHZ_SET; | ||
+ break; | ||
+ default: | ||
+ return 0; | ||
+ } | ||
+ | ||
+ mlxcpld_i2c_write_comm(priv, MLXCPLD_LPCI2C_HALF_CYC_REG, &freq, 1); | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
static int mlxcpld_i2c_probe(struct platform_device *pdev) | ||
{ | ||
+ struct mlxreg_core_hotplug_platform_data *pdata; | ||
struct mlxcpld_i2c_priv *priv; | ||
int err; | ||
u8 val; | ||
@@ -479,6 +528,14 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev) | ||
priv->dev = &pdev->dev; | ||
priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR; | ||
|
||
+ /* Set I2C bus frequency if platform data provides this info. */ | ||
+ pdata = dev_get_platdata(&pdev->dev); | ||
+ if (pdata) { | ||
+ err = mlxcpld_i2c_set_frequency(priv, pdata); | ||
+ if (err) | ||
+ goto mlxcpld_i2_probe_failed; | ||
+ } | ||
+ | ||
/* Register with i2c layer */ | ||
mlxcpld_i2c_adapter.timeout = usecs_to_jiffies(MLXCPLD_I2C_XFER_TO); | ||
/* Read capability register */ | ||
@@ -497,8 +554,12 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev) | ||
|
||
err = i2c_add_numbered_adapter(&priv->adap); | ||
if (err) | ||
- mutex_destroy(&priv->lock); | ||
+ goto mlxcpld_i2_probe_failed; | ||
|
||
+ return 0; | ||
+ | ||
+mlxcpld_i2_probe_failed: | ||
+ mutex_destroy(&priv->lock); | ||
return err; | ||
} | ||
|
||
-- | ||
2.11.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
From 49611e8c60944021657bbf056aa746363079c9d4 Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Fri, 22 Jan 2021 21:24:56 +0200 | ||
|
||
commit 337bc68c294dd42538409f2a37b3daad2c851f98 upstream | ||
|
||
Subject: [PATCH backport 4.19 03/11] i2c: mux: mlxcpld: Update module license | ||
|
||
Update license to SPDX-License. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Acked-by: Peter Rosin <peda@axentia.se> | ||
Signed-off-by: Wolfram Sang <wsa@kernel.org> | ||
--- | ||
drivers/i2c/muxes/i2c-mux-mlxcpld.c | 33 +++------------------------------ | ||
1 file changed, 3 insertions(+), 30 deletions(-) | ||
|
||
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
index f2bf3e57ed67..c9a94abcb6be 100644 | ||
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
@@ -1,35 +1,8 @@ | ||
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 | ||
/* | ||
- * drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
- * Copyright (c) 2016 Mellanox Technologies. All rights reserved. | ||
- * Copyright (c) 2016 Michael Shych <michaels@mellanox.com> | ||
+ * Mellanox i2c mux driver | ||
* | ||
- * Redistribution and use in source and binary forms, with or without | ||
- * modification, are permitted provided that the following conditions are met: | ||
- * | ||
- * 1. Redistributions of source code must retain the above copyright | ||
- * notice, this list of conditions and the following disclaimer. | ||
- * 2. Redistributions in binary form must reproduce the above copyright | ||
- * notice, this list of conditions and the following disclaimer in the | ||
- * documentation and/or other materials provided with the distribution. | ||
- * 3. Neither the names of the copyright holders nor the names of its | ||
- * contributors may be used to endorse or promote products derived from | ||
- * this software without specific prior written permission. | ||
- * | ||
- * Alternatively, this software may be distributed under the terms of the | ||
- * GNU General Public License ("GPL") version 2 as published by the Free | ||
- * Software Foundation. | ||
- * | ||
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
- * POSSIBILITY OF SUCH DAMAGE. | ||
+ * Copyright (C) 2016-2020 Mellanox Technologies | ||
*/ | ||
|
||
#include <linux/device.h> | ||
-- | ||
2.11.0 | ||
|
43 changes: 43 additions & 0 deletions
43
patch/0036-i2c-mux-mlxcpld-Move-header-file-out-of-x86-realm.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
From 62165c690ee56554693ac14fc7bd0e260389a2f5 Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Fri, 22 Jan 2021 21:24:58 +0200 | ||
|
||
commit 98d29c410475f30b627502d845794352e9be4046 upstream | ||
|
||
Subject: [PATCH backport 4.19 04/11] i2c: mux: mlxcpld: Move header file out | ||
of x86 realm | ||
|
||
Move out header file from include/linux/platform_data/x86/ to | ||
include/linux/platform_data/, since it does not depend on x86 | ||
architecture. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Reviewed-by: Michael Shych <michaelsh@nvidia.com> | ||
Acked-by: Peter Rosin <peda@axentia.se> | ||
Signed-off-by: Wolfram Sang <wsa@kernel.org> | ||
--- | ||
drivers/i2c/muxes/i2c-mux-mlxcpld.c | 2 +- | ||
include/linux/platform_data/{x86 => }/mlxcpld.h | 0 | ||
2 files changed, 1 insertion(+), 1 deletion(-) | ||
rename include/linux/platform_data/{x86 => }/mlxcpld.h (100%) | ||
|
||
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
index c9a94abcb6be..be2d0fa24096 100644 | ||
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
@@ -11,7 +11,7 @@ | ||
#include <linux/io.h> | ||
#include <linux/init.h> | ||
#include <linux/module.h> | ||
-#include <linux/platform_data/x86/mlxcpld.h> | ||
+#include <linux/platform_data/mlxcpld.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/slab.h> | ||
|
||
diff --git a/include/linux/platform_data/x86/mlxcpld.h b/include/linux/platform_data/mlxcpld.h | ||
similarity index 100% | ||
rename from include/linux/platform_data/x86/mlxcpld.h | ||
rename to include/linux/platform_data/mlxcpld.h | ||
-- | ||
2.11.0 | ||
|
63 changes: 63 additions & 0 deletions
63
patch/0037-platform-x86-mlxcpld-Update-module-license.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
From 1b3ca3f6dac2f45e727f946ab8063c1f65ad51ec Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Sun, 7 Feb 2021 20:51:32 +0200 | ||
|
||
commit 9ff0c6db0605e9b88360048c8d0a6a9ff647eb71 upstream | ||
|
||
Subject: [PATCH backport 4.19 05/11] platform/x86: mlxcpld: Update module | ||
license | ||
|
||
Update license to SPDX-License. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
--- | ||
include/linux/platform_data/mlxcpld.h | 34 +++------------------------------- | ||
1 file changed, 3 insertions(+), 31 deletions(-) | ||
|
||
diff --git a/include/linux/platform_data/mlxcpld.h b/include/linux/platform_data/mlxcpld.h | ||
index b08dcb183fca..e6c18bf017dd 100644 | ||
--- a/include/linux/platform_data/mlxcpld.h | ||
+++ b/include/linux/platform_data/mlxcpld.h | ||
@@ -1,36 +1,8 @@ | ||
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ | ||
/* | ||
- * mlxcpld.h - Mellanox I2C multiplexer support in CPLD | ||
+ * Mellanox I2C multiplexer support in CPLD | ||
* | ||
- * Copyright (c) 2016 Mellanox Technologies. All rights reserved. | ||
- * Copyright (c) 2016 Michael Shych <michaels@mellanox.com> | ||
- * | ||
- * Redistribution and use in source and binary forms, with or without | ||
- * modification, are permitted provided that the following conditions are met: | ||
- * | ||
- * 1. Redistributions of source code must retain the above copyright | ||
- * notice, this list of conditions and the following disclaimer. | ||
- * 2. Redistributions in binary form must reproduce the above copyright | ||
- * notice, this list of conditions and the following disclaimer in the | ||
- * documentation and/or other materials provided with the distribution. | ||
- * 3. Neither the names of the copyright holders nor the names of its | ||
- * contributors may be used to endorse or promote products derived from | ||
- * this software without specific prior written permission. | ||
- * | ||
- * Alternatively, this software may be distributed under the terms of the | ||
- * GNU General Public License ("GPL") version 2 as published by the Free | ||
- * Software Foundation. | ||
- * | ||
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
- * POSSIBILITY OF SUCH DAMAGE. | ||
+ * Copyright (C) 2016-2020 Mellanox Technologies | ||
*/ | ||
|
||
#ifndef _LINUX_I2C_MLXCPLD_H | ||
-- | ||
2.11.0 | ||
|
186 changes: 186 additions & 0 deletions
186
patch/0038-i2c-mux-mlxcpld-Convert-driver-to-platform-driver.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
From d08adf371eafde3a772a2c433b1bbfcf1a14caae Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Sun, 7 Feb 2021 21:17:09 +0200 | ||
|
||
commit 84af1b168c5015fca0761cf9cce4add31e354dce upstream | ||
|
||
Subject: [PATCH backport 4.19 06/11] i2c: mux: mlxcpld: Convert driver to | ||
platform driver | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=UTF-8 | ||
Content-Transfer-Encoding: 8bit | ||
|
||
Convert driver from 'i2c' to 'platform'. | ||
The motivation is to avoid I2C addressing conflict between | ||
‘i2c-mux-cpld’ driver, providing mux selection and deselection through | ||
CPLD ‘mux control’ register, and CPLD host driver. The CPLD is I2C | ||
device and is multi-functional device performing logic for different | ||
components, like LED, ‘hwmon’, interrupt control, watchdog etcetera. | ||
For such configuration CPLD should be host I2C device, connected to the | ||
relevant I2C bus with the relevant I2C address and all others component | ||
drivers are supposed to be its children. | ||
The hierarchy in such case will be like in the below example: | ||
ls /sys/bus/i2c/devices/44-0032 | ||
i2c-mux-mlxcpld.44 leds-mlxreg.44 mlxreg-io.44 | ||
ls /sys/bus/i2c/devices/44-0032/i2c-mux-mlxcpld.44 | ||
channel-0, …, channel-X | ||
|
||
Currently this driver is not activated by any kernel driver, | ||
so this conversion doesn’t affect any user. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Reviewed-by: Michael Shych <michaelsh@nvidia.com> | ||
--- | ||
drivers/i2c/muxes/i2c-mux-mlxcpld.c | 62 +++++++++++++++++-------------------- | ||
1 file changed, 28 insertions(+), 34 deletions(-) | ||
|
||
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
index be2d0fa24096..b53f1479272d 100644 | ||
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
@@ -20,10 +20,12 @@ | ||
/* mlxcpld_mux - mux control structure: | ||
* @last_chan - last register value | ||
* @client - I2C device client | ||
+ * @pdata: platform data | ||
*/ | ||
struct mlxcpld_mux { | ||
u8 last_chan; | ||
struct i2c_client *client; | ||
+ struct mlxcpld_mux_plat_data pdata; | ||
}; | ||
|
||
/* MUX logic description. | ||
@@ -54,37 +56,30 @@ struct mlxcpld_mux { | ||
* | ||
*/ | ||
|
||
-static const struct i2c_device_id mlxcpld_mux_id[] = { | ||
- { "mlxcpld_mux_module", 0 }, | ||
- { } | ||
-}; | ||
-MODULE_DEVICE_TABLE(i2c, mlxcpld_mux_id); | ||
- | ||
/* Write to mux register. Don't use i2c_transfer() and i2c_smbus_xfer() | ||
* for this as they will try to lock adapter a second time. | ||
*/ | ||
static int mlxcpld_mux_reg_write(struct i2c_adapter *adap, | ||
- struct i2c_client *client, u8 val) | ||
+ struct mlxcpld_mux *mux, u8 val) | ||
{ | ||
- struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev); | ||
+ struct i2c_client *client = mux->client; | ||
union i2c_smbus_data data = { .byte = val }; | ||
|
||
return __i2c_smbus_xfer(adap, client->addr, client->flags, | ||
- I2C_SMBUS_WRITE, pdata->sel_reg_addr, | ||
+ I2C_SMBUS_WRITE, mux->pdata.sel_reg_addr, | ||
I2C_SMBUS_BYTE_DATA, &data); | ||
} | ||
|
||
static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan) | ||
{ | ||
- struct mlxcpld_mux *data = i2c_mux_priv(muxc); | ||
- struct i2c_client *client = data->client; | ||
+ struct mlxcpld_mux *mux = i2c_mux_priv(muxc); | ||
u8 regval = chan + 1; | ||
int err = 0; | ||
|
||
/* Only select the channel if its different from the last channel */ | ||
- if (data->last_chan != regval) { | ||
- err = mlxcpld_mux_reg_write(muxc->parent, client, regval); | ||
- data->last_chan = err < 0 ? 0 : regval; | ||
+ if (mux->last_chan != regval) { | ||
+ err = mlxcpld_mux_reg_write(muxc->parent, mux, regval); | ||
+ mux->last_chan = err < 0 ? 0 : regval; | ||
} | ||
|
||
return err; | ||
@@ -92,21 +87,19 @@ static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan) | ||
|
||
static int mlxcpld_mux_deselect(struct i2c_mux_core *muxc, u32 chan) | ||
{ | ||
- struct mlxcpld_mux *data = i2c_mux_priv(muxc); | ||
- struct i2c_client *client = data->client; | ||
+ struct mlxcpld_mux *mux = i2c_mux_priv(muxc); | ||
|
||
/* Deselect active channel */ | ||
- data->last_chan = 0; | ||
+ mux->last_chan = 0; | ||
|
||
- return mlxcpld_mux_reg_write(muxc->parent, client, data->last_chan); | ||
+ return mlxcpld_mux_reg_write(muxc->parent, mux, mux->last_chan); | ||
} | ||
|
||
/* Probe/reomove functions */ | ||
-static int mlxcpld_mux_probe(struct i2c_client *client, | ||
- const struct i2c_device_id *id) | ||
+static int mlxcpld_mux_probe(struct platform_device *pdev) | ||
{ | ||
- struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); | ||
- struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev); | ||
+ struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&pdev->dev); | ||
+ struct i2c_client *client = to_i2c_client(pdev->dev.parent); | ||
struct i2c_mux_core *muxc; | ||
int num, force; | ||
struct mlxcpld_mux *data; | ||
@@ -115,18 +108,20 @@ static int mlxcpld_mux_probe(struct i2c_client *client, | ||
if (!pdata) | ||
return -EINVAL; | ||
|
||
- if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
+ if (!i2c_check_functionality(client->adapter, | ||
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
return -ENODEV; | ||
|
||
- muxc = i2c_mux_alloc(adap, &client->dev, CPLD_MUX_MAX_NCHANS, | ||
+ muxc = i2c_mux_alloc(client->adapter, &pdev->dev, CPLD_MUX_MAX_NCHANS, | ||
sizeof(*data), 0, mlxcpld_mux_select_chan, | ||
mlxcpld_mux_deselect); | ||
if (!muxc) | ||
return -ENOMEM; | ||
|
||
+ platform_set_drvdata(pdev, muxc); | ||
data = i2c_mux_priv(muxc); | ||
- i2c_set_clientdata(client, muxc); | ||
data->client = client; | ||
+ memcpy(&data->pdata, pdata, sizeof(*pdata)); | ||
data->last_chan = 0; /* force the first selection */ | ||
|
||
/* Create an adapter for each channel. */ | ||
@@ -149,24 +144,23 @@ virt_reg_failed: | ||
return err; | ||
} | ||
|
||
-static int mlxcpld_mux_remove(struct i2c_client *client) | ||
+static int mlxcpld_mux_remove(struct platform_device *pdev) | ||
{ | ||
- struct i2c_mux_core *muxc = i2c_get_clientdata(client); | ||
+ struct i2c_mux_core *muxc = platform_get_drvdata(pdev); | ||
|
||
i2c_mux_del_adapters(muxc); | ||
return 0; | ||
} | ||
|
||
-static struct i2c_driver mlxcpld_mux_driver = { | ||
- .driver = { | ||
- .name = "mlxcpld-mux", | ||
+static struct platform_driver mlxcpld_mux_driver = { | ||
+ .driver = { | ||
+ .name = "i2c-mux-mlxcpld", | ||
}, | ||
- .probe = mlxcpld_mux_probe, | ||
- .remove = mlxcpld_mux_remove, | ||
- .id_table = mlxcpld_mux_id, | ||
+ .probe = mlxcpld_mux_probe, | ||
+ .remove = mlxcpld_mux_remove, | ||
}; | ||
|
||
-module_i2c_driver(mlxcpld_mux_driver); | ||
+module_platform_driver(mlxcpld_mux_driver); | ||
|
||
MODULE_AUTHOR("Michael Shych (michaels@mellanox.com)"); | ||
MODULE_DESCRIPTION("Mellanox I2C-CPLD-MUX driver"); | ||
-- | ||
2.11.0 | ||
|
90 changes: 90 additions & 0 deletions
90
patch/0039-i2c-mux-mlxcpld-Prepare-mux-selection-infrastructure.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
From f75ab2b3d365e8e53c206179efe6b55df47f55dc Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Sun, 7 Feb 2021 21:18:00 +0200 | ||
|
||
commit 81566938083af15aec75201293cf6047bb04f4d3 upstream | ||
|
||
Subject: [PATCH backport 4.19 07/11] i2c: mux: mlxcpld: Prepare mux selection | ||
infrastructure for two-byte support | ||
|
||
Allow to program register value zero to the mux register, which is | ||
required for word address mux register space support. | ||
Change key selector type from 'unsigned short' to 'integer' in order to | ||
allow to set it to -1 on deselection. | ||
Rename key selector field from 'last_chan' to 'last_val', since this | ||
fields keeps actually selector value and not channel number. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
--- | ||
drivers/i2c/muxes/i2c-mux-mlxcpld.c | 18 +++++++++--------- | ||
1 file changed, 9 insertions(+), 9 deletions(-) | ||
|
||
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
index b53f1479272d..113ad84cdd94 100644 | ||
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
@@ -18,12 +18,12 @@ | ||
#define CPLD_MUX_MAX_NCHANS 8 | ||
|
||
/* mlxcpld_mux - mux control structure: | ||
- * @last_chan - last register value | ||
+ * @last_val - last selected register value or -1 if mux deselected | ||
* @client - I2C device client | ||
* @pdata: platform data | ||
*/ | ||
struct mlxcpld_mux { | ||
- u8 last_chan; | ||
+ int last_val; | ||
struct i2c_client *client; | ||
struct mlxcpld_mux_plat_data pdata; | ||
}; | ||
@@ -60,7 +60,7 @@ struct mlxcpld_mux { | ||
* for this as they will try to lock adapter a second time. | ||
*/ | ||
static int mlxcpld_mux_reg_write(struct i2c_adapter *adap, | ||
- struct mlxcpld_mux *mux, u8 val) | ||
+ struct mlxcpld_mux *mux, u32 val) | ||
{ | ||
struct i2c_client *client = mux->client; | ||
union i2c_smbus_data data = { .byte = val }; | ||
@@ -73,13 +73,13 @@ static int mlxcpld_mux_reg_write(struct i2c_adapter *adap, | ||
static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan) | ||
{ | ||
struct mlxcpld_mux *mux = i2c_mux_priv(muxc); | ||
- u8 regval = chan + 1; | ||
+ u32 regval = chan + 1; | ||
int err = 0; | ||
|
||
/* Only select the channel if its different from the last channel */ | ||
- if (mux->last_chan != regval) { | ||
+ if (mux->last_val != regval) { | ||
err = mlxcpld_mux_reg_write(muxc->parent, mux, regval); | ||
- mux->last_chan = err < 0 ? 0 : regval; | ||
+ mux->last_val = err < 0 ? -1 : regval; | ||
} | ||
|
||
return err; | ||
@@ -90,9 +90,9 @@ static int mlxcpld_mux_deselect(struct i2c_mux_core *muxc, u32 chan) | ||
struct mlxcpld_mux *mux = i2c_mux_priv(muxc); | ||
|
||
/* Deselect active channel */ | ||
- mux->last_chan = 0; | ||
+ mux->last_val = -1; | ||
|
||
- return mlxcpld_mux_reg_write(muxc->parent, mux, mux->last_chan); | ||
+ return mlxcpld_mux_reg_write(muxc->parent, mux, 0); | ||
} | ||
|
||
/* Probe/reomove functions */ | ||
@@ -122,7 +122,7 @@ static int mlxcpld_mux_probe(struct platform_device *pdev) | ||
data = i2c_mux_priv(muxc); | ||
data->client = client; | ||
memcpy(&data->pdata, pdata, sizeof(*pdata)); | ||
- data->last_chan = 0; /* force the first selection */ | ||
+ data->last_val = -1; /* force the first selection */ | ||
|
||
/* Create an adapter for each channel. */ | ||
for (num = 0; num < CPLD_MUX_MAX_NCHANS; num++) { | ||
-- | ||
2.11.0 | ||
|
77 changes: 77 additions & 0 deletions
77
patch/0040-i2c-mux-mlxcpld-Get-rid-of-adapter-numbers-enforceme.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
From 8afdccd70c3ccb6a62b4d834c978b08d1bd13d94 Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Sun, 7 Feb 2021 21:20:18 +0200 | ||
|
||
commit cae5216387d18c888f9f38a0cf5be341a0af75a6 upstream | ||
|
||
Subject: [PATCH backport 4.19 08/11] i2c: mux: mlxcpld: Get rid of adapter | ||
numbers enforcement | ||
|
||
Do not set the argument 'force_nr' of i2c_mux_add_adapter() routine, | ||
instead provide argument 'chan_id'. | ||
Rename mux ids array from 'adap_ids' to 'chan_ids'. | ||
|
||
The motivation is to prepare infrastructure to be able to: | ||
- Create only the child adapters which are actually needed - for which | ||
channel ids are specified. | ||
- To assign 'nrs' to these child adapters dynamically, with no 'nr' | ||
enforcement. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
--- | ||
drivers/i2c/muxes/i2c-mux-mlxcpld.c | 11 ++--------- | ||
include/linux/platform_data/mlxcpld.h | 4 ++-- | ||
2 files changed, 4 insertions(+), 11 deletions(-) | ||
|
||
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
index 113ad84cdd94..388fe5c080aa 100644 | ||
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
@@ -101,9 +101,8 @@ static int mlxcpld_mux_probe(struct platform_device *pdev) | ||
struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&pdev->dev); | ||
struct i2c_client *client = to_i2c_client(pdev->dev.parent); | ||
struct i2c_mux_core *muxc; | ||
- int num, force; | ||
struct mlxcpld_mux *data; | ||
- int err; | ||
+ int num, err; | ||
|
||
if (!pdata) | ||
return -EINVAL; | ||
@@ -126,13 +125,7 @@ static int mlxcpld_mux_probe(struct platform_device *pdev) | ||
|
||
/* Create an adapter for each channel. */ | ||
for (num = 0; num < CPLD_MUX_MAX_NCHANS; num++) { | ||
- if (num >= pdata->num_adaps) | ||
- /* discard unconfigured channels */ | ||
- break; | ||
- | ||
- force = pdata->adap_ids[num]; | ||
- | ||
- err = i2c_mux_add_adapter(muxc, force, num, 0); | ||
+ err = i2c_mux_add_adapter(muxc, 0, pdata->chan_ids[num], 0); | ||
if (err) | ||
goto virt_reg_failed; | ||
} | ||
diff --git a/include/linux/platform_data/mlxcpld.h b/include/linux/platform_data/mlxcpld.h | ||
index e6c18bf017dd..04d93c563c04 100644 | ||
--- a/include/linux/platform_data/mlxcpld.h | ||
+++ b/include/linux/platform_data/mlxcpld.h | ||
@@ -11,12 +11,12 @@ | ||
/* Platform data for the CPLD I2C multiplexers */ | ||
|
||
/* mlxcpld_mux_plat_data - per mux data, used with i2c_register_board_info | ||
- * @adap_ids - adapter array | ||
+ * @chan_ids - channels array | ||
* @num_adaps - number of adapters | ||
* @sel_reg_addr - mux select register offset in CPLD space | ||
*/ | ||
struct mlxcpld_mux_plat_data { | ||
- int *adap_ids; | ||
+ int *chan_ids; | ||
int num_adaps; | ||
int sel_reg_addr; | ||
}; | ||
-- | ||
2.11.0 | ||
|
117 changes: 117 additions & 0 deletions
117
patch/0041-i2c-mux-mlxcpld-Extend-driver-to-support-word-addres.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
From 09c9ec94318e6e90c2aacc26655e409b4d7092d4 Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Sun, 7 Feb 2021 21:28:28 +0200 | ||
|
||
commit c52a1c5f5db55c6a71110c2db9ae26b9f5269d20 upstream | ||
|
||
Subject: [PATCH backport 4.19 09/11] i2c: mux: mlxcpld: Extend driver to | ||
support word address space devices | ||
|
||
Extend driver to allow I2C routing control through CPLD devices with | ||
word address space. Till now only CPLD devices with byte address space | ||
have been supported. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Reviewed-by: Michael Shych <michaelsh@nvidia.com> | ||
--- | ||
drivers/i2c/muxes/i2c-mux-mlxcpld.c | 47 +++++++++++++++++++++++++++++------ | ||
include/linux/platform_data/mlxcpld.h | 2 ++ | ||
2 files changed, 41 insertions(+), 8 deletions(-) | ||
|
||
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
index 388fe5c080aa..ba307ee6b034 100644 | ||
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
@@ -63,19 +63,39 @@ static int mlxcpld_mux_reg_write(struct i2c_adapter *adap, | ||
struct mlxcpld_mux *mux, u32 val) | ||
{ | ||
struct i2c_client *client = mux->client; | ||
- union i2c_smbus_data data = { .byte = val }; | ||
- | ||
- return __i2c_smbus_xfer(adap, client->addr, client->flags, | ||
- I2C_SMBUS_WRITE, mux->pdata.sel_reg_addr, | ||
- I2C_SMBUS_BYTE_DATA, &data); | ||
+ union i2c_smbus_data data; | ||
+ struct i2c_msg msg; | ||
+ u8 buf[3]; | ||
+ | ||
+ switch (mux->pdata.reg_size) { | ||
+ case 1: | ||
+ data.byte = val; | ||
+ return __i2c_smbus_xfer(adap, client->addr, client->flags, | ||
+ I2C_SMBUS_WRITE, mux->pdata.sel_reg_addr, | ||
+ I2C_SMBUS_BYTE_DATA, &data); | ||
+ case 2: | ||
+ buf[0] = mux->pdata.sel_reg_addr >> 8; | ||
+ buf[1] = mux->pdata.sel_reg_addr; | ||
+ buf[2] = val; | ||
+ msg.addr = client->addr; | ||
+ msg.buf = buf; | ||
+ msg.len = mux->pdata.reg_size + 1; | ||
+ msg.flags = 0; | ||
+ return __i2c_transfer(adap, &msg, 1); | ||
+ default: | ||
+ return -EINVAL; | ||
+ } | ||
} | ||
|
||
static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan) | ||
{ | ||
struct mlxcpld_mux *mux = i2c_mux_priv(muxc); | ||
- u32 regval = chan + 1; | ||
+ u32 regval = chan; | ||
int err = 0; | ||
|
||
+ if (mux->pdata.reg_size == 1) | ||
+ regval += 1; | ||
+ | ||
/* Only select the channel if its different from the last channel */ | ||
if (mux->last_val != regval) { | ||
err = mlxcpld_mux_reg_write(muxc->parent, mux, regval); | ||
@@ -103,12 +123,23 @@ static int mlxcpld_mux_probe(struct platform_device *pdev) | ||
struct i2c_mux_core *muxc; | ||
struct mlxcpld_mux *data; | ||
int num, err; | ||
+ u32 func; | ||
|
||
if (!pdata) | ||
return -EINVAL; | ||
|
||
- if (!i2c_check_functionality(client->adapter, | ||
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
+ switch (pdata->reg_size) { | ||
+ case 1: | ||
+ func = I2C_FUNC_SMBUS_WRITE_BYTE_DATA; | ||
+ break; | ||
+ case 2: | ||
+ func = I2C_FUNC_I2C; | ||
+ break; | ||
+ default: | ||
+ return -EINVAL; | ||
+ } | ||
+ | ||
+ if (!i2c_check_functionality(client->adapter, func)) | ||
return -ENODEV; | ||
|
||
muxc = i2c_mux_alloc(client->adapter, &pdev->dev, CPLD_MUX_MAX_NCHANS, | ||
diff --git a/include/linux/platform_data/mlxcpld.h b/include/linux/platform_data/mlxcpld.h | ||
index 04d93c563c04..a7bee798d991 100644 | ||
--- a/include/linux/platform_data/mlxcpld.h | ||
+++ b/include/linux/platform_data/mlxcpld.h | ||
@@ -14,11 +14,13 @@ | ||
* @chan_ids - channels array | ||
* @num_adaps - number of adapters | ||
* @sel_reg_addr - mux select register offset in CPLD space | ||
+ * @reg_size: register size in bytes | ||
*/ | ||
struct mlxcpld_mux_plat_data { | ||
int *chan_ids; | ||
int num_adaps; | ||
int sel_reg_addr; | ||
+ u8 reg_size; | ||
}; | ||
|
||
#endif /* _LINUX_I2C_MLXCPLD_H */ | ||
-- | ||
2.11.0 | ||
|
54 changes: 54 additions & 0 deletions
54
patch/0042-i2c-mux-mlxcpld-Extend-supported-mux-number.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
From 9eb7d15063a9c4932716f49e7aa9319b8e6f0ade Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Sun, 7 Feb 2021 21:29:06 +0200 | ||
|
||
commit 699c0506543ee9ba3f5a67ab0837b292b098aeb4 upstream | ||
|
||
Subject: [PATCH backport 4.19 10/11] i2c: mux: mlxcpld: Extend supported mux | ||
number | ||
|
||
Allow to extend mux number supported by driver. | ||
Currently it is limited by eight, which is not enough for new coming | ||
Mellanox modular system with line cards, which require up to 64 mux | ||
support. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Reviewed-by: Michael Shych <michaelsh@nvidia.com> | ||
--- | ||
drivers/i2c/muxes/i2c-mux-mlxcpld.c | 6 ++---- | ||
1 file changed, 2 insertions(+), 4 deletions(-) | ||
|
||
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
index ba307ee6b034..5e0672f9979b 100644 | ||
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
@@ -15,8 +15,6 @@ | ||
#include <linux/platform_device.h> | ||
#include <linux/slab.h> | ||
|
||
-#define CPLD_MUX_MAX_NCHANS 8 | ||
- | ||
/* mlxcpld_mux - mux control structure: | ||
* @last_val - last selected register value or -1 if mux deselected | ||
* @client - I2C device client | ||
@@ -142,7 +140,7 @@ static int mlxcpld_mux_probe(struct platform_device *pdev) | ||
if (!i2c_check_functionality(client->adapter, func)) | ||
return -ENODEV; | ||
|
||
- muxc = i2c_mux_alloc(client->adapter, &pdev->dev, CPLD_MUX_MAX_NCHANS, | ||
+ muxc = i2c_mux_alloc(client->adapter, &pdev->dev, pdata->num_adaps, | ||
sizeof(*data), 0, mlxcpld_mux_select_chan, | ||
mlxcpld_mux_deselect); | ||
if (!muxc) | ||
@@ -155,7 +153,7 @@ static int mlxcpld_mux_probe(struct platform_device *pdev) | ||
data->last_val = -1; /* force the first selection */ | ||
|
||
/* Create an adapter for each channel. */ | ||
- for (num = 0; num < CPLD_MUX_MAX_NCHANS; num++) { | ||
+ for (num = 0; num < pdata->num_adaps; num++) { | ||
err = i2c_mux_add_adapter(muxc, 0, pdata->chan_ids[num], 0); | ||
if (err) | ||
goto virt_reg_failed; | ||
-- | ||
2.11.0 | ||
|
61 changes: 61 additions & 0 deletions
61
patch/0043-i2c-mux-mlxcpld-Add-callback-to-notify-mux-creation-.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
From 8e6d7ffd04b6362c1b244843c70a9ac9f76bf773 Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Sun, 7 Feb 2021 21:29:38 +0200 | ||
|
||
commit a39bd92e92b96d05d676fb5c9493cf1c911d2a0a upstream | ||
|
||
Subject: [PATCH backport 4.19 11/11] i2c: mux: mlxcpld: Add callback to notify | ||
mux creation completion | ||
|
||
Add notification to inform caller that mux objects array has been | ||
created. It allows to user, invoked platform device registration for | ||
"i2c-mux-mlxcpld" driver, to be notified that mux infrastructure is | ||
available, and thus some devices could be connected to this | ||
infrastructure. | ||
|
||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
--- | ||
drivers/i2c/muxes/i2c-mux-mlxcpld.c | 4 ++++ | ||
include/linux/platform_data/mlxcpld.h | 5 +++++ | ||
2 files changed, 9 insertions(+) | ||
|
||
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
index 5e0672f9979b..1a879f6a31ef 100644 | ||
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c | ||
@@ -159,6 +159,10 @@ static int mlxcpld_mux_probe(struct platform_device *pdev) | ||
goto virt_reg_failed; | ||
} | ||
|
||
+ /* Notify caller when all channels' adapters are created. */ | ||
+ if (pdata->completion_notify) | ||
+ pdata->completion_notify(pdata->handle, muxc->parent, muxc->adapter); | ||
+ | ||
return 0; | ||
|
||
virt_reg_failed: | ||
diff --git a/include/linux/platform_data/mlxcpld.h b/include/linux/platform_data/mlxcpld.h | ||
index a7bee798d991..d7610b528856 100644 | ||
--- a/include/linux/platform_data/mlxcpld.h | ||
+++ b/include/linux/platform_data/mlxcpld.h | ||
@@ -15,12 +15,17 @@ | ||
* @num_adaps - number of adapters | ||
* @sel_reg_addr - mux select register offset in CPLD space | ||
* @reg_size: register size in bytes | ||
+ * @handle: handle to be passed by callback | ||
+ * @completion_notify: callback to notify when all the adapters are created | ||
*/ | ||
struct mlxcpld_mux_plat_data { | ||
int *chan_ids; | ||
int num_adaps; | ||
int sel_reg_addr; | ||
u8 reg_size; | ||
+ void *handle; | ||
+ int (*completion_notify)(void *handle, struct i2c_adapter *parent, | ||
+ struct i2c_adapter *adapters[]); | ||
}; | ||
|
||
#endif /* _LINUX_I2C_MLXCPLD_H */ | ||
-- | ||
2.11.0 | ||
|
68 changes: 68 additions & 0 deletions
68
patch/0044-platform-x86-mlx-platform-remove-an-unused-variable.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
From c15798055ec98f7af0ce2d9866563908005b750a Mon Sep 17 00:00:00 2001 | ||
From: Arnd Bergmann <arnd@arndb.de> | ||
Date: Thu, 3 Dec 2020 23:30:56 +0100 | ||
|
||
commit eca6ba20f38cfa2f148d7bd13db7ccd19e88635b upstream | ||
|
||
Subject: [PATCH backport 4.19 05/10] platform/x86: mlx-platform: remove an | ||
unused variable | ||
|
||
The only reference to the mlxplat_mlxcpld_psu[] array got removed, | ||
so there is now a warning from clang: | ||
|
||
drivers/platform/x86/mlx-platform.c:322:30: error: variable 'mlxplat_mlxcpld_psu' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration] | ||
static struct i2c_board_info mlxplat_mlxcpld_psu[] = { | ||
|
||
Remove the array as well and adapt the ARRAY_SIZE() call | ||
accordingly. | ||
|
||
Fixes: 912b341585e3 ("platform/x86: mlx-platform: Remove PSU EEPROM from MSN274x platform configuration") | ||
Signed-off-by: Arnd Bergmann <arnd@arndb.de> | ||
Acked-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Link: https://lore.kernel.org/r/20201203223105.1195709-1-arnd@kernel.org | ||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> | ||
--- | ||
drivers/platform/x86/mlx-platform.c | 13 ++----------- | ||
1 file changed, 2 insertions(+), 11 deletions(-) | ||
|
||
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c | ||
index c1d1a7817d02..218e3ae68825 100644 | ||
--- a/drivers/platform/x86/mlx-platform.c | ||
+++ b/drivers/platform/x86/mlx-platform.c | ||
@@ -320,15 +320,6 @@ static struct i2c_mux_reg_platform_data mlxplat_extended_mux_data[] = { | ||
}; | ||
|
||
/* Platform hotplug devices */ | ||
-static struct i2c_board_info mlxplat_mlxcpld_psu[] = { | ||
- { | ||
- I2C_BOARD_INFO("24c02", 0x51), | ||
- }, | ||
- { | ||
- I2C_BOARD_INFO("24c02", 0x50), | ||
- }, | ||
-}; | ||
- | ||
static struct i2c_board_info mlxplat_mlxcpld_pwr[] = { | ||
{ | ||
I2C_BOARD_INFO("dps460", 0x59), | ||
@@ -448,7 +439,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = { | ||
.aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF, | ||
.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, | ||
.mask = MLXPLAT_CPLD_PSU_MASK, | ||
- .count = ARRAY_SIZE(mlxplat_mlxcpld_psu), | ||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_psu_items_data), | ||
.inversed = 1, | ||
.health = false, | ||
}, | ||
@@ -487,7 +478,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_comex_items[] = { | ||
.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER, | ||
.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, | ||
.mask = MLXPLAT_CPLD_PSU_MASK, | ||
- .count = ARRAY_SIZE(mlxplat_mlxcpld_psu), | ||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_psu_items_data), | ||
.inversed = 1, | ||
.health = false, | ||
}, | ||
-- | ||
2.11.0 | ||
|
56 changes: 56 additions & 0 deletions
56
patch/0045-platform-x86-mlx-platform-Fix-item-counter-assignmen.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
From 9b0d00b714d50580882accaf9e4c57f24b064a19 Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Mon, 7 Dec 2020 19:47:44 +0200 | ||
|
||
commit ba4939f1dd46dde08c2f9b9d7ac86ed3ea7ead86 upstream | ||
|
||
Subject: [PATCH backport 4.19 06/10] platform/x86: mlx-platform: Fix item | ||
counter assignment for MSN2700, MSN24xx systems | ||
|
||
Fix array names to match assignments for data items and data items | ||
counter in 'mlxplat_mlxcpld_default_items' structure for: | ||
.data = mlxplat_mlxcpld_default_pwr_items_data, | ||
.count = ARRAY_SIZE(mlxplat_mlxcpld_pwr), | ||
and | ||
.data = mlxplat_mlxcpld_default_fan_items_data, | ||
.count = ARRAY_SIZE(mlxplat_mlxcpld_fan), | ||
|
||
Replace: | ||
- 'mlxplat_mlxcpld_pwr' by 'mlxplat_mlxcpld_default_pwr_items_data' for | ||
ARRAY_SIZE() calculation. | ||
- 'mlxplat_mlxcpld_fan' by 'mlxplat_mlxcpld_default_fan_items_data' | ||
for ARRAY_SIZE() calculation. | ||
|
||
Fixes: c6acad68eb2d ("platform/mellanox: mlxreg-hotplug: Modify to use a regmap interface") | ||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Link: https://lore.kernel.org/r/20201207174745.22889-2-vadimp@nvidia.com | ||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> | ||
--- | ||
drivers/platform/x86/mlx-platform.c | 4 ++-- | ||
1 file changed, 2 insertions(+), 2 deletions(-) | ||
|
||
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c | ||
index 218e3ae68825..f3420c577ec8 100644 | ||
--- a/drivers/platform/x86/mlx-platform.c | ||
+++ b/drivers/platform/x86/mlx-platform.c | ||
@@ -448,7 +448,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = { | ||
.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF, | ||
.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, | ||
.mask = MLXPLAT_CPLD_PWR_MASK, | ||
- .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr), | ||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_pwr_items_data), | ||
.inversed = 0, | ||
.health = false, | ||
}, | ||
@@ -457,7 +457,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = { | ||
.aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF, | ||
.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, | ||
.mask = MLXPLAT_CPLD_FAN_MASK, | ||
- .count = ARRAY_SIZE(mlxplat_mlxcpld_fan), | ||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_items_data), | ||
.inversed = 1, | ||
.health = false, | ||
}, | ||
-- | ||
2.11.0 | ||
|
56 changes: 56 additions & 0 deletions
56
patch/0046-platform-x86-mlx-platform-Fix-item-counter-assignmen.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
From 491f092cec707697107616ec691557a1d0c6cfd7 Mon Sep 17 00:00:00 2001 | ||
From: Vadim Pasternak <vadimp@nvidia.com> | ||
Date: Mon, 7 Dec 2020 19:47:45 +0200 | ||
|
||
commit cf791774a16caf87b0e4c0c55b82979bad0b6c01 upstream | ||
|
||
Subject: [PATCH backport 4.19 07/10] platform/x86: mlx-platform: Fix item | ||
counter assignment for MSN2700/ComEx system | ||
|
||
Fix array names to match assignments for data items and data items | ||
counter in 'mlxplat_mlxcpld_comex_items' structure for: | ||
.data = mlxplat_mlxcpld_default_pwr_items_data, | ||
.count = ARRAY_SIZE(mlxplat_mlxcpld_pwr), | ||
and | ||
.data = mlxplat_mlxcpld_default_fan_items_data, | ||
.count = ARRAY_SIZE(mlxplat_mlxcpld_fan), | ||
|
||
Replace: | ||
- 'mlxplat_mlxcpld_pwr' by 'mlxplat_mlxcpld_default_pwr_items_data' for | ||
ARRAY_SIZE() calculation. | ||
- 'mlxplat_mlxcpld_fan' by 'mlxplat_mlxcpld_default_fan_items_data' | ||
for ARRAY_SIZE() calculation. | ||
|
||
Fixes: bdd6e155e0d6 ("platform/x86: mlx-platform: Add support for new system type") | ||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Link: https://lore.kernel.org/r/20201207174745.22889-3-vadimp@nvidia.com | ||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> | ||
--- | ||
drivers/platform/x86/mlx-platform.c | 4 ++-- | ||
1 file changed, 2 insertions(+), 2 deletions(-) | ||
|
||
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c | ||
index f3420c577ec8..721b745c9bc5 100644 | ||
--- a/drivers/platform/x86/mlx-platform.c | ||
+++ b/drivers/platform/x86/mlx-platform.c | ||
@@ -487,7 +487,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_comex_items[] = { | ||
.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER, | ||
.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, | ||
.mask = MLXPLAT_CPLD_PWR_MASK, | ||
- .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr), | ||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_pwr_items_data), | ||
.inversed = 0, | ||
.health = false, | ||
}, | ||
@@ -496,7 +496,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_comex_items[] = { | ||
.aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER, | ||
.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, | ||
.mask = MLXPLAT_CPLD_FAN_MASK, | ||
- .count = ARRAY_SIZE(mlxplat_mlxcpld_fan), | ||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_items_data), | ||
.inversed = 1, | ||
.health = false, | ||
}, | ||
-- | ||
2.11.0 | ||
|
53 changes: 53 additions & 0 deletions
53
patch/0047-mlxsw-core-Set-thermal-zone-polling-delay-argument-t.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
From b32836310a24740a0d7f420faf8c25ea5b37fcc3 Mon Sep 17 00:00:00 2001 | ||
From: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Date: Tue, 1 Jun 2021 14:40:22 +0300 | ||
|
||
commit 2fd8d84ce3095e8a7b5fe96532c91b1b9e07339c upstream | ||
|
||
Subject: [PATCH 1/6] mlxsw: core: Set thermal zone polling delay argument to | ||
real value at init | ||
|
||
Thermal polling delay argument for modules and gearboxes thermal zones | ||
used to be initialized with zero value, while actual delay was used to be | ||
set by mlxsw_thermal_set_mode() by thermal operation callback set_mode(). | ||
After operation set_mode()/get_mode() have been removed by cited commits, | ||
modules and gearboxes thermal zones always have polling time set to zero | ||
and do not perform temperature monitoring. | ||
|
||
Set non-zero "polling_delay" in thermal_zone_device_register() routine, | ||
thus, the relevant thermal zones will perform thermal monitoring. | ||
|
||
Fixes: 5d7bd8aa7c35 ("thermal: Simplify or eliminate unnecessary set_mode() methods") | ||
Fixes: 1ee14820fd8e ("thermal: remove get_mode() operation of drivers") | ||
Signed-off-by: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Acked-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Reviewed-by: Jiri Pirko <jiri@nvidia.com> | ||
Signed-off-by: Ido Schimmel <idosch@nvidia.com> | ||
--- | ||
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 7 ++++--- | ||
1 file changed, 4 insertions(+), 3 deletions(-) | ||
|
||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
index 0cfabbd..19781b3 100644 | ||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
@@ -789,7 +789,8 @@ static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev, | ||
MLXSW_THERMAL_TRIP_MASK, | ||
module_tz, | ||
&mlxsw_thermal_module_ops, | ||
- &mlxsw_thermal_params, 0, 0); | ||
+ &mlxsw_thermal_params, 0, | ||
+ module_tz->parent->polling_delay); | ||
if (IS_ERR(module_tz->tzdev)) { | ||
err = PTR_ERR(module_tz->tzdev); | ||
return err; | ||
@@ -909,7 +910,8 @@ static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz) | ||
MLXSW_THERMAL_TRIP_MASK, | ||
gearbox_tz, | ||
&mlxsw_thermal_gearbox_ops, | ||
- &mlxsw_thermal_params, 0, 0); | ||
+ &mlxsw_thermal_params, 0, | ||
+ gearbox_tz->parent->polling_delay); | ||
if (IS_ERR(gearbox_tz->tzdev)) | ||
return PTR_ERR(gearbox_tz->tzdev); | ||
|
149 changes: 149 additions & 0 deletions
149
patch/0048-mlxsw-reg-Extend-MTMP-register-with-new-threshold-fi.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
From a1eae5be1d1a5d4b09be7f0bc5085289dfe94eca Mon Sep 17 00:00:00 2001 | ||
From: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Date: Thu, 3 Jun 2021 18:18:03 +0300 | ||
|
||
commit 314dbb19f95b67456cb042e4a7a36b777a029bea upstream | ||
|
||
Subject: [PATCH 2/6] mlxsw: reg: Extend MTMP register with new threshold field | ||
|
||
Extend Management Temperature (MTMP) register with new field specifying | ||
the maximum temperature threshold. | ||
|
||
Extend mlxsw_reg_mtmp_unpack() function with two extra arguments, | ||
providing high and maximum temperature thresholds. For modules, these | ||
thresholds correspond to critical and emergency thresholds that are read | ||
from the module's EEPROM. | ||
|
||
Signed-off-by: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Acked-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Signed-off-by: Ido Schimmel <idosch@nvidia.com> | ||
--- | ||
.../net/ethernet/mellanox/mlxsw/core_env.c | 2 +- | ||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 6 +++--- | ||
.../ethernet/mellanox/mlxsw/core_thermal.c | 6 +++--- | ||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 20 ++++++++++++++++++- | ||
4 files changed, 26 insertions(+), 8 deletions(-) | ||
|
||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c | ||
index c36deca8d372..8c65a6ffd6a4 100644 | ||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c | ||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c | ||
@@ -143,7 +143,7 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, u8 slot_index, | ||
err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl); | ||
if (err) | ||
return err; | ||
- mlxsw_reg_mtmp_unpack(mtmp_pl, &module_temp, NULL, NULL); | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &module_temp, NULL, NULL, NULL, NULL); | ||
if (!module_temp) { | ||
*temp = 0; | ||
return 0; | ||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | ||
index 0f46125d688c..a2cd4715b244 100644 | ||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | ||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | ||
@@ -86,7 +86,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev, | ||
dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n"); | ||
return err; | ||
} | ||
- mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); | ||
return sprintf(buf, "%d\n", temp); | ||
} | ||
|
||
@@ -112,7 +112,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev, | ||
dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n"); | ||
return err; | ||
} | ||
- mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL); | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL, NULL, NULL); | ||
return sprintf(buf, "%d\n", temp_max); | ||
} | ||
|
||
@@ -264,7 +264,7 @@ static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev, | ||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl); | ||
if (err) | ||
return err; | ||
- mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); | ||
|
||
return sprintf(buf, "%d\n", temp); | ||
} | ||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
index d83c4d02159a..08eef0a39e39 100644 | ||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
@@ -336,7 +336,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev, | ||
dev_err(dev, "Failed to query temp sensor\n"); | ||
return err; | ||
} | ||
- mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); | ||
if (temp > 0) | ||
mlxsw_thermal_tz_score_update(thermal, tzdev, thermal->trips, | ||
temp); | ||
@@ -541,7 +541,7 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, | ||
*p_temp = (int) temp; | ||
return 0; | ||
} | ||
- mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); | ||
*p_temp = temp; | ||
|
||
if (!temp) | ||
@@ -667,7 +667,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev, | ||
if (err) | ||
return err; | ||
|
||
- mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); | ||
if (temp > 0) | ||
mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp); | ||
|
||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h | ||
index bb2a1420d741..ebf98737cee9 100644 | ||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h | ||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h | ||
@@ -7954,6 +7954,14 @@ MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 12); | ||
((s16)((GENMASK(15, 0) + (v_) + 1) \ | ||
* 125)); }) | ||
|
||
+/* reg_mtmp_max_operational_temperature | ||
+ * The highest temperature in the nominal operational range. Reading is in | ||
+ * 0.125 Celsius degrees units. | ||
+ * In case of module this is SFF critical temperature threshold. | ||
+ * Access: RO | ||
+ */ | ||
+MLXSW_ITEM32(reg, mtmp, max_operational_temperature, 0x04, 16, 16); | ||
+ | ||
/* reg_mtmp_temperature | ||
* Temperature reading from the sensor. Reading is in 0.125 Celsius | ||
* degrees units. | ||
@@ -8025,7 +8033,9 @@ static inline void mlxsw_reg_mtmp_pack(char *payload, u8 slot_index, | ||
} | ||
|
||
static inline void mlxsw_reg_mtmp_unpack(char *payload, int *p_temp, | ||
- int *p_max_temp, char *sensor_name) | ||
+ int *p_max_temp, int *p_temp_hi, | ||
+ int *p_max_oper_temp, | ||
+ char *sensor_name) | ||
{ | ||
s16 temp; | ||
|
||
@@ -8037,6 +8047,14 @@ static inline void mlxsw_reg_mtmp_unpack(char *payload, int *p_temp, | ||
temp = mlxsw_reg_mtmp_max_temperature_get(payload); | ||
*p_max_temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp); | ||
} | ||
+ if (p_temp_hi) { | ||
+ temp = mlxsw_reg_mtmp_temperature_threshold_hi_get(payload); | ||
+ *p_temp_hi = MLXSW_REG_MTMP_TEMP_TO_MC(temp); | ||
+ } | ||
+ if (p_max_oper_temp) { | ||
+ temp = mlxsw_reg_mtmp_max_operational_temperature_get(payload); | ||
+ *p_max_oper_temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp); | ||
+ } | ||
if (sensor_name) | ||
mlxsw_reg_mtmp_sensor_name_memcpy_from(payload, sensor_name); | ||
} | ||
-- | ||
2.20.1 | ||
|
73 changes: 73 additions & 0 deletions
73
patch/0049-mlxsw-core_env-Read-module-temperature-thresholds-us.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
From 05212296a16d4b4cb252f16d260289b626f3eff7 Mon Sep 17 00:00:00 2001 | ||
From: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Date: Thu, 3 Jun 2021 18:18:04 +0300 | ||
|
||
commit befc2048088aefbcd88b18225ba33231887137dc upstream | ||
|
||
Subject: [PATCH 3/6] mlxsw: core_env: Read module temperature thresholds using | ||
MTMP register | ||
|
||
Currently, module temperature thresholds are obtained from Management | ||
Cable Info Access (MCIA) register by specifying the thresholds offsets | ||
within module EEPROM layout. This data does not pass validation and in | ||
some cases can be unreliable. For example, due to some problem with the | ||
module. | ||
|
||
Add support for a new feature provided by Management Temperature (MTMP) | ||
register for sanitization of temperature thresholds values. | ||
|
||
Extend mlxsw_env_module_temp_thresholds_get() to get temperature | ||
thresholds through MTMP field 'max_operational_temperature' - if it is | ||
not zero, feature is supported. Otherwise fallback to old method and get | ||
the thresholds through MCIA. | ||
|
||
Signed-off-by: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Acked-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Signed-off-by: Ido Schimmel <idosch@nvidia.com> | ||
--- | ||
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 13 +++++++++++-- | ||
1 file changed, 11 insertions(+), 2 deletions(-) | ||
|
||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c | ||
index 09e72c8f7..b8ee9abe7 100644 | ||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c | ||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c | ||
@@ -109,6 +109,7 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module, | ||
int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module, | ||
int off, int *temp) | ||
{ | ||
+ unsigned int module_temp, module_crit, module_emerg; | ||
char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE]; | ||
union { | ||
u8 buf[MLXSW_REG_MCIA_TH_ITEM_SIZE]; | ||
@@ -116,7 +117,6 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module, | ||
} temp_thresh; | ||
char mcia_pl[MLXSW_REG_MCIA_LEN] = {0}; | ||
char mtmp_pl[MLXSW_REG_MTMP_LEN]; | ||
- unsigned int module_temp; | ||
bool qsfp, cmis; | ||
int page; | ||
int err; | ||
@@ -126,12 +126,21 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module, | ||
err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl); | ||
if (err) | ||
return err; | ||
- mlxsw_reg_mtmp_unpack(mtmp_pl, &module_temp, NULL, NULL, NULL, NULL); | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &module_temp, NULL, &module_crit, | ||
+ &module_emerg, NULL); | ||
if (!module_temp) { | ||
*temp = 0; | ||
return 0; | ||
} | ||
|
||
+ /* Validate if threshold reading is available through MTMP register, | ||
+ * otherwise fallback to read through MCIA. | ||
+ */ | ||
+ if (module_emerg) { | ||
+ *temp = off == SFP_TEMP_HIGH_WARN ? module_crit : module_emerg; | ||
+ return 0; | ||
+ } | ||
+ | ||
/* Read Free Side Device Temperature Thresholds from page 03h | ||
* (MSB at lower byte address). | ||
* Bytes: |
99 changes: 99 additions & 0 deletions
99
patch/0050-mlxsw-thermal-Add-function-for-reading-module-temper.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
From dce3743d854355fbc0aea3180ba40c937d21d499 Mon Sep 17 00:00:00 2001 | ||
From: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Date: Thu, 3 Jun 2021 18:18:05 +0300 | ||
|
||
commit e57977b34ab5d52d73bc0b8b2ff941ac21d7166f upstream | ||
|
||
Subject: [PATCH 4/6] mlxsw: thermal: Add function for reading module | ||
temperature and thresholds | ||
|
||
Provide new function mlxsw_thermal_module_temp_and_thresholds_get() for | ||
reading temperature and temperature thresholds by a single operation. | ||
The motivation is to reduce the number of transactions with the device | ||
which is important when operating over a slow bus such as I2C. | ||
|
||
Currently, the sole caller of the function is only using it to read the | ||
module's temperature. The next patch will also use it to query the | ||
module's temperature thresholds. | ||
|
||
Signed-off-by: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Acked-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Signed-off-by: Ido Schimmel <idosch@nvidia.com> | ||
--- | ||
.../ethernet/mellanox/mlxsw/core_thermal.c | 52 +++++++++++++------ | ||
1 file changed, 36 insertions(+), 16 deletions(-) | ||
|
||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
index e5812df9e..0a151d175 100644 | ||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
@@ -500,13 +500,40 @@ static int mlxsw_thermal_module_mode_set(struct thermal_zone_device *tzdev, | ||
return 0; | ||
} | ||
|
||
+static void | ||
+mlxsw_thermal_module_temp_and_thresholds_get(struct mlxsw_core *core, | ||
+ u16 sensor_index, | ||
+ int *p_temp, int *p_crit_temp, | ||
+ int *p_emerg_temp) | ||
+{ | ||
+ char mtmp_pl[MLXSW_REG_MTMP_LEN]; | ||
+ int err; | ||
+ | ||
+ /* Read module temperature and thresholds. */ | ||
+ mlxsw_reg_mtmp_pack(mtmp_pl, sensor_index, false, false); | ||
+ err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl); | ||
+ if (err) { | ||
+ /* Set temperature and thresholds to zero to avoid passing | ||
+ * uninitialized data back to the caller. | ||
+ */ | ||
+ *p_temp = 0; | ||
+ *p_crit_temp = 0; | ||
+ *p_emerg_temp = 0; | ||
+ | ||
+ return; | ||
+ } | ||
+ mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, p_crit_temp, p_emerg_temp, | ||
+ NULL); | ||
+} | ||
+ | ||
+ | ||
static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, | ||
int *p_temp) | ||
{ | ||
struct mlxsw_thermal_module *tz = tzdev->devdata; | ||
struct mlxsw_thermal *thermal = tz->parent; | ||
- struct device *dev = thermal->bus_info->dev; | ||
- char mtmp_pl[MLXSW_REG_MTMP_LEN]; | ||
+ struct device *dev; | ||
+ u16 sensor_index; | ||
int temp; | ||
int err; | ||
|
||
@@ -516,19 +543,13 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, | ||
return 0; | ||
} | ||
|
||
- /* Read module temperature. */ | ||
- mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + | ||
- tz->module, false, false); | ||
- err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl); | ||
- if (err) { | ||
- /* Do not return error - in case of broken module's sensor | ||
- * it will cause error message flooding. | ||
- */ | ||
- temp = 0; | ||
- *p_temp = (int) temp; | ||
- return 0; | ||
- } | ||
- mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL); | ||
+ dev = thermal->bus_info->dev; | ||
+ sensor_index = MLXSW_REG_MTMP_MODULE_INDEX_MIN + tz->module; | ||
+ | ||
+ /* Read module temperature and thresholds. */ | ||
+ mlxsw_thermal_module_temp_and_thresholds_get(thermal->core, | ||
+ sensor_index, &temp, | ||
+ NULL, NULL); | ||
*p_temp = temp; | ||
|
||
if (!temp) |
105 changes: 105 additions & 0 deletions
105
patch/0051-mlxsw-thermal-Read-module-temperature-thresholds-usi.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
From 0af8cae6c3eb4cb0519a972137587113a44f9f9c Mon Sep 17 00:00:00 2001 | ||
From: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Date: Thu, 3 Jun 2021 18:18:06 +0300 | ||
|
||
commit 72a64c2fe9d8a08c9c57fc22adc1b44d13f97cac upstream | ||
|
||
Subject: [PATCH 5/6] mlxsw: thermal: Read module temperature thresholds using | ||
MTMP register | ||
|
||
mlxsw_thermal_module_trips_update() is used to update the trip points of | ||
the module's thermal zone. Currently, this is done by querying the | ||
thresholds from the module's EEPROM via MCIA register. This data does | ||
not pass validation and in some cases can be unreliable. For example, | ||
due to some problem with transceiver module. | ||
|
||
Previous patch made it possible to read module's temperature and | ||
thresholds via MTMP register. Therefore, extend | ||
mlxsw_thermal_module_trips_update() to use the thresholds queried from | ||
MTMP, if valid. | ||
|
||
This is both more reliable and more efficient than current method, as | ||
temperature and thresholds are queried in one transaction instead of | ||
three. This is significant when working over a slow bus such as I2C. | ||
|
||
Signed-off-by: Mykola Kostenok <c_mykolak@nvidia.com> | ||
Acked-by: Vadim Pasternak <vadimp@nvidia.com> | ||
Signed-off-by: Ido Schimmel <idosch@nvidia.com> | ||
--- | ||
.../ethernet/mellanox/mlxsw/core_thermal.c | 40 +++++++++++-------- | ||
1 file changed, 23 insertions(+), 17 deletions(-) | ||
|
||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
index 0a151d175..754a9813a 100644 | ||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | ||
@@ -155,22 +155,27 @@ mlxsw_thermal_module_trips_reset(struct mlxsw_thermal_module *tz) | ||
|
||
static int | ||
mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core, | ||
- struct mlxsw_thermal_module *tz) | ||
+ struct mlxsw_thermal_module *tz, | ||
+ int crit_temp, int emerg_temp) | ||
{ | ||
- int crit_temp, emerg_temp; | ||
int err; | ||
|
||
- err = mlxsw_env_module_temp_thresholds_get(core, tz->module, | ||
- SFP_TEMP_HIGH_WARN, | ||
- &crit_temp); | ||
- if (err) | ||
- return err; | ||
- | ||
- err = mlxsw_env_module_temp_thresholds_get(core, tz->module, | ||
- SFP_TEMP_HIGH_ALARM, | ||
- &emerg_temp); | ||
- if (err) | ||
- return err; | ||
+ /* Do not try to query temperature thresholds directly from the module's | ||
+ * EEPROM if we got valid thresholds from MTMP. | ||
+ */ | ||
+ if (!emerg_temp || !crit_temp) { | ||
+ err = mlxsw_env_module_temp_thresholds_get(core, tz->module, | ||
+ SFP_TEMP_HIGH_WARN, | ||
+ &crit_temp); | ||
+ if (err) | ||
+ return err; | ||
+ | ||
+ err = mlxsw_env_module_temp_thresholds_get(core, tz->module, | ||
+ SFP_TEMP_HIGH_ALARM, | ||
+ &emerg_temp); | ||
+ if (err) | ||
+ return err; | ||
+ } | ||
|
||
if (crit_temp > emerg_temp) { | ||
dev_warn(dev, "%s : Critical threshold %d is above emergency threshold %d\n", | ||
@@ -532,9 +537,9 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, | ||
{ | ||
struct mlxsw_thermal_module *tz = tzdev->devdata; | ||
struct mlxsw_thermal *thermal = tz->parent; | ||
+ int temp, crit_temp, emerg_temp; | ||
struct device *dev; | ||
u16 sensor_index; | ||
- int temp; | ||
int err; | ||
|
||
/* Do not read temperature in initialization stage. */ | ||
@@ -549,14 +554,15 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, | ||
/* Read module temperature and thresholds. */ | ||
mlxsw_thermal_module_temp_and_thresholds_get(thermal->core, | ||
sensor_index, &temp, | ||
- NULL, NULL); | ||
+ &crit_temp, &emerg_temp); | ||
*p_temp = temp; | ||
|
||
if (!temp) | ||
return 0; | ||
|
||
/* Update trip points. */ | ||
- err = mlxsw_thermal_module_trips_update(dev, thermal->core, tz); | ||
+ err = mlxsw_thermal_module_trips_update(dev, thermal->core, tz, | ||
+ crit_temp, emerg_temp); | ||
if (!err && temp > 0) | ||
mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters