Skip to content

Commit f14f4e6

Browse files
mellanoxbmcdavem330
authored andcommitted
mlxsw: core: Extend thermal core with per inter-connect device thermal zones
Add a dedicated thermal zone for each inter-connect device. The current temperature is obtained from inter-connect temperature sensor and the default trip points are set to the same values as default ASIC trip points. These settings could be changed from the user space. A cooling device (fan) is bound to all inter-connect devices. Signed-off-by: Vadim Pasternak <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Acked-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c04b6ea commit f14f4e6

File tree

1 file changed

+136
-1
lines changed

1 file changed

+136
-1
lines changed

drivers/net/ethernet/mellanox/mlxsw/core_thermal.c

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ struct mlxsw_thermal_module {
9898
struct thermal_zone_device *tzdev;
9999
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
100100
enum thermal_device_mode mode;
101-
int module;
101+
int module; /* Module or gearbox number */
102102
};
103103

104104
struct mlxsw_thermal {
@@ -111,6 +111,8 @@ struct mlxsw_thermal {
111111
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
112112
enum thermal_device_mode mode;
113113
struct mlxsw_thermal_module *tz_module_arr;
114+
struct mlxsw_thermal_module *tz_gearbox_arr;
115+
u8 tz_gearbox_num;
114116
};
115117

116118
static inline u8 mlxsw_state_to_duty(int state)
@@ -554,6 +556,46 @@ static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
554556
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
555557
};
556558

559+
static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
560+
int *p_temp)
561+
{
562+
struct mlxsw_thermal_module *tz = tzdev->devdata;
563+
struct mlxsw_thermal *thermal = tz->parent;
564+
char mtmp_pl[MLXSW_REG_MTMP_LEN];
565+
unsigned int temp;
566+
u16 index;
567+
int err;
568+
569+
index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
570+
mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
571+
572+
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
573+
if (err)
574+
return err;
575+
576+
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
577+
578+
*p_temp = (int) temp;
579+
return 0;
580+
}
581+
582+
static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
583+
.bind = mlxsw_thermal_module_bind,
584+
.unbind = mlxsw_thermal_module_unbind,
585+
.get_mode = mlxsw_thermal_module_mode_get,
586+
.set_mode = mlxsw_thermal_module_mode_set,
587+
.get_temp = mlxsw_thermal_gearbox_temp_get,
588+
.get_trip_type = mlxsw_thermal_module_trip_type_get,
589+
.get_trip_temp = mlxsw_thermal_module_trip_temp_get,
590+
.set_trip_temp = mlxsw_thermal_module_trip_temp_set,
591+
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
592+
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
593+
};
594+
595+
static struct thermal_zone_params mlxsw_thermal_gearbox_params = {
596+
.governor_name = "user_space",
597+
};
598+
557599
static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
558600
unsigned long *p_state)
559601
{
@@ -779,6 +821,92 @@ mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
779821
kfree(thermal->tz_module_arr);
780822
}
781823

824+
static int
825+
mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
826+
{
827+
char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
828+
829+
snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
830+
gearbox_tz->module + 1);
831+
gearbox_tz->tzdev = thermal_zone_device_register(tz_name,
832+
MLXSW_THERMAL_NUM_TRIPS,
833+
MLXSW_THERMAL_TRIP_MASK,
834+
gearbox_tz,
835+
&mlxsw_thermal_gearbox_ops,
836+
&mlxsw_thermal_gearbox_params,
837+
0, 0);
838+
if (IS_ERR(gearbox_tz->tzdev))
839+
return PTR_ERR(gearbox_tz->tzdev);
840+
841+
return 0;
842+
}
843+
844+
static void
845+
mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
846+
{
847+
thermal_zone_device_unregister(gearbox_tz->tzdev);
848+
}
849+
850+
static int
851+
mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
852+
struct mlxsw_thermal *thermal)
853+
{
854+
struct mlxsw_thermal_module *gearbox_tz;
855+
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
856+
int i;
857+
int err;
858+
859+
if (!mlxsw_core_res_query_enabled(core))
860+
return 0;
861+
862+
mlxsw_reg_mgpir_pack(mgpir_pl);
863+
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
864+
if (err)
865+
return err;
866+
867+
mlxsw_reg_mgpir_unpack(mgpir_pl, &thermal->tz_gearbox_num, NULL, NULL);
868+
if (!thermal->tz_gearbox_num)
869+
return 0;
870+
871+
thermal->tz_gearbox_arr = kcalloc(thermal->tz_gearbox_num,
872+
sizeof(*thermal->tz_gearbox_arr),
873+
GFP_KERNEL);
874+
if (!thermal->tz_gearbox_arr)
875+
return -ENOMEM;
876+
877+
for (i = 0; i < thermal->tz_gearbox_num; i++) {
878+
gearbox_tz = &thermal->tz_gearbox_arr[i];
879+
memcpy(gearbox_tz->trips, default_thermal_trips,
880+
sizeof(thermal->trips));
881+
gearbox_tz->module = i;
882+
gearbox_tz->parent = thermal;
883+
err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
884+
if (err)
885+
goto err_unreg_tz_gearbox;
886+
}
887+
888+
return 0;
889+
890+
err_unreg_tz_gearbox:
891+
for (i--; i >= 0; i--)
892+
mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
893+
kfree(thermal->tz_gearbox_arr);
894+
return err;
895+
}
896+
897+
static void
898+
mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal)
899+
{
900+
int i;
901+
902+
if (!mlxsw_core_res_query_enabled(thermal->core))
903+
return;
904+
905+
for (i = thermal->tz_gearbox_num - 1; i >= 0; i--)
906+
mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
907+
kfree(thermal->tz_gearbox_arr);
908+
}
909+
782910
int mlxsw_thermal_init(struct mlxsw_core *core,
783911
const struct mlxsw_bus_info *bus_info,
784912
struct mlxsw_thermal **p_thermal)
@@ -869,10 +997,16 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
869997
if (err)
870998
goto err_unreg_tzdev;
871999

1000+
err = mlxsw_thermal_gearboxes_init(dev, core, thermal);
1001+
if (err)
1002+
goto err_unreg_modules_tzdev;
1003+
8721004
thermal->mode = THERMAL_DEVICE_ENABLED;
8731005
*p_thermal = thermal;
8741006
return 0;
8751007

1008+
err_unreg_modules_tzdev:
1009+
mlxsw_thermal_modules_fini(thermal);
8761010
err_unreg_tzdev:
8771011
if (thermal->tzdev) {
8781012
thermal_zone_device_unregister(thermal->tzdev);
@@ -891,6 +1025,7 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
8911025
{
8921026
int i;
8931027

1028+
mlxsw_thermal_gearboxes_fini(thermal);
8941029
mlxsw_thermal_modules_fini(thermal);
8951030
if (thermal->tzdev) {
8961031
thermal_zone_device_unregister(thermal->tzdev);

0 commit comments

Comments
 (0)