mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
					
				
					 1 changed files with 143 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -59,6 +59,7 @@
 | 
			
		|||
#define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET		0x31
 | 
			
		||||
#define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET		0x32
 | 
			
		||||
#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_MASK_OFFSET	0x3b
 | 
			
		||||
#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_EVENT_OFFSET	0x89
 | 
			
		||||
#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_I2C_CH1_OFF		0xdb
 | 
			
		||||
#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF		0xda
 | 
			
		||||
 | 
			
		||||
#define MLXPLAT_CPLD_LPC_PIO_OFFSET		0x10000UL
 | 
			
		||||
#define MLXPLAT_CPLD_LPC_REG1	((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
 | 
			
		||||
				  MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +146,7 @@
 | 
			
		|||
 * @pdev_hotplug - hotplug platform devices
 | 
			
		||||
 * @pdev_led - led platform devices
 | 
			
		||||
 * @pdev_io_regs - register access platform devices
 | 
			
		||||
 * @pdev_fan - FAN platform devices
 | 
			
		||||
 */
 | 
			
		||||
struct mlxplat_priv {
 | 
			
		||||
	struct platform_device *pdev_i2c;
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +154,7 @@ struct mlxplat_priv {
 | 
			
		|||
	struct platform_device *pdev_hotplug;
 | 
			
		||||
	struct platform_device *pdev_led;
 | 
			
		||||
	struct platform_device *pdev_io_regs;
 | 
			
		||||
	struct platform_device *pdev_fan;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 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),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 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)
 | 
			
		||||
{
 | 
			
		||||
	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_FAN_EVENT_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 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_EVENT_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 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_EVENT_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 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[] = {
 | 
			
		||||
	{ MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
 | 
			
		||||
	{ MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
 | 
			
		||||
	{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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_platform_data *mlxplat_led;
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1155,6 +1277,7 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
 | 
			
		|||
	mlxplat_hotplug->deferred_nr =
 | 
			
		||||
		mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
 | 
			
		||||
	mlxplat_led = &mlxplat_msn21xx_led_data;
 | 
			
		||||
	mlxplat_fan = &mlxplat_default_fan_data;
 | 
			
		||||
 | 
			
		||||
	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. */
 | 
			
		||||
	regcache_mark_dirty(mlxplat_hotplug->regmap);
 | 
			
		||||
	err = regcache_sync(mlxplat_hotplug->regmap);
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto fail_platform_io_regs_register;
 | 
			
		||||
		goto fail_platform_fan_register;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
fail_platform_fan_register:
 | 
			
		||||
	if (mlxplat_fan)
 | 
			
		||||
		platform_device_unregister(priv->pdev_fan);
 | 
			
		||||
fail_platform_io_regs_register:
 | 
			
		||||
	if (mlxplat_regs_io)
 | 
			
		||||
		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);
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (priv->pdev_fan)
 | 
			
		||||
		platform_device_unregister(priv->pdev_fan);
 | 
			
		||||
	if (priv->pdev_io_regs)
 | 
			
		||||
		platform_device_unregister(priv->pdev_io_regs);
 | 
			
		||||
	platform_device_unregister(priv->pdev_led);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue