Skip to content

Commit ef0df4f

Browse files
vadimp-nvidiadavem330
authored andcommitted
mlxsw: core_thermal: Extend internal structures to support multi thermal areas
Introduce intermediate level for thermal zones areas. Currently all thermal zones are associated with thermal objects located within the main board. Such objects are created during driver initialization and removed during driver de-initialization. For line cards in modular system the thermal zones are to be associated with the specific line card. They should be created whenever new line card is available (inserted, validated, powered and enabled) and removed, when line card is getting unavailable. The thermal objects found on the line card #n are accessed by setting slot index to #n, while for access to objects found on the main board slot index should be set to default value zero. Each thermal area contains the set of thermal zones associated with particular slot index. Thus introduction of thermal zone areas allows to use the same APIs for the main board and line cards, by adding slot index argument. Signed-off-by: Vadim Pasternak <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fd27849 commit ef0df4f

File tree

1 file changed

+91
-57
lines changed

1 file changed

+91
-57
lines changed

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

Lines changed: 91 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ struct mlxsw_thermal_module {
8282
struct thermal_zone_device *tzdev;
8383
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
8484
int module; /* Module or gearbox number */
85+
u8 slot_index;
86+
};
87+
88+
struct mlxsw_thermal_area {
89+
struct mlxsw_thermal_module *tz_module_arr;
90+
u8 tz_module_num;
91+
struct mlxsw_thermal_module *tz_gearbox_arr;
92+
u8 tz_gearbox_num;
93+
u8 slot_index;
8594
};
8695

8796
struct mlxsw_thermal {
@@ -92,12 +101,9 @@ struct mlxsw_thermal {
92101
struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
93102
u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
94103
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
95-
struct mlxsw_thermal_module *tz_module_arr;
96-
u8 tz_module_num;
97-
struct mlxsw_thermal_module *tz_gearbox_arr;
98-
u8 tz_gearbox_num;
99104
unsigned int tz_highest_score;
100105
struct thermal_zone_device *tz_highest_dev;
106+
struct mlxsw_thermal_area line_cards[];
101107
};
102108

103109
static inline u8 mlxsw_state_to_duty(int state)
@@ -150,13 +156,15 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
150156
* EEPROM if we got valid thresholds from MTMP.
151157
*/
152158
if (!emerg_temp || !crit_temp) {
153-
err = mlxsw_env_module_temp_thresholds_get(core, 0, tz->module,
159+
err = mlxsw_env_module_temp_thresholds_get(core, tz->slot_index,
160+
tz->module,
154161
SFP_TEMP_HIGH_WARN,
155162
&crit_temp);
156163
if (err)
157164
return err;
158165

159-
err = mlxsw_env_module_temp_thresholds_get(core, 0, tz->module,
166+
err = mlxsw_env_module_temp_thresholds_get(core, tz->slot_index,
167+
tz->module,
160168
SFP_TEMP_HIGH_ALARM,
161169
&emerg_temp);
162170
if (err)
@@ -423,15 +431,16 @@ static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev,
423431

424432
static void
425433
mlxsw_thermal_module_temp_and_thresholds_get(struct mlxsw_core *core,
426-
u16 sensor_index, int *p_temp,
427-
int *p_crit_temp,
434+
u8 slot_index, u16 sensor_index,
435+
int *p_temp, int *p_crit_temp,
428436
int *p_emerg_temp)
429437
{
430438
char mtmp_pl[MLXSW_REG_MTMP_LEN];
431439
int err;
432440

433441
/* Read module temperature and thresholds. */
434-
mlxsw_reg_mtmp_pack(mtmp_pl, 0, sensor_index, false, false);
442+
mlxsw_reg_mtmp_pack(mtmp_pl, slot_index, sensor_index,
443+
false, false);
435444
err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl);
436445
if (err) {
437446
/* Set temperature and thresholds to zero to avoid passing
@@ -462,6 +471,7 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
462471

463472
/* Read module temperature and thresholds. */
464473
mlxsw_thermal_module_temp_and_thresholds_get(thermal->core,
474+
tz->slot_index,
465475
sensor_index, &temp,
466476
&crit_temp, &emerg_temp);
467477
*p_temp = temp;
@@ -576,7 +586,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
576586
int err;
577587

578588
index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
579-
mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
589+
mlxsw_reg_mtmp_pack(mtmp_pl, tz->slot_index, index, false, false);
580590

581591
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
582592
if (err)
@@ -704,25 +714,28 @@ static void mlxsw_thermal_module_tz_fini(struct thermal_zone_device *tzdev)
704714

705715
static int
706716
mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
707-
struct mlxsw_thermal *thermal, u8 module)
717+
struct mlxsw_thermal *thermal,
718+
struct mlxsw_thermal_area *area, u8 module)
708719
{
709720
struct mlxsw_thermal_module *module_tz;
710721
int dummy_temp, crit_temp, emerg_temp;
711722
u16 sensor_index;
712723

713724
sensor_index = MLXSW_REG_MTMP_MODULE_INDEX_MIN + module;
714-
module_tz = &thermal->tz_module_arr[module];
725+
module_tz = &area->tz_module_arr[module];
715726
/* Skip if parent is already set (case of port split). */
716727
if (module_tz->parent)
717728
return 0;
718729
module_tz->module = module;
730+
module_tz->slot_index = area->slot_index;
719731
module_tz->parent = thermal;
720732
memcpy(module_tz->trips, default_thermal_trips,
721733
sizeof(thermal->trips));
722734
/* Initialize all trip point. */
723735
mlxsw_thermal_module_trips_reset(module_tz);
724736
/* Read module temperature and thresholds. */
725-
mlxsw_thermal_module_temp_and_thresholds_get(core, sensor_index, &dummy_temp,
737+
mlxsw_thermal_module_temp_and_thresholds_get(core, area->slot_index,
738+
sensor_index, &dummy_temp,
726739
&crit_temp, &emerg_temp);
727740
/* Update trip point according to the module data. */
728741
return mlxsw_thermal_module_trips_update(dev, core, module_tz,
@@ -740,34 +753,39 @@ static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz)
740753

741754
static int
742755
mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
743-
struct mlxsw_thermal *thermal)
756+
struct mlxsw_thermal *thermal,
757+
struct mlxsw_thermal_area *area)
744758
{
745759
struct mlxsw_thermal_module *module_tz;
746760
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
747761
int i, err;
748762

749-
mlxsw_reg_mgpir_pack(mgpir_pl, 0);
763+
mlxsw_reg_mgpir_pack(mgpir_pl, area->slot_index);
750764
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
751765
if (err)
752766
return err;
753767

754768
mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
755-
&thermal->tz_module_num, NULL);
769+
&area->tz_module_num, NULL);
756770

757-
thermal->tz_module_arr = kcalloc(thermal->tz_module_num,
758-
sizeof(*thermal->tz_module_arr),
759-
GFP_KERNEL);
760-
if (!thermal->tz_module_arr)
771+
/* For modular system module counter could be zero. */
772+
if (!area->tz_module_num)
773+
return 0;
774+
775+
area->tz_module_arr = kcalloc(area->tz_module_num,
776+
sizeof(*area->tz_module_arr),
777+
GFP_KERNEL);
778+
if (!area->tz_module_arr)
761779
return -ENOMEM;
762780

763-
for (i = 0; i < thermal->tz_module_num; i++) {
764-
err = mlxsw_thermal_module_init(dev, core, thermal, i);
781+
for (i = 0; i < area->tz_module_num; i++) {
782+
err = mlxsw_thermal_module_init(dev, core, thermal, area, i);
765783
if (err)
766784
goto err_thermal_module_init;
767785
}
768786

769-
for (i = 0; i < thermal->tz_module_num; i++) {
770-
module_tz = &thermal->tz_module_arr[i];
787+
for (i = 0; i < area->tz_module_num; i++) {
788+
module_tz = &area->tz_module_arr[i];
771789
if (!module_tz->parent)
772790
continue;
773791
err = mlxsw_thermal_module_tz_init(module_tz);
@@ -779,20 +797,21 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
779797

780798
err_thermal_module_tz_init:
781799
err_thermal_module_init:
782-
for (i = thermal->tz_module_num - 1; i >= 0; i--)
783-
mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
784-
kfree(thermal->tz_module_arr);
800+
for (i = area->tz_module_num - 1; i >= 0; i--)
801+
mlxsw_thermal_module_fini(&area->tz_module_arr[i]);
802+
kfree(area->tz_module_arr);
785803
return err;
786804
}
787805

788806
static void
789-
mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
807+
mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal,
808+
struct mlxsw_thermal_area *area)
790809
{
791810
int i;
792811

793-
for (i = thermal->tz_module_num - 1; i >= 0; i--)
794-
mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
795-
kfree(thermal->tz_module_arr);
812+
for (i = area->tz_module_num - 1; i >= 0; i--)
813+
mlxsw_thermal_module_fini(&area->tz_module_arr[i]);
814+
kfree(area->tz_module_arr);
796815
}
797816

798817
static int
@@ -828,7 +847,8 @@ mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
828847

829848
static int
830849
mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
831-
struct mlxsw_thermal *thermal)
850+
struct mlxsw_thermal *thermal,
851+
struct mlxsw_thermal_area *area)
832852
{
833853
enum mlxsw_reg_mgpir_device_type device_type;
834854
struct mlxsw_thermal_module *gearbox_tz;
@@ -837,7 +857,7 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
837857
int i;
838858
int err;
839859

840-
mlxsw_reg_mgpir_pack(mgpir_pl, 0);
860+
mlxsw_reg_mgpir_pack(mgpir_pl, area->slot_index);
841861
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
842862
if (err)
843863
return err;
@@ -848,19 +868,20 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
848868
!gbox_num)
849869
return 0;
850870

851-
thermal->tz_gearbox_num = gbox_num;
852-
thermal->tz_gearbox_arr = kcalloc(thermal->tz_gearbox_num,
853-
sizeof(*thermal->tz_gearbox_arr),
854-
GFP_KERNEL);
855-
if (!thermal->tz_gearbox_arr)
871+
area->tz_gearbox_num = gbox_num;
872+
area->tz_gearbox_arr = kcalloc(area->tz_gearbox_num,
873+
sizeof(*area->tz_gearbox_arr),
874+
GFP_KERNEL);
875+
if (!area->tz_gearbox_arr)
856876
return -ENOMEM;
857877

858-
for (i = 0; i < thermal->tz_gearbox_num; i++) {
859-
gearbox_tz = &thermal->tz_gearbox_arr[i];
878+
for (i = 0; i < area->tz_gearbox_num; i++) {
879+
gearbox_tz = &area->tz_gearbox_arr[i];
860880
memcpy(gearbox_tz->trips, default_thermal_trips,
861881
sizeof(thermal->trips));
862882
gearbox_tz->module = i;
863883
gearbox_tz->parent = thermal;
884+
gearbox_tz->slot_index = area->slot_index;
864885
err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
865886
if (err)
866887
goto err_thermal_gearbox_tz_init;
@@ -870,19 +891,20 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
870891

871892
err_thermal_gearbox_tz_init:
872893
for (i--; i >= 0; i--)
873-
mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
874-
kfree(thermal->tz_gearbox_arr);
894+
mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
895+
kfree(area->tz_gearbox_arr);
875896
return err;
876897
}
877898

878899
static void
879-
mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal)
900+
mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal,
901+
struct mlxsw_thermal_area *area)
880902
{
881903
int i;
882904

883-
for (i = thermal->tz_gearbox_num - 1; i >= 0; i--)
884-
mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
885-
kfree(thermal->tz_gearbox_arr);
905+
for (i = area->tz_gearbox_num - 1; i >= 0; i--)
906+
mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
907+
kfree(area->tz_gearbox_arr);
886908
}
887909

