aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Pasternak <vadimp@mellanox.com>2018-07-26 18:40:57 -0400
committerDarren Hart (VMware) <dvhart@infradead.org>2018-08-01 20:41:31 -0400
commit0378123c580091b4c2972a6e4fcb3dcb4686667a (patch)
treeb15e143d2c794583944704933db161bce0950ddc
parent5788f77959110480486c441b912da5c2cc5fc4d2 (diff)
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>
-rw-r--r--drivers/platform/x86/mlx-platform.c144
1 files changed, 143 insertions, 1 deletions
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
index 3a227509c7ac..deea6a6339af 100644
--- a/drivers/platform/x86/mlx-platform.c
+++ b/drivers/platform/x86/mlx-platform.c
@@ -59,6 +59,7 @@
59#define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31 59#define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31
60#define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32 60#define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32
61#define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET 0x33 61#define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET 0x33
62#define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET 0x37
62#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a 63#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
63#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b 64#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
64#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40 65#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
@@ -73,9 +74,23 @@
73#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88 74#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
74#define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89 75#define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89
75#define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a 76#define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a
77#define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3
78#define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4
79#define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET 0xe5
80#define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET 0xe6
81#define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET 0xe7
82#define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET 0xe8
83#define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET 0xe9
84#define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET 0xea
85#define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET 0xeb
86#define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET 0xec
87#define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET 0xed
88#define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET 0xee
89#define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET 0xef
76#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100 90#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
77#define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb 91#define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb
78#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda 92#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda
93
79#define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL 94#define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL
80#define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \ 95#define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
81 MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \ 96 MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
@@ -131,6 +146,7 @@
131 * @pdev_hotplug - hotplug platform devices 146 * @pdev_hotplug - hotplug platform devices
132 * @pdev_led - led platform devices 147 * @pdev_led - led platform devices
133 * @pdev_io_regs - register access platform devices 148 * @pdev_io_regs - register access platform devices
149 * @pdev_fan - FAN platform devices
134 */ 150 */
135struct mlxplat_priv { 151struct mlxplat_priv {
136 struct platform_device *pdev_i2c; 152 struct platform_device *pdev_i2c;
@@ -138,6 +154,7 @@ struct mlxplat_priv {
138 struct platform_device *pdev_hotplug; 154 struct platform_device *pdev_hotplug;
139 struct platform_device *pdev_led; 155 struct platform_device *pdev_led;
140 struct platform_device *pdev_io_regs; 156 struct platform_device *pdev_io_regs;
157 struct platform_device *pdev_fan;
141}; 158};
142 159
143/* Regions for LPC I2C controller and LPC base register space */ 160/* 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 = {
929 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data), 946 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data),
930}; 947};
931 948
949/* Platform FAN default */
950static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
951 {
952 .label = "pwm1",
953 .reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
954 },
955 {
956 .label = "tacho1",
957 .reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
958 .mask = GENMASK(7, 0),
959 },
960 {
961 .label = "tacho2",
962 .reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
963 .mask = GENMASK(7, 0),
964 },
965 {
966 .label = "tacho3",
967 .reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
968 .mask = GENMASK(7, 0),
969 },
970 {
971 .label = "tacho4",
972 .reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
973 .mask = GENMASK(7, 0),
974 },
975 {
976 .label = "tacho5",
977 .reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
978 .mask = GENMASK(7, 0),
979 },
980 {
981 .label = "tacho6",
982 .reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
983 .mask = GENMASK(7, 0),
984 },
985 {
986 .label = "tacho7",
987 .reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
988 .mask = GENMASK(7, 0),
989 },
990 {
991 .label = "tacho8",
992 .reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
993 .mask = GENMASK(7, 0),
994 },
995 {
996 .label = "tacho9",
997 .reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
998 .mask = GENMASK(7, 0),
999 },
1000 {
1001 .label = "tacho10",
1002 .reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
1003 .mask = GENMASK(7, 0),
1004 },
1005 {
1006 .label = "tacho11",
1007 .reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
1008 .mask = GENMASK(7, 0),
1009 },
1010 {
1011 .label = "tacho12",
1012 .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
1013 .mask = GENMASK(7, 0),
1014 },
1015};
1016
1017static struct mlxreg_core_platform_data mlxplat_default_fan_data = {
1018 .data = mlxplat_mlxcpld_default_fan_data,
1019 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
1020};
1021
932static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg) 1022static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
933{ 1023{
934 switch (reg) { 1024 switch (reg) {
@@ -949,6 +1039,8 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
949 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET: 1039 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
950 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: 1040 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
951 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: 1041 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1042 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1043 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
952 return true; 1044 return true;
953 } 1045 }
954 return false; 1046 return false;
@@ -983,6 +1075,20 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
983 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET: 1075 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
984 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: 1076 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
985 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: 1077 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1078 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1079 case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
1080 case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
1081 case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
1082 case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
1083 case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
1084 case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
1085 case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
1086 case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
1087 case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
1088 case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
1089 case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
1090 case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
1091 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
986 return true; 1092 return true;
987 } 1093 }
988 return false; 1094 return false;
@@ -1015,6 +1121,20 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
1015 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET: 1121 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
1016 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: 1122 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
1017 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: 1123 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
1124 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
1125 case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
1126 case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
1127 case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
1128 case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
1129 case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
1130 case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
1131 case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
1132 case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
1133 case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
1134 case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
1135 case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
1136 case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
1137 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
1018 return true; 1138 return true;
1019 } 1139 }
1020 return false; 1140 return false;
@@ -1023,6 +1143,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
1023static const struct reg_default mlxplat_mlxcpld_regmap_default[] = { 1143static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
1024 { MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 }, 1144 { MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
1025 { MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 }, 1145 { MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
1146 { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
1026}; 1147};
1027 1148
1028struct mlxplat_mlxcpld_regmap_context { 1149struct mlxplat_mlxcpld_regmap_context {
@@ -1071,6 +1192,7 @@ static struct platform_device *mlxplat_dev;
1071static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug; 1192static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
1072static struct mlxreg_core_platform_data *mlxplat_led; 1193static struct mlxreg_core_platform_data *mlxplat_led;
1073static struct mlxreg_core_platform_data *mlxplat_regs_io; 1194static struct mlxreg_core_platform_data *mlxplat_regs_io;
1195static struct mlxreg_core_platform_data *mlxplat_fan;
1074 1196
1075static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi) 1197static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
1076{ 1198{
@@ -1155,6 +1277,7 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
1155 mlxplat_hotplug->deferred_nr = 1277 mlxplat_hotplug->deferred_nr =
1156 mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1]; 1278 mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
1157 mlxplat_led = &mlxplat_msn21xx_led_data; 1279 mlxplat_led = &mlxplat_msn21xx_led_data;
1280 mlxplat_fan = &mlxplat_default_fan_data;
1158 1281
1159 return 1; 1282 return 1;
1160}; 1283};
@@ -1410,14 +1533,31 @@ static int __init mlxplat_init(void)
1410 } 1533 }
1411 } 1534 }
1412 1535
1536 /* Add FAN driver. */
1537 if (mlxplat_fan) {
1538 mlxplat_fan->regmap = mlxplat_hotplug->regmap;
1539 priv->pdev_fan = platform_device_register_resndata(
1540 &mlxplat_dev->dev, "mlxreg-fan",
1541 PLATFORM_DEVID_NONE, NULL, 0,
1542 mlxplat_fan,
1543 sizeof(*mlxplat_fan));
1544 if (IS_ERR(priv->pdev_io_regs)) {
1545 err = PTR_ERR(priv->pdev_io_regs);
1546 goto fail_platform_io_regs_register;
1547 }
1548 }
1549
1413 /* Sync registers with hardware. */ 1550 /* Sync registers with hardware. */
1414 regcache_mark_dirty(mlxplat_hotplug->regmap); 1551 regcache_mark_dirty(mlxplat_hotplug->regmap);
1415 err = regcache_sync(mlxplat_hotplug->regmap); 1552 err = regcache_sync(mlxplat_hotplug->regmap);
1416 if (err) 1553 if (err)
1417 goto fail_platform_io_regs_register; 1554 goto fail_platform_fan_register;
1418 1555
1419 return 0; 1556 return 0;
1420 1557
1558fail_platform_fan_register:
1559 if (mlxplat_fan)
1560 platform_device_unregister(priv->pdev_fan);
1421fail_platform_io_regs_register: 1561fail_platform_io_regs_register:
1422 if (mlxplat_regs_io) 1562 if (mlxplat_regs_io)
1423 platform_device_unregister(priv->pdev_io_regs); 1563 platform_device_unregister(priv->pdev_io_regs);
@@ -1441,6 +1581,8 @@ static void __exit mlxplat_exit(void)
1441 struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev); 1581 struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
1442 int i; 1582 int i;
1443 1583
1584 if (priv->pdev_fan)
1585 platform_device_unregister(priv->pdev_fan);
1444 if (priv->pdev_io_regs) 1586 if (priv->pdev_io_regs)
1445 platform_device_unregister(priv->pdev_io_regs); 1587 platform_device_unregister(priv->pdev_io_regs);
1446 platform_device_unregister(priv->pdev_led); 1588 platform_device_unregister(priv->pdev_led);