@@ -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
104104struct 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
116118static 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+
557599static 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+
782910int 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 );
8761010err_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