Skip to content

Commit

Permalink
hw-mgmt: kernel patches: 4.19: mlxsw: Add support for line card hwmon…
Browse files Browse the repository at this point in the history
… and thermal

Add line card thermal area registration and de-registration interfaces
to thermal initialization/de-initialization flows.

Add callback for line card thermal area activation and de-activation.
These callbacks are to be invoked, when firmware indicates it got
active or inactive state.

When "active event" is received for particular line card, its thermal
interfaces should be configured according to the configuration obtained
from the firmware. When opposite "inactive event" is received all these
interfaces should be removed.

Each line card is associated with the relevant thermal area, which may
contain thermal zones for cages and gearboxes found on this line card.

For example thermal zone for module #9 located at line card #7 will
have type:
mlxsw-lc7-module9.
And thermal zone for gearbox #2 located at line card #5 will have type:
mlxsw-lc5-gearbox2.

Add line card 'hwmon' registration and de-registration interfaces to
'hwmon' initialization/de-initialization flows.

Add callback for line card 'hwmon' objects activation and
de-activation. These callbacks are to be invoked, when firmware
indicates it got active or inactive state.

When "active event" is received for particular line card, its 'hwmon'
interfaces should be configured according to the configuration obtained
from the firmware. When opposite "inactive event" is received all these
interfaces should be removed.

Each line card is associated with the relevant 'hwmon' devices, which
may contain thermal attributes for the cages and gearboxes found on
this line card.

For example cage temperature for module #9 located at line card #7 will
be exposed by utility 'sensors' like:
linecard#07 front panel 009:	+32.0°C  (crit = +70.0°C, emerg = +80.0°C)
And temperature for gearbox #3 located at line card #5 will be exposed
like:
linecard#05 gearbox 003:		+41.0°C  (highest = +41.0°C)

Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
  • Loading branch information
vadimp-nvidia committed Feb 28, 2021
1 parent 99573cb commit c7a5e2b
Show file tree
Hide file tree
Showing 2 changed files with 354 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
From 5427cd84db8ed4b8527b9e2e9c7fc347421e816c Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@nvidia.com>
Date: Sun, 28 Feb 2021 12:03:32 +0200
Subject: [PATCH backport 4.19 1/2] mlxsw: core_thermal: Add line card support

Add line card thermal area registration and de-registration interfaces
to thermal initialization/de-initialization flows.

Add callback for line card thermal area activation and de-activation.
These callbacks are to be invoked, when firmware indicates it got
active or inactive state.

When "active event" is received for particular line card, its thermal
interfaces should be configured according to the configuration obtained
from the firmware. When opposite "inactive event" is received all these
interfaces should be removed.

Each line card is associated with the relevant thermal area, which may
contain thermal zones for cages and gearboxes found on this line card.

For example thermal zone for module #9 located at line card #7 will
have type:
mlxsw-lc7-module9.
And thermal zone for gearbox #2 located at line card #5 will have type:
mlxsw-lc5-gearbox2.

Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 98 ++++++++++++++++++++++
1 file changed, 98 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index 23bb61a4fc28..c849646c0dc4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -128,6 +128,7 @@ struct mlxsw_thermal {
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
enum thermal_device_mode mode;
struct mlxsw_thermal_area *main;
+ struct mlxsw_thermal_area **linecards;
unsigned int tz_highest_score;
struct thermal_zone_device *tz_highest_dev;
bool initializing; /* Driver is in initialization stage */
@@ -1059,6 +1060,97 @@ mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal,
mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
}

+static void
+mlxsw_thermal_got_active(struct mlxsw_core *mlxsw_core, u8 slot_index,
+ const struct mlxsw_linecard *linecard, void *priv)
+{
+ struct mlxsw_thermal *thermal = priv;
+ struct mlxsw_thermal_area *area = thermal->linecards[slot_index];
+ struct mlxsw_env_gearbox_sensors_map map;
+ int err;
+
+ err = mlxsw_thermal_modules_init(thermal->bus_info->dev, thermal->core,
+ thermal, area);
+ if (err)
+ goto err_thermal_linecard_modules_init;
+
+ map.sensor_bit_map = area->gearbox_sensor_map;
+ err = mlxsw_env_sensor_map_create(thermal->core, thermal->bus_info,
+ linecard->slot_index, &map);
+ if (err)
+ goto err_thermal_linecard_env_sensor_map_create;
+
+ err = mlxsw_thermal_gearboxes_init(thermal->bus_info->dev, thermal->core,
+ thermal, area);
+ if (err)
+ goto err_thermal_linecard_gearboxes_init;
+
+ return;
+
+err_thermal_linecard_gearboxes_init:
+ mlxsw_env_sensor_map_destroy(thermal->bus_info,
+ area->gearbox_sensor_map);
+err_thermal_linecard_env_sensor_map_create:
+ mlxsw_thermal_modules_fini(thermal, area);
+err_thermal_linecard_modules_init:
+ devm_kfree(thermal->bus_info->dev, area);
+}
+
+static void mlxsw_thermal_got_inactive(struct mlxsw_core *mlxsw_core, u8 slot_index,
+ const struct mlxsw_linecard *linecard, void *priv)
+{
+ struct mlxsw_thermal *thermal = priv;
+ struct mlxsw_thermal_area *area = thermal->linecards[slot_index];
+
+ mlxsw_thermal_gearboxes_fini(thermal, area);
+ mlxsw_env_sensor_map_destroy(thermal->bus_info,
+ area->gearbox_sensor_map);
+ mlxsw_thermal_modules_fini(thermal, area);
+ devm_kfree(thermal->bus_info->dev, area);
+}
+
+static struct mlxsw_linecards_event_ops mlxsw_thermal_event_ops = {
+ .got_active = mlxsw_thermal_got_active,
+ .got_inactive = mlxsw_thermal_got_inactive,
+};
+
+static int mlxsw_thermal_linecards_register(struct mlxsw_core *mlxsw_core,
+ struct mlxsw_thermal *thermal)
+{
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_core);
+ int err;
+
+ if (!linecards || !linecards->count)
+ return 0;
+
+ thermal->linecards = kcalloc(linecards->count, sizeof(*thermal->linecards),
+ GFP_KERNEL);
+ if (!thermal->linecards)
+ return -ENOMEM;
+
+ err = mlxsw_linecards_event_ops_register(mlxsw_core,
+ &mlxsw_thermal_event_ops,
+ thermal);
+ if (err)
+ goto err_linecards_event_ops_register;
+
+err_linecards_event_ops_register:
+ kfree(thermal->linecards);
+ return err;
+}
+
+static void mlxsw_thermal_linecards_unregister(struct mlxsw_thermal *thermal)
+{
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(thermal->core);
+
+ if (!linecards || !linecards->count)
+ return;
+
+ mlxsw_linecards_event_ops_unregister(thermal->core,
+ &mlxsw_thermal_event_ops, thermal);
+ kfree(thermal->linecards);
+}
+
int mlxsw_thermal_init(struct mlxsw_core *core,
const struct mlxsw_bus_info *bus_info,
struct mlxsw_thermal **p_thermal)
@@ -1164,11 +1256,16 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
if (err)
goto err_thermal_gearboxes_init;

+ err = mlxsw_thermal_linecards_register(core, thermal);
+ if (err)
+ goto err_linecards_register;
+
thermal->mode = THERMAL_DEVICE_ENABLED;
thermal->initializing = false;
*p_thermal = thermal;
return 0;

+err_linecards_register:
err_thermal_gearboxes_init:
mlxsw_thermal_gearboxes_main_fini(thermal->main);
err_thermal_gearboxes_main_init:
@@ -1195,6 +1292,7 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
{
int i;

+ mlxsw_thermal_linecards_unregister(thermal);
mlxsw_thermal_gearboxes_fini(thermal, thermal->main);
mlxsw_thermal_gearboxes_main_fini(thermal->main);
mlxsw_thermal_modules_fini(thermal, thermal->main);
--
2.11.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
From 8379b1139130da0bbd647f6a86eb3290bbd66429 Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@nvidia.com>
Date: Sun, 28 Feb 2021 13:48:37 +0200
Subject: [PATCH backport 4.19 2/2] mlxsw: core_hwmon: Add line card support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add line card 'hwmon' registration and de-registration interfaces to
'hwmon' initialization/de-initialization flows.

Add callback for line card 'hwmon' objects activation and
de-activation. These callbacks are to be invoked, when firmware
indicates it got active or inactive state.

When "active event" is received for particular line card, its 'hwmon'
interfaces should be configured according to the configuration obtained
from the firmware. When opposite "inactive event" is received all these
interfaces should be removed.

Each line card is associated with the relevant 'hwmon' devices, which
may contain thermal attributes for the cages and gearboxes found on
this line card.

For example cage temperature for module #9 located at line card #7 will
be exposed by utility 'sensors' like:
linecard#07 front panel 009: +32.0°C (crit = +70.0°C, emerg = +80.0°C)
And temperature for gearbox #3 located at line card #5 will be exposed
like:
linecard#05 gearbox 003: +41.0°C (highest = +41.0°C)

Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
---
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 110 +++++++++++++++++++++++
1 file changed, 110 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
index 6c95335c23ea..15a9eecd4c96 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -61,6 +61,7 @@ struct mlxsw_hwmon {
struct mlxsw_core *core;
const struct mlxsw_bus_info *bus_info;
struct mlxsw_hwmon_dev *main;
+ struct mlxsw_hwmon_dev **linecards;
};

static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
@@ -726,6 +727,108 @@ mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev, u8 gbox_num)
return 0;
}

