Commit a50c1e35 authored by Ivan Vecera's avatar Ivan Vecera Committed by David S. Miller

mlxsw: core: Implement thermal zone

Implement thermal zone for mlxsw based HW. It uses temperature sensor
provided by ASIC (the same as mlxsw hwmon interface) to report current
temp to thermal core. The ASIC's PWM is then used to control speed
of system fans registered as cooling devices.
Signed-off-by: default avatarIvan Vecera <cera@cera.cz>
Reviewed-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 55c63aaa
...@@ -19,6 +19,15 @@ config MLXSW_CORE_HWMON ...@@ -19,6 +19,15 @@ config MLXSW_CORE_HWMON
---help--- ---help---
Say Y here if you want to expose HWMON interface on mlxsw devices. Say Y here if you want to expose HWMON interface on mlxsw devices.
config MLXSW_CORE_THERMAL
bool "Thermal zone support for Mellanox Technologies Switch ASICs"
depends on MLXSW_CORE && THERMAL
depends on !(MLXSW_CORE=y && THERMAL=m)
default y
---help---
Say Y here if you want to automatically control fans speed according
ambient temperature reported by ASIC.
config MLXSW_PCI config MLXSW_PCI
tristate "PCI bus implementation for Mellanox Technologies Switch ASICs" tristate "PCI bus implementation for Mellanox Technologies Switch ASICs"
depends on PCI && HAS_DMA && HAS_IOMEM && MLXSW_CORE depends on PCI && HAS_DMA && HAS_IOMEM && MLXSW_CORE
......
obj-$(CONFIG_MLXSW_CORE) += mlxsw_core.o obj-$(CONFIG_MLXSW_CORE) += mlxsw_core.o
mlxsw_core-objs := core.o mlxsw_core-objs := core.o
mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o
mlxsw_core-$(CONFIG_MLXSW_CORE_THERMAL) += core_thermal.o
obj-$(CONFIG_MLXSW_PCI) += mlxsw_pci.o obj-$(CONFIG_MLXSW_PCI) += mlxsw_pci.o
mlxsw_pci-objs := pci.o mlxsw_pci-objs := pci.o
obj-$(CONFIG_MLXSW_I2C) += mlxsw_i2c.o obj-$(CONFIG_MLXSW_I2C) += mlxsw_i2c.o
......
...@@ -131,6 +131,7 @@ struct mlxsw_core { ...@@ -131,6 +131,7 @@ struct mlxsw_core {
} lag; } lag;
struct mlxsw_res res; struct mlxsw_res res;
struct mlxsw_hwmon *hwmon; struct mlxsw_hwmon *hwmon;
struct mlxsw_thermal *thermal;
struct mlxsw_core_port ports[MLXSW_PORT_MAX_PORTS]; struct mlxsw_core_port ports[MLXSW_PORT_MAX_PORTS];
unsigned long driver_priv[0]; unsigned long driver_priv[0];
/* driver_priv has to be always the last item */ /* driver_priv has to be always the last item */
...@@ -1162,6 +1163,11 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, ...@@ -1162,6 +1163,11 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
if (err) if (err)
goto err_hwmon_init; goto err_hwmon_init;
err = mlxsw_thermal_init(mlxsw_core, mlxsw_bus_info,
&mlxsw_core->thermal);
if (err)
goto err_thermal_init;
if (mlxsw_driver->init) { if (mlxsw_driver->init) {
err = mlxsw_driver->init(mlxsw_core, mlxsw_bus_info); err = mlxsw_driver->init(mlxsw_core, mlxsw_bus_info);
if (err) if (err)
...@@ -1178,6 +1184,7 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, ...@@ -1178,6 +1184,7 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
if (mlxsw_core->driver->fini) if (mlxsw_core->driver->fini)
mlxsw_core->driver->fini(mlxsw_core); mlxsw_core->driver->fini(mlxsw_core);
err_driver_init: err_driver_init:
err_thermal_init:
err_hwmon_init: err_hwmon_init:
devlink_unregister(devlink); devlink_unregister(devlink);
err_devlink_register: err_devlink_register:
...@@ -1204,6 +1211,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core) ...@@ -1204,6 +1211,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core)
mlxsw_core_debugfs_fini(mlxsw_core); mlxsw_core_debugfs_fini(mlxsw_core);
if (mlxsw_core->driver->fini) if (mlxsw_core->driver->fini)
mlxsw_core->driver->fini(mlxsw_core); mlxsw_core->driver->fini(mlxsw_core);
mlxsw_thermal_fini(mlxsw_core->thermal);
devlink_unregister(devlink); devlink_unregister(devlink);
mlxsw_emad_fini(mlxsw_core); mlxsw_emad_fini(mlxsw_core);
mlxsw_core->bus->fini(mlxsw_core->bus_priv); mlxsw_core->bus->fini(mlxsw_core->bus_priv);
......
...@@ -321,4 +321,28 @@ static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core, ...@@ -321,4 +321,28 @@ static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
#endif #endif
struct mlxsw_thermal;
#ifdef CONFIG_MLXSW_CORE_THERMAL
int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
const struct mlxsw_bus_info *mlxsw_bus_info,
struct mlxsw_thermal **p_thermal);
void mlxsw_thermal_fini(struct mlxsw_thermal *thermal);
#else
static inline int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
const struct mlxsw_bus_info *mlxsw_bus_info,
struct mlxsw_thermal **p_thermal)
{
return 0;
}
static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
{
}
#endif
#endif #endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment