diff options
author | Vadim Pasternak <vadimp@mellanox.com> | 2018-07-26 18:40:57 -0400 |
---|---|---|
committer | Darren Hart (VMware) <dvhart@infradead.org> | 2018-08-01 20:41:31 -0400 |
commit | 0378123c580091b4c2972a6e4fcb3dcb4686667a (patch) | |
tree | b15e143d2c794583944704933db161bce0950ddc | |
parent | 5788f77959110480486c441b912da5c2cc5fc4d2 (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.c | 144 |
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 | */ |
135 | struct mlxplat_priv { | 151 | struct 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 */ | ||
950 | static 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 | |||
1017 | static 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 | |||
932 | static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg) | 1022 | static 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) | |||
1023 | static const struct reg_default mlxplat_mlxcpld_regmap_default[] = { | 1143 | static 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 | ||
1028 | struct mlxplat_mlxcpld_regmap_context { | 1149 | struct mlxplat_mlxcpld_regmap_context { |
@@ -1071,6 +1192,7 @@ static struct platform_device *mlxplat_dev; | |||
1071 | static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug; | 1192 | static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug; |
1072 | static struct mlxreg_core_platform_data *mlxplat_led; | 1193 | static struct mlxreg_core_platform_data *mlxplat_led; |
1073 | static struct mlxreg_core_platform_data *mlxplat_regs_io; | 1194 | static struct mlxreg_core_platform_data *mlxplat_regs_io; |
1195 | static struct mlxreg_core_platform_data *mlxplat_fan; | ||
1074 | 1196 | ||
1075 | static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi) | 1197 | static 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 | ||
1558 | fail_platform_fan_register: | ||
1559 | if (mlxplat_fan) | ||
1560 | platform_device_unregister(priv->pdev_fan); | ||
1421 | fail_platform_io_regs_register: | 1561 | fail_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); |