platform/x86: mlx-platform: Add mlxreg-fan platform driver activation
Add mlxreg-fan platform driver activation. FAN driver uses the same regmap infrastructure as others Mellanox platform drivers. Specific registers description for default FAN platform data configuration are added to mlx-platform. There are the registers for tachometers reading, PWM control and FAN ownership control. The last one has a default value, which is set at initialization time through the regmap infrastructure, which is necessary for moving FAN control ownership from hardware to software. Signed-off-by: Vadim Pasternak <vadimp@mellanox.com> Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
This commit is contained in:
parent
5788f77959
commit
0378123c58
@ -59,6 +59,7 @@
|
|||||||
#define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31
|
#define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31
|
||||||
#define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32
|
#define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32
|
||||||
#define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET 0x33
|
#define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET 0x33
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET 0x37
|
||||||
#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
|
#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
|
||||||
#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
|
#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
|
||||||
#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
|
#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
|
||||||
@ -73,9 +74,23 @@
|
|||||||
#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
|
#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
|
||||||
#define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89
|
#define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89
|
||||||
#define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a
|
#define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET 0xe5
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET 0xe6
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET 0xe7
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET 0xe8
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET 0xe9
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET 0xea
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET 0xeb
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET 0xec
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET 0xed
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET 0xee
|
||||||
|
#define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET 0xef
|
||||||
#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
|
#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
|
||||||
#define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb
|
#define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb
|
||||||
#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda
|
#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda
|
||||||
|
|
||||||
#define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL
|
#define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL
|
||||||
#define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
|
#define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
|
||||||
MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
|
MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
|
||||||
@ -131,6 +146,7 @@
|
|||||||
* @pdev_hotplug - hotplug platform devices
|
* @pdev_hotplug - hotplug platform devices
|
||||||
* @pdev_led - led platform devices
|
* @pdev_led - led platform devices
|
||||||
* @pdev_io_regs - register access platform devices
|
* @pdev_io_regs - register access platform devices
|
||||||
|
* @pdev_fan - FAN platform devices
|
||||||
*/
|
*/
|
||||||
struct mlxplat_priv {
|
struct mlxplat_priv {
|
||||||
struct platform_device *pdev_i2c;
|
struct platform_device *pdev_i2c;
|
||||||
@ -138,6 +154,7 @@ struct mlxplat_priv {
|
|||||||
struct platform_device *pdev_hotplug;
|
struct platform_device *pdev_hotplug;
|
||||||
struct platform_device *pdev_led;
|
struct platform_device *pdev_led;
|
||||||
struct platform_device *pdev_io_regs;
|
struct platform_device *pdev_io_regs;
|
||||||
|
struct platform_device *pdev_fan;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Regions for LPC I2C controller and LPC base register space */
|
/* Regions for LPC I2C controller and LPC base register space */
|
||||||
@ -929,6 +946,79 @@ static struct mlxreg_core_platform_data mlxplat_default_regs_io_data = {
|
|||||||
.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data),
|
.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Platform FAN default */
|
||||||
|
static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
|
||||||
|
{
|
||||||
|
.label = "pwm1",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho1",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho2",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho3",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho4",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho5",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho6",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho7",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho8",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho9",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho10",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho11",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.label = "tacho12",
|
||||||
|
.reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
|
||||||
|
.mask = GENMASK(7, 0),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mlxreg_core_platform_data mlxplat_default_fan_data = {
|
||||||
|
.data = mlxplat_mlxcpld_default_fan_data,
|
||||||
|
.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
|
||||||
|
};
|
||||||
|
|
||||||
static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
|
static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
|
||||||
{
|
{
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
@ -949,6 +1039,8 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
|
|||||||
case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
|
||||||
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
||||||
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -983,6 +1075,20 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
|
|||||||
case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
|
||||||
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
||||||
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1015,6 +1121,20 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
|
|||||||
case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
|
||||||
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
||||||
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
|
||||||
|
case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1023,6 +1143,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
|
|||||||
static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
|
static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
|
||||||
{ MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
|
{ MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
|
||||||
{ MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
|
{ MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
|
||||||
|
{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlxplat_mlxcpld_regmap_context {
|
struct mlxplat_mlxcpld_regmap_context {
|
||||||
@ -1071,6 +1192,7 @@ static struct platform_device *mlxplat_dev;
|
|||||||
static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
|
static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
|
||||||
static struct mlxreg_core_platform_data *mlxplat_led;
|
static struct mlxreg_core_platform_data *mlxplat_led;
|
||||||
static struct mlxreg_core_platform_data *mlxplat_regs_io;
|
static struct mlxreg_core_platform_data *mlxplat_regs_io;
|
||||||
|
static struct mlxreg_core_platform_data *mlxplat_fan;
|
||||||
|
|
||||||
static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
|
static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
|
||||||
{
|
{
|
||||||
@ -1155,6 +1277,7 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
|
|||||||
mlxplat_hotplug->deferred_nr =
|
mlxplat_hotplug->deferred_nr =
|
||||||
mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
||||||
mlxplat_led = &mlxplat_msn21xx_led_data;
|
mlxplat_led = &mlxplat_msn21xx_led_data;
|
||||||
|
mlxplat_fan = &mlxplat_default_fan_data;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
@ -1410,14 +1533,31 @@ static int __init mlxplat_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add FAN driver. */
|
||||||
|
if (mlxplat_fan) {
|
||||||
|
mlxplat_fan->regmap = mlxplat_hotplug->regmap;
|
||||||
|
priv->pdev_fan = platform_device_register_resndata(
|
||||||
|
&mlxplat_dev->dev, "mlxreg-fan",
|
||||||
|
PLATFORM_DEVID_NONE, NULL, 0,
|
||||||
|
mlxplat_fan,
|
||||||
|
sizeof(*mlxplat_fan));
|
||||||
|
if (IS_ERR(priv->pdev_io_regs)) {
|
||||||
|
err = PTR_ERR(priv->pdev_io_regs);
|
||||||
|
goto fail_platform_io_regs_register;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Sync registers with hardware. */
|
/* Sync registers with hardware. */
|
||||||
regcache_mark_dirty(mlxplat_hotplug->regmap);
|
regcache_mark_dirty(mlxplat_hotplug->regmap);
|
||||||
err = regcache_sync(mlxplat_hotplug->regmap);
|
err = regcache_sync(mlxplat_hotplug->regmap);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail_platform_io_regs_register;
|
goto fail_platform_fan_register;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail_platform_fan_register:
|
||||||
|
if (mlxplat_fan)
|
||||||
|
platform_device_unregister(priv->pdev_fan);
|
||||||
fail_platform_io_regs_register:
|
fail_platform_io_regs_register:
|
||||||
if (mlxplat_regs_io)
|
if (mlxplat_regs_io)
|
||||||
platform_device_unregister(priv->pdev_io_regs);
|
platform_device_unregister(priv->pdev_io_regs);
|
||||||
@ -1441,6 +1581,8 @@ static void __exit mlxplat_exit(void)
|
|||||||
struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
|
struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (priv->pdev_fan)
|
||||||
|
platform_device_unregister(priv->pdev_fan);
|
||||||
if (priv->pdev_io_regs)
|
if (priv->pdev_io_regs)
|
||||||
platform_device_unregister(priv->pdev_io_regs);
|
platform_device_unregister(priv->pdev_io_regs);
|
||||||
platform_device_unregister(priv->pdev_led);
|
platform_device_unregister(priv->pdev_led);
|
||||||
|
Loading…
Reference in New Issue
Block a user