+static void
+mlxsw_hwmon_got_active(struct mlxsw_core *mlxsw_core, u8 slot_index,
+ const struct mlxsw_linecard *linecard, void *priv)
+{
+ struct mlxsw_hwmon *hwmon = priv;
+ struct mlxsw_hwmon_dev *lc = hwmon->linecards[slot_index - 1];
+ struct device *dev = hwmon->bus_info->dev;
+ struct mlxsw_env_gearbox_sensors_map map;
+ int err;
+
+ err = mlxsw_hwmon_module_init(lc);
+ if (err)
+ goto err_hwmon_linecard_module_init;
+
+ map.sensor_bit_map = lc->gearbox_sensor_map;
+ err = mlxsw_env_sensor_map_create(hwmon->core,
+ hwmon->bus_info, slot_index,
+ &map);
+ if (err)
+ goto err_hwmon_linecard_env_sensor_map_create;
+
+ err = mlxsw_hwmon_gearbox_init(lc, map.sensor_count);
+ if (err)
+ goto err_hwmon_linecard_gearbox_init;
+
+ lc->groups[0] = &lc->group;
+ lc->group.attrs = lc->attrs;
+ lc->slot_index = slot_index;
+ sprintf(lc->name, "%s#%02u", "linecard", slot_index);
+ lc->hwmon_dev = hwmon_device_register_with_groups(dev, (const char *) lc->name,
+ lc, lc->groups);
+ if (IS_ERR(lc->hwmon_dev)) {
+ err = PTR_ERR(lc->hwmon_dev);
+ goto err_hwmon_linecard_register;
+ }
+
+ return;
+
+err_hwmon_linecard_register:
+err_hwmon_linecard_gearbox_init:
+ mlxsw_env_sensor_map_destroy(hwmon->bus_info,
+ lc->gearbox_sensor_map);
+err_hwmon_linecard_env_sensor_map_create:
+err_hwmon_linecard_module_init:
+ return;
+}
+
+static void
+mlxsw_hwmon_got_inactive(struct mlxsw_core *mlxsw_core, u8 slot_index,
+ const struct mlxsw_linecard *linecard, void *priv)
+{
+ struct mlxsw_hwmon *hwmon = priv;
+ struct mlxsw_hwmon_dev *lc = hwmon->linecards[slot_index - 1];
+
+ if (lc->hwmon_dev)
+ hwmon_device_unregister(lc->hwmon_dev);
+ mlxsw_env_sensor_map_destroy(hwmon->bus_info,
+ lc->gearbox_sensor_map);
+ hwmon->linecards[slot_index - 1] = NULL;
+}
+
+static struct mlxsw_linecards_event_ops mlxsw_hwmon_event_ops = {
+ .got_active = mlxsw_hwmon_got_active,
+ .got_inactive = mlxsw_hwmon_got_inactive,
+};
+
+static int mlxsw_hwmon_linecards_register(struct mlxsw_hwmon *hwmon)
+{
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(hwmon->core);
+ int err;
+
+ if (!linecards || !linecards->count)
+ return 0;
+
+ hwmon->linecards = kcalloc(linecards->count, sizeof(*hwmon->linecards),
+ GFP_KERNEL);
+ if (!hwmon->linecards)
+ return -ENOMEM;
+
+ err = mlxsw_linecards_event_ops_register(hwmon->core,
+ &mlxsw_hwmon_event_ops,
+ hwmon);
+ if (err)
+ goto err_linecards_event_ops_register;
+
+err_linecards_event_ops_register:
+ kfree(hwmon->linecards);
+ return err;
+}
+
+static void mlxsw_hwmon_linecards_unregister(struct mlxsw_hwmon *hwmon)
+{
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(hwmon->core);
+
+ if (!linecards || !linecards->count)
+ return;
+
+ mlxsw_linecards_event_ops_unregister(hwmon->core,
+ &mlxsw_hwmon_event_ops, hwmon);
+ kfree(hwmon->linecards);
+}
+
int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
const struct mlxsw_bus_info *mlxsw_bus_info,
struct mlxsw_hwmon **p_hwmon)
@@ -778,10 +881,16 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
goto err_hwmon_register;
}

+ err = mlxsw_hwmon_linecards_register(mlxsw_hwmon);
+ if (err)
+ goto err_linecards_register;
+
mlxsw_hwmon->main->hwmon_dev = hwmon_dev;
*p_hwmon = mlxsw_hwmon;
return 0;

+err_linecards_register:
+ hwmon_device_unregister(mlxsw_hwmon->main->hwmon_dev);
err_hwmon_register:
err_gearbox_init:
mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon->main);
@@ -797,6 +906,7 @@ err_hwmon_main_init:

void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
{
+ mlxsw_hwmon_linecards_unregister(mlxsw_hwmon);
hwmon_device_unregister(mlxsw_hwmon->main->hwmon_dev);
mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon->main);
kfree(mlxsw_hwmon->main);
--
2.11.0

0 comments on commit c7a5e2b

Please sign in to comment.