Commit 41f698b0 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-thermal-zone'

Jiri Pirko says:

====================
mlxsw: core: Implement thermal zone

Implement thermal zone for mlxsw based HW.
The first patch is just a register dependency for the second patch.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 29033726 a50c1e35
...@@ -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.
...@@ -4518,6 +4518,54 @@ static inline void mlxsw_reg_mfsm_pack(char *payload, u8 tacho) ...@@ -4518,6 +4518,54 @@ static inline void mlxsw_reg_mfsm_pack(char *payload, u8 tacho)
mlxsw_reg_mfsm_tacho_set(payload, tacho); mlxsw_reg_mfsm_tacho_set(payload, tacho);
} }
/* MFSL - Management Fan Speed Limit Register
* ------------------------------------------
* The Fan Speed Limit register is used to configure the fan speed
* event / interrupt notification mechanism. Fan speed threshold are
* defined for both under-speed and over-speed.
*/
#define MLXSW_REG_MFSL_ID 0x9004
#define MLXSW_REG_MFSL_LEN 0x0C
MLXSW_REG_DEFINE(mfsl, MLXSW_REG_MFSL_ID, MLXSW_REG_MFSL_LEN);
/* reg_mfsl_tacho
* Fan tachometer index.
* Access: Index
*/
MLXSW_ITEM32(reg, mfsl, tacho, 0x00, 24, 4);
/* reg_mfsl_tach_min
* Tachometer minimum value (minimum RPM).
* Access: RW
*/
MLXSW_ITEM32(reg, mfsl, tach_min, 0x04, 0, 16);
/* reg_mfsl_tach_max
* Tachometer maximum value (maximum RPM).
* Access: RW
*/
MLXSW_ITEM32(reg, mfsl, tach_max, 0x08, 0, 16);
static inline void mlxsw_reg_mfsl_pack(char *payload, u8 tacho,
u16 tach_min, u16 tach_max)
{
MLXSW_REG_ZERO(mfsl, payload);
mlxsw_reg_mfsl_tacho_set(payload, tacho);
mlxsw_reg_mfsl_tach_min_set(payload, tach_min);
mlxsw_reg_mfsl_tach_max_set(payload, tach_max);
}
static inline void mlxsw_reg_mfsl_unpack(char *payload, u8 tacho,
u16 *p_tach_min, u16 *p_tach_max)
{
if (p_tach_min)
*p_tach_min = mlxsw_reg_mfsl_tach_min_get(payload);
if (p_tach_max)
*p_tach_max = mlxsw_reg_mfsl_tach_max_get(payload);
}
/* MTCAP - Management Temperature Capabilities /* MTCAP - Management Temperature Capabilities
* ------------------------------------------- * -------------------------------------------
* This register exposes the capabilities of the device and * This register exposes the capabilities of the device and
...@@ -5228,6 +5276,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { ...@@ -5228,6 +5276,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(mfcr), MLXSW_REG(mfcr),
MLXSW_REG(mfsc), MLXSW_REG(mfsc),
MLXSW_REG(mfsm), MLXSW_REG(mfsm),
MLXSW_REG(mfsl),
MLXSW_REG(mtcap), MLXSW_REG(mtcap),
MLXSW_REG(mtmp), MLXSW_REG(mtmp),
MLXSW_REG(mpat), MLXSW_REG(mpat),
......
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