888910
int mlxsw_thermal_init(struct mlxsw_core *core,
@@ -892,19 +914,29 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
892914
char mfcr_pl[MLXSW_REG_MFCR_LEN] = { 0 };
893915
enum mlxsw_reg_mfcr_pwm_frequency freq;
894916
struct device *dev = bus_info->dev;
917+
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
895918
struct mlxsw_thermal *thermal;
919+
u8 pwm_active, num_of_slots;
896920
u16 tacho_active;
897-
u8 pwm_active;
898921
int err, i;
899922

900-
thermal = devm_kzalloc(dev, sizeof(*thermal),
901-
GFP_KERNEL);
923+
mlxsw_reg_mgpir_pack(mgpir_pl, 0);
924+
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
925+
if (err)
926+
return err;
927+
928+
mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, NULL,
929+
&num_of_slots);
930+
931+
thermal = kzalloc(struct_size(thermal, line_cards, num_of_slots + 1),
932+
GFP_KERNEL);
902933
if (!thermal)
903934
return -ENOMEM;
904935

905936
thermal->core = core;
906937
thermal->bus_info = bus_info;
907938
memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
939+
thermal->line_cards[0].slot_index = 0;
908940

909941
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
910942
if (err) {
@@ -970,11 +1002,13 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
9701002
goto err_thermal_zone_device_register;
9711003
}
9721004

