@@ -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
8796struct 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
103109static 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
424432static void
425433mlxsw_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
705715static int
706716mlxsw_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
741754static int
742755mlxsw_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
780798err_thermal_module_tz_init :
781799err_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
788806static 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
798817static int
@@ -828,7 +847,8 @@ mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
828847
829848static int
830849mlxsw_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
871892err_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
878899static 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
888910int 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
9881022err_thermal_zone_device_enable :
989- mlxsw_thermal_gearboxes_fini (thermal );
1023+ mlxsw_thermal_gearboxes_fini (thermal , & thermal -> line_cards [ 0 ] );
9901024err_thermal_gearboxes_init :
991- mlxsw_thermal_modules_fini (thermal );
1025+ mlxsw_thermal_modules_fini (thermal , & thermal -> line_cards [ 0 ] );
9921026err_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 ]);
10021036err_reg_write :
10031037err_reg_query :
1004- devm_kfree ( dev , thermal );
1038+ kfree ( thermal );
10051039 return err ;
10061040}
10071041
10081042void 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