973-
err = mlxsw_thermal_modules_init(dev, core, thermal);
1005+
err = mlxsw_thermal_modules_init(dev, core, thermal,
1006+
&thermal->line_cards[0]);
9741007
if (err)
9751008
goto err_thermal_modules_init;
9761009

977-
err = mlxsw_thermal_gearboxes_init(dev, core, thermal);
1010+
err = mlxsw_thermal_gearboxes_init(dev, core, thermal,
1011+
&thermal->line_cards[0]);
9781012
if (err)
9791013
goto err_thermal_gearboxes_init;
9801014

@@ -986,9 +1020,9 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
9861020
return 0;
9871021

9881022
err_thermal_zone_device_enable:
989-
mlxsw_thermal_gearboxes_fini(thermal);
1023+
mlxsw_thermal_gearboxes_fini(thermal, &thermal->line_cards[0]);
9901024
err_thermal_gearboxes_init:
991-
mlxsw_thermal_modules_fini(thermal);
1025+
mlxsw_thermal_modules_fini(thermal, &thermal->line_cards[0]);
9921026
err_thermal_modules_init:
9931027
if (thermal->tzdev) {
9941028
thermal_zone_device_unregister(thermal->tzdev);
@@ -1001,16 +1035,16 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
10011035
thermal_cooling_device_unregister(thermal->cdevs[i]);
10021036
err_reg_write:
10031037
err_reg_query:
1004-
devm_kfree(dev, thermal);
1038+
kfree(thermal);
10051039
return err;
10061040
}
10071041

10081042
void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
10091043
{
10101044
int i;
10111045

1012-
mlxsw_thermal_gearboxes_fini(thermal);
1013-
mlxsw_thermal_modules_fini(thermal);
1046+
mlxsw_thermal_gearboxes_fini(thermal, &thermal->line_cards[0]);
1047+
mlxsw_thermal_modules_fini(thermal, &thermal->line_cards[0]);
10141048
if (thermal->tzdev) {
10151049
thermal_zone_device_unregister(thermal->tzdev);
10161050
thermal->tzdev = NULL;
@@ -1023,5 +1057,5 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
10231057
}
10241058
}
10251059

1026-
devm_kfree(thermal->bus_info->dev, thermal);
1060+
kfree(thermal);
10271061
}

0 commit comments

Comments
 (0)