1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /* 3 * Mellanox platform driver 4 * 5 * Copyright (C) 2016-2018 Mellanox Technologies 6 * Copyright (C) 2016-2018 Vadim Pasternak <vadimp@mellanox.com> 7 */ 8 9 #include <linux/device.h> 10 #include <linux/dmi.h> 11 #include <linux/i2c.h> 12 #include <linux/i2c-mux.h> 13 #include <linux/io.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/platform_data/i2c-mux-reg.h> 17 #include <linux/platform_data/mlxreg.h> 18 #include <linux/regmap.h> 19 20 #define MLX_PLAT_DEVICE_NAME "mlxplat" 21 22 /* LPC bus IO offsets */ 23 #define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000 24 #define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500 25 #define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET 0x00 26 #define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET 0x01 27 #define MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET 0x02 28 #define MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET 0x03 29 #define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET 0x1d 30 #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET 0x1e 31 #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET 0x1f 32 #define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET 0x20 33 #define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET 0x21 34 #define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET 0x22 35 #define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET 0x23 36 #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24 37 #define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION 0x2a 38 #define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET 0x30 39 #define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31 40 #define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32 41 #define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET 0x33 42 #define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET 0x37 43 #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a 44 #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b 45 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40 46 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET 0x41 47 #define MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET 0x42 48 #define MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET 0x43 49 #define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50 50 #define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET 0x51 51 #define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET 0x52 52 #define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET 0x58 53 #define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET 0x59 54 #define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET 0x5a 55 #define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET 0x64 56 #define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET 0x65 57 #define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET 0x66 58 #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88 59 #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89 60 #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a 61 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET 0xc7 62 #define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET 0xc8 63 #define MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET 0xc9 64 #define MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET 0xcb 65 #define MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET 0xcd 66 #define MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET 0xce 67 #define MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET 0xcf 68 #define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET 0xd1 69 #define MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET 0xd2 70 #define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET 0xd3 71 #define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3 72 #define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4 73 #define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET 0xe5 74 #define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET 0xe6 75 #define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET 0xe7 76 #define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET 0xe8 77 #define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET 0xe9 78 #define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET 0xeb 79 #define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET 0xec 80 #define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET 0xed 81 #define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET 0xee 82 #define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET 0xef 83 #define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET 0xf0 84 #define MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET 0xf5 85 #define MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET 0xf6 86 #define MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET 0xf7 87 #define MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET 0xf8 88 #define MLXPLAT_CPLD_LPC_IO_RANGE 0x100 89 #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb 90 #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda 91 92 #define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL 93 #define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \ 94 MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \ 95 MLXPLAT_CPLD_LPC_PIO_OFFSET) 96 #define MLXPLAT_CPLD_LPC_REG2 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \ 97 MLXPLAT_CPLD_LPC_I2C_CH2_OFF) | \ 98 MLXPLAT_CPLD_LPC_PIO_OFFSET) 99 100 /* Masks for aggregation, psu, pwr and fan event in CPLD related registers. */ 101 #define MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF 0x04 102 #define MLXPLAT_CPLD_AGGR_PSU_MASK_DEF 0x08 103 #define MLXPLAT_CPLD_AGGR_PWR_MASK_DEF 0x08 104 #define MLXPLAT_CPLD_AGGR_FAN_MASK_DEF 0x40 105 #define MLXPLAT_CPLD_AGGR_MASK_DEF (MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \ 106 MLXPLAT_CPLD_AGGR_PSU_MASK_DEF | \ 107 MLXPLAT_CPLD_AGGR_FAN_MASK_DEF) 108 #define MLXPLAT_CPLD_AGGR_ASIC_MASK_NG 0x01 109 #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF 0x04 110 #define MLXPLAT_CPLD_AGGR_MASK_COMEX BIT(0) 111 #define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW 0xc1 112 #define MLXPLAT_CPLD_LOW_AGGR_MASK_I2C BIT(6) 113 #define MLXPLAT_CPLD_PSU_MASK GENMASK(1, 0) 114 #define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0) 115 #define MLXPLAT_CPLD_FAN_MASK GENMASK(3, 0) 116 #define MLXPLAT_CPLD_ASIC_MASK GENMASK(1, 0) 117 #define MLXPLAT_CPLD_FAN_NG_MASK GENMASK(5, 0) 118 #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK GENMASK(7, 4) 119 #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK GENMASK(3, 0) 120 121 /* Default I2C parent bus number */ 122 #define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR 1 123 124 /* Maximum number of possible physical buses equipped on system */ 125 #define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM 16 126 127 /* Number of channels in group */ 128 #define MLXPLAT_CPLD_GRP_CHNL_NUM 8 129 130 /* Start channel numbers */ 131 #define MLXPLAT_CPLD_CH1 2 132 #define MLXPLAT_CPLD_CH2 10 133 134 /* Number of LPC attached MUX platform devices */ 135 #define MLXPLAT_CPLD_LPC_MUX_DEVS 2 136 137 /* Hotplug devices adapter numbers */ 138 #define MLXPLAT_CPLD_NR_NONE -1 139 #define MLXPLAT_CPLD_PSU_DEFAULT_NR 10 140 #define MLXPLAT_CPLD_PSU_MSNXXXX_NR 4 141 #define MLXPLAT_CPLD_FAN1_DEFAULT_NR 11 142 #define MLXPLAT_CPLD_FAN2_DEFAULT_NR 12 143 #define MLXPLAT_CPLD_FAN3_DEFAULT_NR 13 144 #define MLXPLAT_CPLD_FAN4_DEFAULT_NR 14 145 146 /* Masks and default values for watchdogs */ 147 #define MLXPLAT_CPLD_WD1_CLEAR_MASK GENMASK(7, 1) 148 #define MLXPLAT_CPLD_WD2_CLEAR_MASK (GENMASK(7, 0) & ~BIT(1)) 149 150 #define MLXPLAT_CPLD_WD_TYPE1_TO_MASK GENMASK(7, 4) 151 #define MLXPLAT_CPLD_WD_TYPE2_TO_MASK 0 152 #define MLXPLAT_CPLD_WD_RESET_ACT_MASK GENMASK(7, 1) 153 #define MLXPLAT_CPLD_WD_FAN_ACT_MASK (GENMASK(7, 0) & ~BIT(4)) 154 #define MLXPLAT_CPLD_WD_COUNT_ACT_MASK (GENMASK(7, 0) & ~BIT(7)) 155 #define MLXPLAT_CPLD_WD_DFLT_TIMEOUT 30 156 #define MLXPLAT_CPLD_WD_MAX_DEVS 2 157 158 /* mlxplat_priv - platform private data 159 * @pdev_i2c - i2c controller platform device 160 * @pdev_mux - array of mux platform devices 161 * @pdev_hotplug - hotplug platform devices 162 * @pdev_led - led platform devices 163 * @pdev_io_regs - register access platform devices 164 * @pdev_fan - FAN platform devices 165 * @pdev_wd - array of watchdog platform devices 166 * @regmap: device register map 167 */ 168 struct mlxplat_priv { 169 struct platform_device *pdev_i2c; 170 struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS]; 171 struct platform_device *pdev_hotplug; 172 struct platform_device *pdev_led; 173 struct platform_device *pdev_io_regs; 174 struct platform_device *pdev_fan; 175 struct platform_device *pdev_wd[MLXPLAT_CPLD_WD_MAX_DEVS]; 176 void *regmap; 177 }; 178 179 /* Regions for LPC I2C controller and LPC base register space */ 180 static const struct resource mlxplat_lpc_resources[] = { 181 [0] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_I2C_BASE_ADRR, 182 MLXPLAT_CPLD_LPC_IO_RANGE, 183 "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO), 184 [1] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_REG_BASE_ADRR, 185 MLXPLAT_CPLD_LPC_IO_RANGE, 186 "mlxplat_cpld_lpc_regs", 187 IORESOURCE_IO), 188 }; 189 190 /* Platform next generation systems i2c data */ 191 static struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_i2c_ng_data = { 192 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET, 193 .mask = MLXPLAT_CPLD_AGGR_MASK_COMEX, 194 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET, 195 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_I2C, 196 }; 197 198 /* Platform default channels */ 199 static const int mlxplat_default_channels[][MLXPLAT_CPLD_GRP_CHNL_NUM] = { 200 { 201 MLXPLAT_CPLD_CH1, MLXPLAT_CPLD_CH1 + 1, MLXPLAT_CPLD_CH1 + 2, 202 MLXPLAT_CPLD_CH1 + 3, MLXPLAT_CPLD_CH1 + 4, MLXPLAT_CPLD_CH1 + 203 5, MLXPLAT_CPLD_CH1 + 6, MLXPLAT_CPLD_CH1 + 7 204 }, 205 { 206 MLXPLAT_CPLD_CH2, MLXPLAT_CPLD_CH2 + 1, MLXPLAT_CPLD_CH2 + 2, 207 MLXPLAT_CPLD_CH2 + 3, MLXPLAT_CPLD_CH2 + 4, MLXPLAT_CPLD_CH2 + 208 5, MLXPLAT_CPLD_CH2 + 6, MLXPLAT_CPLD_CH2 + 7 209 }, 210 }; 211 212 /* Platform channels for MSN21xx system family */ 213 static const int mlxplat_msn21xx_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 214 215 /* Platform mux data */ 216 static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = { 217 { 218 .parent = 1, 219 .base_nr = MLXPLAT_CPLD_CH1, 220 .write_only = 1, 221 .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1, 222 .reg_size = 1, 223 .idle_in_use = 1, 224 }, 225 { 226 .parent = 1, 227 .base_nr = MLXPLAT_CPLD_CH2, 228 .write_only = 1, 229 .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2, 230 .reg_size = 1, 231 .idle_in_use = 1, 232 }, 233 234 }; 235 236 /* Platform hotplug devices */ 237 static struct i2c_board_info mlxplat_mlxcpld_psu[] = { 238 { 239 I2C_BOARD_INFO("24c02", 0x51), 240 }, 241 { 242 I2C_BOARD_INFO("24c02", 0x50), 243 }, 244 }; 245 246 static struct i2c_board_info mlxplat_mlxcpld_ng_psu[] = { 247 { 248 I2C_BOARD_INFO("24c32", 0x51), 249 }, 250 { 251 I2C_BOARD_INFO("24c32", 0x50), 252 }, 253 }; 254 255 static struct i2c_board_info mlxplat_mlxcpld_pwr[] = { 256 { 257 I2C_BOARD_INFO("dps460", 0x59), 258 }, 259 { 260 I2C_BOARD_INFO("dps460", 0x58), 261 }, 262 }; 263 264 static struct i2c_board_info mlxplat_mlxcpld_fan[] = { 265 { 266 I2C_BOARD_INFO("24c32", 0x50), 267 }, 268 { 269 I2C_BOARD_INFO("24c32", 0x50), 270 }, 271 { 272 I2C_BOARD_INFO("24c32", 0x50), 273 }, 274 { 275 I2C_BOARD_INFO("24c32", 0x50), 276 }, 277 }; 278 279 /* Platform hotplug default data */ 280 static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data[] = { 281 { 282 .label = "psu1", 283 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 284 .mask = BIT(0), 285 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0], 286 .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR, 287 }, 288 { 289 .label = "psu2", 290 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 291 .mask = BIT(1), 292 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1], 293 .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR, 294 }, 295 }; 296 297 static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = { 298 { 299 .label = "pwr1", 300 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 301 .mask = BIT(0), 302 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0], 303 .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR, 304 }, 305 { 306 .label = "pwr2", 307 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 308 .mask = BIT(1), 309 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1], 310 .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR, 311 }, 312 }; 313 314 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = { 315 { 316 .label = "fan1", 317 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 318 .mask = BIT(0), 319 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[0], 320 .hpdev.nr = MLXPLAT_CPLD_FAN1_DEFAULT_NR, 321 }, 322 { 323 .label = "fan2", 324 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 325 .mask = BIT(1), 326 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[1], 327 .hpdev.nr = MLXPLAT_CPLD_FAN2_DEFAULT_NR, 328 }, 329 { 330 .label = "fan3", 331 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 332 .mask = BIT(2), 333 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[2], 334 .hpdev.nr = MLXPLAT_CPLD_FAN3_DEFAULT_NR, 335 }, 336 { 337 .label = "fan4", 338 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 339 .mask = BIT(3), 340 .hpdev.brdinfo = &mlxplat_mlxcpld_fan[3], 341 .hpdev.nr = MLXPLAT_CPLD_FAN4_DEFAULT_NR, 342 }, 343 }; 344 345 static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data[] = { 346 { 347 .label = "asic1", 348 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 349 .mask = MLXPLAT_CPLD_ASIC_MASK, 350 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 351 }, 352 }; 353 354 static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = { 355 { 356 .data = mlxplat_mlxcpld_default_psu_items_data, 357 .aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF, 358 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 359 .mask = MLXPLAT_CPLD_PSU_MASK, 360 .count = ARRAY_SIZE(mlxplat_mlxcpld_psu), 361 .inversed = 1, 362 .health = false, 363 }, 364 { 365 .data = mlxplat_mlxcpld_default_pwr_items_data, 366 .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF, 367 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 368 .mask = MLXPLAT_CPLD_PWR_MASK, 369 .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr), 370 .inversed = 0, 371 .health = false, 372 }, 373 { 374 .data = mlxplat_mlxcpld_default_fan_items_data, 375 .aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF, 376 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 377 .mask = MLXPLAT_CPLD_FAN_MASK, 378 .count = ARRAY_SIZE(mlxplat_mlxcpld_fan), 379 .inversed = 1, 380 .health = false, 381 }, 382 { 383 .data = mlxplat_mlxcpld_default_asic_items_data, 384 .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF, 385 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 386 .mask = MLXPLAT_CPLD_ASIC_MASK, 387 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data), 388 .inversed = 0, 389 .health = true, 390 }, 391 }; 392 393 static 394 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = { 395 .items = mlxplat_mlxcpld_default_items, 396 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items), 397 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET, 398 .mask = MLXPLAT_CPLD_AGGR_MASK_DEF, 399 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET, 400 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW, 401 }; 402 403 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data[] = { 404 { 405 .label = "pwr1", 406 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 407 .mask = BIT(0), 408 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 409 }, 410 { 411 .label = "pwr2", 412 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 413 .mask = BIT(1), 414 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 415 }, 416 }; 417 418 /* Platform hotplug MSN21xx system family data */ 419 static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = { 420 { 421 .data = mlxplat_mlxcpld_msn21xx_pwr_items_data, 422 .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF, 423 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 424 .mask = MLXPLAT_CPLD_PWR_MASK, 425 .count = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_pwr_items_data), 426 .inversed = 0, 427 .health = false, 428 }, 429 { 430 .data = mlxplat_mlxcpld_default_asic_items_data, 431 .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF, 432 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 433 .mask = MLXPLAT_CPLD_ASIC_MASK, 434 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data), 435 .inversed = 0, 436 .health = true, 437 }, 438 }; 439 440 static 441 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = { 442 .items = mlxplat_mlxcpld_msn21xx_items, 443 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items), 444 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET, 445 .mask = MLXPLAT_CPLD_AGGR_MASK_DEF, 446 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET, 447 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW, 448 }; 449 450 /* Platform hotplug msn274x system family data */ 451 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_psu_items_data[] = { 452 { 453 .label = "psu1", 454 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 455 .mask = BIT(0), 456 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0], 457 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, 458 }, 459 { 460 .label = "psu2", 461 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 462 .mask = BIT(1), 463 .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1], 464 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, 465 }, 466 }; 467 468 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_pwr_items_data[] = { 469 { 470 .label = "pwr1", 471 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 472 .mask = BIT(0), 473 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0], 474 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, 475 }, 476 { 477 .label = "pwr2", 478 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 479 .mask = BIT(1), 480 .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1], 481 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, 482 }, 483 }; 484 485 static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_fan_items_data[] = { 486 { 487 .label = "fan1", 488 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 489 .mask = BIT(0), 490 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 491 }, 492 { 493 .label = "fan2", 494 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 495 .mask = BIT(1), 496 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 497 }, 498 { 499 .label = "fan3", 500 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 501 .mask = BIT(2), 502 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 503 }, 504 { 505 .label = "fan4", 506 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 507 .mask = BIT(3), 508 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 509 }, 510 }; 511 512 static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items[] = { 513 { 514 .data = mlxplat_mlxcpld_msn274x_psu_items_data, 515 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 516 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 517 .mask = MLXPLAT_CPLD_PSU_MASK, 518 .count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_psu_items_data), 519 .inversed = 1, 520 .health = false, 521 }, 522 { 523 .data = mlxplat_mlxcpld_default_ng_pwr_items_data, 524 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 525 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 526 .mask = MLXPLAT_CPLD_PWR_MASK, 527 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data), 528 .inversed = 0, 529 .health = false, 530 }, 531 { 532 .data = mlxplat_mlxcpld_msn274x_fan_items_data, 533 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 534 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 535 .mask = MLXPLAT_CPLD_FAN_MASK, 536 .count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_fan_items_data), 537 .inversed = 1, 538 .health = false, 539 }, 540 { 541 .data = mlxplat_mlxcpld_default_asic_items_data, 542 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 543 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 544 .mask = MLXPLAT_CPLD_ASIC_MASK, 545 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data), 546 .inversed = 0, 547 .health = true, 548 }, 549 }; 550 551 static 552 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn274x_data = { 553 .items = mlxplat_mlxcpld_msn274x_items, 554 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items), 555 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET, 556 .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 557 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET, 558 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW, 559 }; 560 561 /* Platform hotplug MSN201x system family data */ 562 static struct mlxreg_core_data mlxplat_mlxcpld_msn201x_pwr_items_data[] = { 563 { 564 .label = "pwr1", 565 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 566 .mask = BIT(0), 567 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 568 }, 569 { 570 .label = "pwr2", 571 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 572 .mask = BIT(1), 573 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 574 }, 575 }; 576 577 static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = { 578 { 579 .data = mlxplat_mlxcpld_msn201x_pwr_items_data, 580 .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF, 581 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 582 .mask = MLXPLAT_CPLD_PWR_MASK, 583 .count = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_pwr_items_data), 584 .inversed = 0, 585 .health = false, 586 }, 587 { 588 .data = mlxplat_mlxcpld_default_asic_items_data, 589 .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF, 590 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 591 .mask = MLXPLAT_CPLD_ASIC_MASK, 592 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data), 593 .inversed = 0, 594 .health = true, 595 }, 596 }; 597 598 static 599 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = { 600 .items = mlxplat_mlxcpld_msn201x_items, 601 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items), 602 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET, 603 .mask = MLXPLAT_CPLD_AGGR_MASK_DEF, 604 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET, 605 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW, 606 }; 607 608 /* Platform hotplug next generation system family data */ 609 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_psu_items_data[] = { 610 { 611 .label = "psu1", 612 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 613 .mask = BIT(0), 614 .hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[0], 615 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, 616 }, 617 { 618 .label = "psu2", 619 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 620 .mask = BIT(1), 621 .hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[1], 622 .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, 623 }, 624 }; 625 626 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data[] = { 627 { 628 .label = "fan1", 629 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 630 .mask = BIT(0), 631 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 632 .bit = BIT(0), 633 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 634 }, 635 { 636 .label = "fan2", 637 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 638 .mask = BIT(1), 639 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 640 .bit = BIT(1), 641 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 642 }, 643 { 644 .label = "fan3", 645 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 646 .mask = BIT(2), 647 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 648 .bit = BIT(2), 649 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 650 }, 651 { 652 .label = "fan4", 653 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 654 .mask = BIT(3), 655 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 656 .bit = BIT(3), 657 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 658 }, 659 { 660 .label = "fan5", 661 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 662 .mask = BIT(4), 663 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 664 .bit = BIT(4), 665 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 666 }, 667 { 668 .label = "fan6", 669 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 670 .mask = BIT(5), 671 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 672 .bit = BIT(5), 673 .hpdev.nr = MLXPLAT_CPLD_NR_NONE, 674 }, 675 }; 676 677 static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items[] = { 678 { 679 .data = mlxplat_mlxcpld_default_ng_psu_items_data, 680 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 681 .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, 682 .mask = MLXPLAT_CPLD_PSU_MASK, 683 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_psu_items_data), 684 .inversed = 1, 685 .health = false, 686 }, 687 { 688 .data = mlxplat_mlxcpld_default_ng_pwr_items_data, 689 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 690 .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, 691 .mask = MLXPLAT_CPLD_PWR_MASK, 692 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data), 693 .inversed = 0, 694 .health = false, 695 }, 696 { 697 .data = mlxplat_mlxcpld_default_ng_fan_items_data, 698 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 699 .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, 700 .mask = MLXPLAT_CPLD_FAN_NG_MASK, 701 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data), 702 .inversed = 1, 703 .health = false, 704 }, 705 { 706 .data = mlxplat_mlxcpld_default_asic_items_data, 707 .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF, 708 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 709 .mask = MLXPLAT_CPLD_ASIC_MASK, 710 .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data), 711 .inversed = 0, 712 .health = true, 713 }, 714 }; 715 716 static 717 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = { 718 .items = mlxplat_mlxcpld_default_ng_items, 719 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items), 720 .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET, 721 .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX, 722 .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET, 723 .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW, 724 }; 725 726 /* Platform led default data */ 727 static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = { 728 { 729 .label = "status:green", 730 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 731 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 732 }, 733 { 734 .label = "status:red", 735 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 736 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK 737 }, 738 { 739 .label = "psu:green", 740 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 741 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 742 }, 743 { 744 .label = "psu:red", 745 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 746 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 747 }, 748 { 749 .label = "fan1:green", 750 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 751 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 752 }, 753 { 754 .label = "fan1:red", 755 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 756 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 757 }, 758 { 759 .label = "fan2:green", 760 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 761 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 762 }, 763 { 764 .label = "fan2:red", 765 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 766 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 767 }, 768 { 769 .label = "fan3:green", 770 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, 771 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 772 }, 773 { 774 .label = "fan3:red", 775 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, 776 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 777 }, 778 { 779 .label = "fan4:green", 780 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, 781 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 782 }, 783 { 784 .label = "fan4:red", 785 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, 786 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 787 }, 788 }; 789 790 static struct mlxreg_core_platform_data mlxplat_default_led_data = { 791 .data = mlxplat_mlxcpld_default_led_data, 792 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_data), 793 }; 794 795 /* Platform led MSN21xx system family data */ 796 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data[] = { 797 { 798 .label = "status:green", 799 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 800 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 801 }, 802 { 803 .label = "status:red", 804 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 805 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK 806 }, 807 { 808 .label = "fan:green", 809 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 810 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 811 }, 812 { 813 .label = "fan:red", 814 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 815 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 816 }, 817 { 818 .label = "psu1:green", 819 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, 820 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 821 }, 822 { 823 .label = "psu1:red", 824 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, 825 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 826 }, 827 { 828 .label = "psu2:green", 829 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, 830 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 831 }, 832 { 833 .label = "psu2:red", 834 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, 835 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 836 }, 837 { 838 .label = "uid:blue", 839 .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET, 840 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 841 }, 842 }; 843 844 static struct mlxreg_core_platform_data mlxplat_msn21xx_led_data = { 845 .data = mlxplat_mlxcpld_msn21xx_led_data, 846 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_led_data), 847 }; 848 849 /* Platform led for default data for 200GbE systems */ 850 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = { 851 { 852 .label = "status:green", 853 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 854 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 855 }, 856 { 857 .label = "status:orange", 858 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 859 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK 860 }, 861 { 862 .label = "psu:green", 863 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 864 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 865 }, 866 { 867 .label = "psu:orange", 868 .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET, 869 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 870 }, 871 { 872 .label = "fan1:green", 873 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 874 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 875 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 876 .bit = BIT(0), 877 }, 878 { 879 .label = "fan1:orange", 880 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 881 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 882 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 883 .bit = BIT(0), 884 }, 885 { 886 .label = "fan2:green", 887 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 888 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 889 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 890 .bit = BIT(1), 891 }, 892 { 893 .label = "fan2:orange", 894 .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, 895 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 896 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 897 .bit = BIT(1), 898 }, 899 { 900 .label = "fan3:green", 901 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, 902 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 903 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 904 .bit = BIT(2), 905 }, 906 { 907 .label = "fan3:orange", 908 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, 909 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 910 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 911 .bit = BIT(2), 912 }, 913 { 914 .label = "fan4:green", 915 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, 916 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 917 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 918 .bit = BIT(3), 919 }, 920 { 921 .label = "fan4:orange", 922 .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, 923 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 924 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 925 .bit = BIT(3), 926 }, 927 { 928 .label = "fan5:green", 929 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, 930 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 931 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 932 .bit = BIT(4), 933 }, 934 { 935 .label = "fan5:orange", 936 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, 937 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 938 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 939 .bit = BIT(4), 940 }, 941 { 942 .label = "fan6:green", 943 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, 944 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 945 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 946 .bit = BIT(5), 947 }, 948 { 949 .label = "fan6:orange", 950 .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, 951 .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, 952 .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET, 953 .bit = BIT(5), 954 }, 955 { 956 .label = "uid:blue", 957 .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET, 958 .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, 959 }, 960 }; 961 962 static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = { 963 .data = mlxplat_mlxcpld_default_ng_led_data, 964 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data), 965 }; 966 967 /* Platform register access default */ 968 static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = { 969 { 970 .label = "cpld1_version", 971 .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET, 972 .bit = GENMASK(7, 0), 973 .mode = 0444, 974 }, 975 { 976 .label = "cpld2_version", 977 .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET, 978 .bit = GENMASK(7, 0), 979 .mode = 0444, 980 }, 981 { 982 .label = "reset_long_pb", 983 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 984 .mask = GENMASK(7, 0) & ~BIT(0), 985 .mode = 0444, 986 }, 987 { 988 .label = "reset_short_pb", 989 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 990 .mask = GENMASK(7, 0) & ~BIT(1), 991 .mode = 0444, 992 }, 993 { 994 .label = "reset_aux_pwr_or_ref", 995 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 996 .mask = GENMASK(7, 0) & ~BIT(2), 997 .mode = 0444, 998 }, 999 { 1000 .label = "reset_main_pwr_fail", 1001 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1002 .mask = GENMASK(7, 0) & ~BIT(3), 1003 .mode = 0444, 1004 }, 1005 { 1006 .label = "reset_sw_reset", 1007 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1008 .mask = GENMASK(7, 0) & ~BIT(4), 1009 .mode = 0444, 1010 }, 1011 { 1012 .label = "reset_fw_reset", 1013 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1014 .mask = GENMASK(7, 0) & ~BIT(5), 1015 .mode = 0444, 1016 }, 1017 { 1018 .label = "reset_hotswap_or_wd", 1019 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1020 .mask = GENMASK(7, 0) & ~BIT(6), 1021 .mode = 0444, 1022 }, 1023 { 1024 .label = "reset_asic_thermal", 1025 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1026 .mask = GENMASK(7, 0) & ~BIT(7), 1027 .mode = 0444, 1028 }, 1029 { 1030 .label = "psu1_on", 1031 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1032 .mask = GENMASK(7, 0) & ~BIT(0), 1033 .mode = 0200, 1034 }, 1035 { 1036 .label = "psu2_on", 1037 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1038 .mask = GENMASK(7, 0) & ~BIT(1), 1039 .mode = 0200, 1040 }, 1041 { 1042 .label = "pwr_cycle", 1043 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1044 .mask = GENMASK(7, 0) & ~BIT(2), 1045 .mode = 0200, 1046 }, 1047 { 1048 .label = "pwr_down", 1049 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1050 .mask = GENMASK(7, 0) & ~BIT(3), 1051 .mode = 0200, 1052 }, 1053 { 1054 .label = "select_iio", 1055 .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET, 1056 .mask = GENMASK(7, 0) & ~BIT(6), 1057 .mode = 0644, 1058 }, 1059 { 1060 .label = "asic_health", 1061 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 1062 .mask = MLXPLAT_CPLD_ASIC_MASK, 1063 .bit = 1, 1064 .mode = 0444, 1065 }, 1066 }; 1067 1068 static struct mlxreg_core_platform_data mlxplat_default_regs_io_data = { 1069 .data = mlxplat_mlxcpld_default_regs_io_data, 1070 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data), 1071 }; 1072 1073 /* Platform register access MSN21xx, MSN201x, MSN274x systems families data */ 1074 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data[] = { 1075 { 1076 .label = "cpld1_version", 1077 .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET, 1078 .bit = GENMASK(7, 0), 1079 .mode = 0444, 1080 }, 1081 { 1082 .label = "cpld2_version", 1083 .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET, 1084 .bit = GENMASK(7, 0), 1085 .mode = 0444, 1086 }, 1087 { 1088 .label = "reset_long_pb", 1089 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1090 .mask = GENMASK(7, 0) & ~BIT(0), 1091 .mode = 0444, 1092 }, 1093 { 1094 .label = "reset_short_pb", 1095 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1096 .mask = GENMASK(7, 0) & ~BIT(1), 1097 .mode = 0444, 1098 }, 1099 { 1100 .label = "reset_aux_pwr_or_ref", 1101 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1102 .mask = GENMASK(7, 0) & ~BIT(2), 1103 .mode = 0444, 1104 }, 1105 { 1106 .label = "reset_sw_reset", 1107 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1108 .mask = GENMASK(7, 0) & ~BIT(3), 1109 .mode = 0444, 1110 }, 1111 { 1112 .label = "reset_main_pwr_fail", 1113 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1114 .mask = GENMASK(7, 0) & ~BIT(4), 1115 .mode = 0444, 1116 }, 1117 { 1118 .label = "reset_asic_thermal", 1119 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1120 .mask = GENMASK(7, 0) & ~BIT(5), 1121 .mode = 0444, 1122 }, 1123 { 1124 .label = "reset_hotswap_or_halt", 1125 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1126 .mask = GENMASK(7, 0) & ~BIT(6), 1127 .mode = 0444, 1128 }, 1129 { 1130 .label = "reset_sff_wd", 1131 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET, 1132 .mask = GENMASK(7, 0) & ~BIT(6), 1133 .mode = 0444, 1134 }, 1135 { 1136 .label = "psu1_on", 1137 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1138 .mask = GENMASK(7, 0) & ~BIT(0), 1139 .mode = 0200, 1140 }, 1141 { 1142 .label = "psu2_on", 1143 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1144 .mask = GENMASK(7, 0) & ~BIT(1), 1145 .mode = 0200, 1146 }, 1147 { 1148 .label = "pwr_cycle", 1149 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1150 .mask = GENMASK(7, 0) & ~BIT(2), 1151 .mode = 0200, 1152 }, 1153 { 1154 .label = "pwr_down", 1155 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1156 .mask = GENMASK(7, 0) & ~BIT(3), 1157 .mode = 0200, 1158 }, 1159 { 1160 .label = "asic_health", 1161 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 1162 .mask = MLXPLAT_CPLD_ASIC_MASK, 1163 .bit = 1, 1164 .mode = 0444, 1165 }, 1166 }; 1167 1168 static struct mlxreg_core_platform_data mlxplat_msn21xx_regs_io_data = { 1169 .data = mlxplat_mlxcpld_msn21xx_regs_io_data, 1170 .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_regs_io_data), 1171 }; 1172 1173 /* Platform register access for next generation systems families data */ 1174 static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { 1175 { 1176 .label = "cpld1_version", 1177 .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET, 1178 .bit = GENMASK(7, 0), 1179 .mode = 0444, 1180 }, 1181 { 1182 .label = "cpld2_version", 1183 .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET, 1184 .bit = GENMASK(7, 0), 1185 .mode = 0444, 1186 }, 1187 { 1188 .label = "cpld3_version", 1189 .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET, 1190 .bit = GENMASK(7, 0), 1191 .mode = 0444, 1192 }, 1193 { 1194 .label = "cpld4_version", 1195 .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET, 1196 .bit = GENMASK(7, 0), 1197 .mode = 0444, 1198 }, 1199 { 1200 .label = "reset_long_pb", 1201 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1202 .mask = GENMASK(7, 0) & ~BIT(0), 1203 .mode = 0444, 1204 }, 1205 { 1206 .label = "reset_short_pb", 1207 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1208 .mask = GENMASK(7, 0) & ~BIT(1), 1209 .mode = 0444, 1210 }, 1211 { 1212 .label = "reset_aux_pwr_or_ref", 1213 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1214 .mask = GENMASK(7, 0) & ~BIT(2), 1215 .mode = 0444, 1216 }, 1217 { 1218 .label = "reset_from_comex", 1219 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1220 .mask = GENMASK(7, 0) & ~BIT(4), 1221 .mode = 0444, 1222 }, 1223 { 1224 .label = "reset_from_asic", 1225 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1226 .mask = GENMASK(7, 0) & ~BIT(5), 1227 .mode = 0444, 1228 }, 1229 { 1230 .label = "reset_swb_wd", 1231 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1232 .mask = GENMASK(7, 0) & ~BIT(6), 1233 .mode = 0444, 1234 }, 1235 { 1236 .label = "reset_asic_thermal", 1237 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1238 .mask = GENMASK(7, 0) & ~BIT(7), 1239 .mode = 0444, 1240 }, 1241 { 1242 .label = "reset_comex_pwr_fail", 1243 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET, 1244 .mask = GENMASK(7, 0) & ~BIT(3), 1245 .mode = 0444, 1246 }, 1247 { 1248 .label = "reset_comex_wd", 1249 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET, 1250 .mask = GENMASK(7, 0) & ~BIT(6), 1251 .mode = 0444, 1252 }, 1253 { 1254 .label = "reset_voltmon_upgrade_fail", 1255 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET, 1256 .mask = GENMASK(7, 0) & ~BIT(0), 1257 .mode = 0444, 1258 }, 1259 { 1260 .label = "reset_system", 1261 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET, 1262 .mask = GENMASK(7, 0) & ~BIT(1), 1263 .mode = 0444, 1264 }, 1265 { 1266 .label = "reset_comex_thermal", 1267 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET, 1268 .mask = GENMASK(7, 0) & ~BIT(3), 1269 .mode = 0444, 1270 }, 1271 { 1272 .label = "reset_reload_bios", 1273 .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET, 1274 .mask = GENMASK(7, 0) & ~BIT(5), 1275 .mode = 0444, 1276 }, 1277 { 1278 .label = "psu1_on", 1279 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1280 .mask = GENMASK(7, 0) & ~BIT(0), 1281 .mode = 0200, 1282 }, 1283 { 1284 .label = "psu2_on", 1285 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1286 .mask = GENMASK(7, 0) & ~BIT(1), 1287 .mode = 0200, 1288 }, 1289 { 1290 .label = "pwr_cycle", 1291 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1292 .mask = GENMASK(7, 0) & ~BIT(2), 1293 .mode = 0200, 1294 }, 1295 { 1296 .label = "pwr_down", 1297 .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, 1298 .mask = GENMASK(7, 0) & ~BIT(3), 1299 .mode = 0200, 1300 }, 1301 { 1302 .label = "jtag_enable", 1303 .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET, 1304 .mask = GENMASK(7, 0) & ~BIT(4), 1305 .mode = 0644, 1306 }, 1307 { 1308 .label = "asic_health", 1309 .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET, 1310 .mask = MLXPLAT_CPLD_ASIC_MASK, 1311 .bit = 1, 1312 .mode = 0444, 1313 }, 1314 { 1315 .label = "fan_dir", 1316 .reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION, 1317 .bit = GENMASK(7, 0), 1318 .mode = 0444, 1319 }, 1320 }; 1321 1322 static struct mlxreg_core_platform_data mlxplat_default_ng_regs_io_data = { 1323 .data = mlxplat_mlxcpld_default_ng_regs_io_data, 1324 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_regs_io_data), 1325 }; 1326 1327 /* Platform FAN default */ 1328 static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = { 1329 { 1330 .label = "pwm1", 1331 .reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET, 1332 }, 1333 { 1334 .label = "tacho1", 1335 .reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET, 1336 .mask = GENMASK(7, 0), 1337 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, 1338 .bit = BIT(0), 1339 }, 1340 { 1341 .label = "tacho2", 1342 .reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET, 1343 .mask = GENMASK(7, 0), 1344 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, 1345 .bit = BIT(1), 1346 }, 1347 { 1348 .label = "tacho3", 1349 .reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET, 1350 .mask = GENMASK(7, 0), 1351 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, 1352 .bit = BIT(2), 1353 }, 1354 { 1355 .label = "tacho4", 1356 .reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET, 1357 .mask = GENMASK(7, 0), 1358 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, 1359 .bit = BIT(3), 1360 }, 1361 { 1362 .label = "tacho5", 1363 .reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET, 1364 .mask = GENMASK(7, 0), 1365 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, 1366 .bit = BIT(4), 1367 }, 1368 { 1369 .label = "tacho6", 1370 .reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET, 1371 .mask = GENMASK(7, 0), 1372 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, 1373 .bit = BIT(5), 1374 }, 1375 { 1376 .label = "tacho7", 1377 .reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET, 1378 .mask = GENMASK(7, 0), 1379 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, 1380 .bit = BIT(6), 1381 }, 1382 { 1383 .label = "tacho8", 1384 .reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET, 1385 .mask = GENMASK(7, 0), 1386 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET, 1387 .bit = BIT(7), 1388 }, 1389 { 1390 .label = "tacho9", 1391 .reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET, 1392 .mask = GENMASK(7, 0), 1393 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET, 1394 .bit = BIT(0), 1395 }, 1396 { 1397 .label = "tacho10", 1398 .reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET, 1399 .mask = GENMASK(7, 0), 1400 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET, 1401 .bit = BIT(1), 1402 }, 1403 { 1404 .label = "tacho11", 1405 .reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET, 1406 .mask = GENMASK(7, 0), 1407 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET, 1408 .bit = BIT(2), 1409 }, 1410 { 1411 .label = "tacho12", 1412 .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET, 1413 .mask = GENMASK(7, 0), 1414 .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET, 1415 .bit = BIT(3), 1416 }, 1417 { 1418 .label = "conf", 1419 .capability = MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET, 1420 }, 1421 }; 1422 1423 static struct mlxreg_core_platform_data mlxplat_default_fan_data = { 1424 .data = mlxplat_mlxcpld_default_fan_data, 1425 .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data), 1426 }; 1427 1428 /* Watchdog type1: hardware implementation version1 1429 * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems). 1430 */ 1431 static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type1[] = { 1432 { 1433 .label = "action", 1434 .reg = MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET, 1435 .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK, 1436 .bit = 0, 1437 }, 1438 { 1439 .label = "timeout", 1440 .reg = MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET, 1441 .mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK, 1442 .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT, 1443 }, 1444 { 1445 .label = "ping", 1446 .reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET, 1447 .mask = MLXPLAT_CPLD_WD1_CLEAR_MASK, 1448 .bit = 0, 1449 }, 1450 { 1451 .label = "reset", 1452 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1453 .mask = GENMASK(7, 0) & ~BIT(6), 1454 .bit = 6, 1455 }, 1456 }; 1457 1458 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type1[] = { 1459 { 1460 .label = "action", 1461 .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 1462 .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK, 1463 .bit = 4, 1464 }, 1465 { 1466 .label = "timeout", 1467 .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET, 1468 .mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK, 1469 .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT, 1470 }, 1471 { 1472 .label = "ping", 1473 .reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET, 1474 .mask = MLXPLAT_CPLD_WD1_CLEAR_MASK, 1475 .bit = 1, 1476 }, 1477 }; 1478 1479 static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type1[] = { 1480 { 1481 .data = mlxplat_mlxcpld_wd_main_regs_type1, 1482 .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type1), 1483 .version = MLX_WDT_TYPE1, 1484 .identity = "mlx-wdt-main", 1485 }, 1486 { 1487 .data = mlxplat_mlxcpld_wd_aux_regs_type1, 1488 .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type1), 1489 .version = MLX_WDT_TYPE1, 1490 .identity = "mlx-wdt-aux", 1491 }, 1492 }; 1493 1494 /* Watchdog type2: hardware implementation version 2 1495 * (all systems except (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140). 1496 */ 1497 static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type2[] = { 1498 { 1499 .label = "action", 1500 .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 1501 .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK, 1502 .bit = 0, 1503 }, 1504 { 1505 .label = "timeout", 1506 .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET, 1507 .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK, 1508 .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT, 1509 }, 1510 { 1511 .label = "timeleft", 1512 .reg = MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET, 1513 .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK, 1514 }, 1515 { 1516 .label = "ping", 1517 .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 1518 .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK, 1519 .bit = 0, 1520 }, 1521 { 1522 .label = "reset", 1523 .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, 1524 .mask = GENMASK(7, 0) & ~BIT(6), 1525 .bit = 6, 1526 }, 1527 }; 1528 1529 static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type2[] = { 1530 { 1531 .label = "action", 1532 .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 1533 .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK, 1534 .bit = 4, 1535 }, 1536 { 1537 .label = "timeout", 1538 .reg = MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET, 1539 .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK, 1540 .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT, 1541 }, 1542 { 1543 .label = "timeleft", 1544 .reg = MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET, 1545 .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK, 1546 }, 1547 { 1548 .label = "ping", 1549 .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 1550 .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK, 1551 .bit = 4, 1552 }, 1553 }; 1554 1555 static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type2[] = { 1556 { 1557 .data = mlxplat_mlxcpld_wd_main_regs_type2, 1558 .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type2), 1559 .version = MLX_WDT_TYPE2, 1560 .identity = "mlx-wdt-main", 1561 }, 1562 { 1563 .data = mlxplat_mlxcpld_wd_aux_regs_type2, 1564 .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type2), 1565 .version = MLX_WDT_TYPE2, 1566 .identity = "mlx-wdt-aux", 1567 }, 1568 }; 1569 1570 static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg) 1571 { 1572 switch (reg) { 1573 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET: 1574 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET: 1575 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET: 1576 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET: 1577 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET: 1578 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET: 1579 case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET: 1580 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET: 1581 case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET: 1582 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET: 1583 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET: 1584 case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET: 1585 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET: 1586 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET: 1587 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET: 1588 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET: 1589 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET: 1590 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET: 1591 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: 1592 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: 1593 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET: 1594 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET: 1595 case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET: 1596 case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET: 1597 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET: 1598 case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET: 1599 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET: 1600 case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET: 1601 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET: 1602 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET: 1603 return true; 1604 } 1605 return false; 1606 } 1607 1608 static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) 1609 { 1610 switch (reg) { 1611 case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET: 1612 case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET: 1613 case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET: 1614 case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET: 1615 case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET: 1616 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET: 1617 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET: 1618 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET: 1619 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET: 1620 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET: 1621 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET: 1622 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET: 1623 case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION: 1624 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET: 1625 case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET: 1626 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET: 1627 case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET: 1628 case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET: 1629 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET: 1630 case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET: 1631 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET: 1632 case MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET: 1633 case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET: 1634 case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET: 1635 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET: 1636 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET: 1637 case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET: 1638 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET: 1639 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET: 1640 case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET: 1641 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET: 1642 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET: 1643 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET: 1644 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: 1645 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: 1646 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET: 1647 case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET: 1648 case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET: 1649 case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET: 1650 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET: 1651 case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET: 1652 case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET: 1653 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET: 1654 case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET: 1655 case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET: 1656 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET: 1657 case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET: 1658 case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET: 1659 case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET: 1660 case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET: 1661 case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET: 1662 case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET: 1663 case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET: 1664 case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET: 1665 case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET: 1666 case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET: 1667 case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET: 1668 case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET: 1669 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET: 1670 case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET: 1671 case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET: 1672 case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET: 1673 case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET: 1674 return true; 1675 } 1676 return false; 1677 } 1678 1679 static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) 1680 { 1681 switch (reg) { 1682 case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET: 1683 case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET: 1684 case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET: 1685 case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET: 1686 case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET: 1687 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET: 1688 case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET: 1689 case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET: 1690 case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET: 1691 case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET: 1692 case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET: 1693 case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET: 1694 case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION: 1695 case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET: 1696 case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET: 1697 case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET: 1698 case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET: 1699 case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET: 1700 case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET: 1701 case MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET: 1702 case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET: 1703 case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET: 1704 case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET: 1705 case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET: 1706 case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET: 1707 case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET: 1708 case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET: 1709 case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET: 1710 case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET: 1711 case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET: 1712 case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET: 1713 case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET: 1714 case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET: 1715 case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET: 1716 case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET: 1717 case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET: 1718 case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET: 1719 case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET: 1720 case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET: 1721 case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET: 1722 case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET: 1723 case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET: 1724 case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET: 1725 case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET: 1726 case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET: 1727 case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET: 1728 case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET: 1729 case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET: 1730 case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET: 1731 case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET: 1732 case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET: 1733 case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET: 1734 case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET: 1735 case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET: 1736 case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET: 1737 return true; 1738 } 1739 return false; 1740 } 1741 1742 static const struct reg_default mlxplat_mlxcpld_regmap_default[] = { 1743 { MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 }, 1744 { MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 }, 1745 { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 }, 1746 { MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET, 0x00 }, 1747 }; 1748 1749 static const struct reg_default mlxplat_mlxcpld_regmap_ng[] = { 1750 { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 }, 1751 { MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET, 0x00 }, 1752 }; 1753 1754 struct mlxplat_mlxcpld_regmap_context { 1755 void __iomem *base; 1756 }; 1757 1758 static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx; 1759 1760 static int 1761 mlxplat_mlxcpld_reg_read(void *context, unsigned int reg, unsigned int *val) 1762 { 1763 struct mlxplat_mlxcpld_regmap_context *ctx = context; 1764 1765 *val = ioread8(ctx->base + reg); 1766 return 0; 1767 } 1768 1769 static int 1770 mlxplat_mlxcpld_reg_write(void *context, unsigned int reg, unsigned int val) 1771 { 1772 struct mlxplat_mlxcpld_regmap_context *ctx = context; 1773 1774 iowrite8(val, ctx->base + reg); 1775 return 0; 1776 } 1777 1778 static const struct regmap_config mlxplat_mlxcpld_regmap_config = { 1779 .reg_bits = 8, 1780 .val_bits = 8, 1781 .max_register = 255, 1782 .cache_type = REGCACHE_FLAT, 1783 .writeable_reg = mlxplat_mlxcpld_writeable_reg, 1784 .readable_reg = mlxplat_mlxcpld_readable_reg, 1785 .volatile_reg = mlxplat_mlxcpld_volatile_reg, 1786 .reg_defaults = mlxplat_mlxcpld_regmap_default, 1787 .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_default), 1788 .reg_read = mlxplat_mlxcpld_reg_read, 1789 .reg_write = mlxplat_mlxcpld_reg_write, 1790 }; 1791 1792 static const struct regmap_config mlxplat_mlxcpld_regmap_config_ng = { 1793 .reg_bits = 8, 1794 .val_bits = 8, 1795 .max_register = 255, 1796 .cache_type = REGCACHE_FLAT, 1797 .writeable_reg = mlxplat_mlxcpld_writeable_reg, 1798 .readable_reg = mlxplat_mlxcpld_readable_reg, 1799 .volatile_reg = mlxplat_mlxcpld_volatile_reg, 1800 .reg_defaults = mlxplat_mlxcpld_regmap_ng, 1801 .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_ng), 1802 .reg_read = mlxplat_mlxcpld_reg_read, 1803 .reg_write = mlxplat_mlxcpld_reg_write, 1804 }; 1805 1806 static struct resource mlxplat_mlxcpld_resources[] = { 1807 [0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"), 1808 }; 1809 1810 static struct platform_device *mlxplat_dev; 1811 static struct mlxreg_core_hotplug_platform_data *mlxplat_i2c; 1812 static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug; 1813 static struct mlxreg_core_platform_data *mlxplat_led; 1814 static struct mlxreg_core_platform_data *mlxplat_regs_io; 1815 static struct mlxreg_core_platform_data *mlxplat_fan; 1816 static struct mlxreg_core_platform_data 1817 *mlxplat_wd_data[MLXPLAT_CPLD_WD_MAX_DEVS]; 1818 static const struct regmap_config *mlxplat_regmap_config; 1819 1820 static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi) 1821 { 1822 int i; 1823 1824 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 1825 mlxplat_mux_data[i].values = mlxplat_default_channels[i]; 1826 mlxplat_mux_data[i].n_values = 1827 ARRAY_SIZE(mlxplat_default_channels[i]); 1828 } 1829 mlxplat_hotplug = &mlxplat_mlxcpld_default_data; 1830 mlxplat_hotplug->deferred_nr = 1831 mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1]; 1832 mlxplat_led = &mlxplat_default_led_data; 1833 mlxplat_regs_io = &mlxplat_default_regs_io_data; 1834 mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0]; 1835 1836 return 1; 1837 }; 1838 1839 static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi) 1840 { 1841 int i; 1842 1843 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 1844 mlxplat_mux_data[i].values = mlxplat_msn21xx_channels; 1845 mlxplat_mux_data[i].n_values = 1846 ARRAY_SIZE(mlxplat_msn21xx_channels); 1847 } 1848 mlxplat_hotplug = &mlxplat_mlxcpld_msn21xx_data; 1849 mlxplat_hotplug->deferred_nr = 1850 mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1]; 1851 mlxplat_led = &mlxplat_msn21xx_led_data; 1852 mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data; 1853 mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0]; 1854 1855 return 1; 1856 }; 1857 1858 static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi) 1859 { 1860 int i; 1861 1862 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 1863 mlxplat_mux_data[i].values = mlxplat_msn21xx_channels; 1864 mlxplat_mux_data[i].n_values = 1865 ARRAY_SIZE(mlxplat_msn21xx_channels); 1866 } 1867 mlxplat_hotplug = &mlxplat_mlxcpld_msn274x_data; 1868 mlxplat_hotplug->deferred_nr = 1869 mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1]; 1870 mlxplat_led = &mlxplat_default_led_data; 1871 mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data; 1872 mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0]; 1873 1874 return 1; 1875 }; 1876 1877 static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi) 1878 { 1879 int i; 1880 1881 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 1882 mlxplat_mux_data[i].values = mlxplat_msn21xx_channels; 1883 mlxplat_mux_data[i].n_values = 1884 ARRAY_SIZE(mlxplat_msn21xx_channels); 1885 } 1886 mlxplat_hotplug = &mlxplat_mlxcpld_msn201x_data; 1887 mlxplat_hotplug->deferred_nr = 1888 mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1]; 1889 mlxplat_led = &mlxplat_msn21xx_led_data; 1890 mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data; 1891 mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0]; 1892 1893 return 1; 1894 }; 1895 1896 static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi) 1897 { 1898 int i; 1899 1900 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 1901 mlxplat_mux_data[i].values = mlxplat_msn21xx_channels; 1902 mlxplat_mux_data[i].n_values = 1903 ARRAY_SIZE(mlxplat_msn21xx_channels); 1904 } 1905 mlxplat_hotplug = &mlxplat_mlxcpld_default_ng_data; 1906 mlxplat_hotplug->deferred_nr = 1907 mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1]; 1908 mlxplat_led = &mlxplat_default_ng_led_data; 1909 mlxplat_regs_io = &mlxplat_default_ng_regs_io_data; 1910 mlxplat_fan = &mlxplat_default_fan_data; 1911 for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++) 1912 mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i]; 1913 mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data; 1914 mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng; 1915 1916 return 1; 1917 }; 1918 1919 static const struct dmi_system_id mlxplat_dmi_table[] __initconst = { 1920 { 1921 .callback = mlxplat_dmi_default_matched, 1922 .matches = { 1923 DMI_MATCH(DMI_BOARD_NAME, "VMOD0001"), 1924 }, 1925 }, 1926 { 1927 .callback = mlxplat_dmi_msn21xx_matched, 1928 .matches = { 1929 DMI_MATCH(DMI_BOARD_NAME, "VMOD0002"), 1930 }, 1931 }, 1932 { 1933 .callback = mlxplat_dmi_msn274x_matched, 1934 .matches = { 1935 DMI_MATCH(DMI_BOARD_NAME, "VMOD0003"), 1936 }, 1937 }, 1938 { 1939 .callback = mlxplat_dmi_msn201x_matched, 1940 .matches = { 1941 DMI_MATCH(DMI_BOARD_NAME, "VMOD0004"), 1942 }, 1943 }, 1944 { 1945 .callback = mlxplat_dmi_qmb7xx_matched, 1946 .matches = { 1947 DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"), 1948 }, 1949 }, 1950 { 1951 .callback = mlxplat_dmi_qmb7xx_matched, 1952 .matches = { 1953 DMI_MATCH(DMI_BOARD_NAME, "VMOD0007"), 1954 }, 1955 }, 1956 { 1957 .callback = mlxplat_dmi_msn274x_matched, 1958 .matches = { 1959 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 1960 DMI_MATCH(DMI_PRODUCT_NAME, "MSN274"), 1961 }, 1962 }, 1963 { 1964 .callback = mlxplat_dmi_default_matched, 1965 .matches = { 1966 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 1967 DMI_MATCH(DMI_PRODUCT_NAME, "MSN24"), 1968 }, 1969 }, 1970 { 1971 .callback = mlxplat_dmi_default_matched, 1972 .matches = { 1973 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 1974 DMI_MATCH(DMI_PRODUCT_NAME, "MSN27"), 1975 }, 1976 }, 1977 { 1978 .callback = mlxplat_dmi_default_matched, 1979 .matches = { 1980 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 1981 DMI_MATCH(DMI_PRODUCT_NAME, "MSB"), 1982 }, 1983 }, 1984 { 1985 .callback = mlxplat_dmi_default_matched, 1986 .matches = { 1987 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 1988 DMI_MATCH(DMI_PRODUCT_NAME, "MSX"), 1989 }, 1990 }, 1991 { 1992 .callback = mlxplat_dmi_msn21xx_matched, 1993 .matches = { 1994 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 1995 DMI_MATCH(DMI_PRODUCT_NAME, "MSN21"), 1996 }, 1997 }, 1998 { 1999 .callback = mlxplat_dmi_msn201x_matched, 2000 .matches = { 2001 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 2002 DMI_MATCH(DMI_PRODUCT_NAME, "MSN201"), 2003 }, 2004 }, 2005 { 2006 .callback = mlxplat_dmi_qmb7xx_matched, 2007 .matches = { 2008 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 2009 DMI_MATCH(DMI_PRODUCT_NAME, "MQM87"), 2010 }, 2011 }, 2012 { 2013 .callback = mlxplat_dmi_qmb7xx_matched, 2014 .matches = { 2015 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 2016 DMI_MATCH(DMI_PRODUCT_NAME, "MSN37"), 2017 }, 2018 }, 2019 { 2020 .callback = mlxplat_dmi_qmb7xx_matched, 2021 .matches = { 2022 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 2023 DMI_MATCH(DMI_PRODUCT_NAME, "MSN34"), 2024 }, 2025 }, 2026 { 2027 .callback = mlxplat_dmi_qmb7xx_matched, 2028 .matches = { 2029 DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"), 2030 DMI_MATCH(DMI_PRODUCT_NAME, "MSN38"), 2031 }, 2032 }, 2033 { } 2034 }; 2035 2036 MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table); 2037 2038 static int mlxplat_mlxcpld_verify_bus_topology(int *nr) 2039 { 2040 struct i2c_adapter *search_adap; 2041 int shift, i; 2042 2043 /* Scan adapters from expected id to verify it is free. */ 2044 *nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; 2045 for (i = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; i < 2046 MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM; i++) { 2047 search_adap = i2c_get_adapter(i); 2048 if (search_adap) { 2049 i2c_put_adapter(search_adap); 2050 continue; 2051 } 2052 2053 /* Return if expected parent adapter is free. */ 2054 if (i == MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR) 2055 return 0; 2056 break; 2057 } 2058 2059 /* Return with error if free id for adapter is not found. */ 2060 if (i == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM) 2061 return -ENODEV; 2062 2063 /* Shift adapter ids, since expected parent adapter is not free. */ 2064 *nr = i; 2065 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 2066 shift = *nr - mlxplat_mux_data[i].parent; 2067 mlxplat_mux_data[i].parent = *nr; 2068 mlxplat_mux_data[i].base_nr += shift; 2069 if (shift > 0) 2070 mlxplat_hotplug->shift_nr = shift; 2071 } 2072 2073 return 0; 2074 } 2075 2076 static int __init mlxplat_init(void) 2077 { 2078 struct mlxplat_priv *priv; 2079 int i, j, nr, err; 2080 2081 if (!dmi_check_system(mlxplat_dmi_table)) 2082 return -ENODEV; 2083 2084 mlxplat_dev = platform_device_register_simple(MLX_PLAT_DEVICE_NAME, -1, 2085 mlxplat_lpc_resources, 2086 ARRAY_SIZE(mlxplat_lpc_resources)); 2087 2088 if (IS_ERR(mlxplat_dev)) 2089 return PTR_ERR(mlxplat_dev); 2090 2091 priv = devm_kzalloc(&mlxplat_dev->dev, sizeof(struct mlxplat_priv), 2092 GFP_KERNEL); 2093 if (!priv) { 2094 err = -ENOMEM; 2095 goto fail_alloc; 2096 } 2097 platform_set_drvdata(mlxplat_dev, priv); 2098 2099 mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev, 2100 mlxplat_lpc_resources[1].start, 1); 2101 if (!mlxplat_mlxcpld_regmap_ctx.base) { 2102 err = -ENOMEM; 2103 goto fail_alloc; 2104 } 2105 2106 if (!mlxplat_regmap_config) 2107 mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config; 2108 2109 priv->regmap = devm_regmap_init(&mlxplat_dev->dev, NULL, 2110 &mlxplat_mlxcpld_regmap_ctx, 2111 mlxplat_regmap_config); 2112 if (IS_ERR(priv->regmap)) { 2113 err = PTR_ERR(priv->regmap); 2114 goto fail_alloc; 2115 } 2116 2117 err = mlxplat_mlxcpld_verify_bus_topology(&nr); 2118 if (nr < 0) 2119 goto fail_alloc; 2120 2121 nr = (nr == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM) ? -1 : nr; 2122 if (mlxplat_i2c) 2123 mlxplat_i2c->regmap = priv->regmap; 2124 priv->pdev_i2c = platform_device_register_resndata( 2125 &mlxplat_dev->dev, "i2c_mlxcpld", 2126 nr, mlxplat_mlxcpld_resources, 2127 ARRAY_SIZE(mlxplat_mlxcpld_resources), 2128 mlxplat_i2c, sizeof(*mlxplat_i2c)); 2129 if (IS_ERR(priv->pdev_i2c)) { 2130 err = PTR_ERR(priv->pdev_i2c); 2131 goto fail_alloc; 2132 } 2133 2134 for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) { 2135 priv->pdev_mux[i] = platform_device_register_resndata( 2136 &priv->pdev_i2c->dev, 2137 "i2c-mux-reg", i, NULL, 2138 0, &mlxplat_mux_data[i], 2139 sizeof(mlxplat_mux_data[i])); 2140 if (IS_ERR(priv->pdev_mux[i])) { 2141 err = PTR_ERR(priv->pdev_mux[i]); 2142 goto fail_platform_mux_register; 2143 } 2144 } 2145 2146 /* Add hotplug driver */ 2147 mlxplat_hotplug->regmap = priv->regmap; 2148 priv->pdev_hotplug = platform_device_register_resndata( 2149 &mlxplat_dev->dev, "mlxreg-hotplug", 2150 PLATFORM_DEVID_NONE, 2151 mlxplat_mlxcpld_resources, 2152 ARRAY_SIZE(mlxplat_mlxcpld_resources), 2153 mlxplat_hotplug, sizeof(*mlxplat_hotplug)); 2154 if (IS_ERR(priv->pdev_hotplug)) { 2155 err = PTR_ERR(priv->pdev_hotplug); 2156 goto fail_platform_mux_register; 2157 } 2158 2159 /* Set default registers. */ 2160 for (j = 0; j < mlxplat_regmap_config->num_reg_defaults; j++) { 2161 err = regmap_write(priv->regmap, 2162 mlxplat_regmap_config->reg_defaults[j].reg, 2163 mlxplat_regmap_config->reg_defaults[j].def); 2164 if (err) 2165 goto fail_platform_mux_register; 2166 } 2167 2168 /* Add LED driver. */ 2169 mlxplat_led->regmap = priv->regmap; 2170 priv->pdev_led = platform_device_register_resndata( 2171 &mlxplat_dev->dev, "leds-mlxreg", 2172 PLATFORM_DEVID_NONE, NULL, 0, 2173 mlxplat_led, sizeof(*mlxplat_led)); 2174 if (IS_ERR(priv->pdev_led)) { 2175 err = PTR_ERR(priv->pdev_led); 2176 goto fail_platform_hotplug_register; 2177 } 2178 2179 /* Add registers io access driver. */ 2180 if (mlxplat_regs_io) { 2181 mlxplat_regs_io->regmap = priv->regmap; 2182 priv->pdev_io_regs = platform_device_register_resndata( 2183 &mlxplat_dev->dev, "mlxreg-io", 2184 PLATFORM_DEVID_NONE, NULL, 0, 2185 mlxplat_regs_io, 2186 sizeof(*mlxplat_regs_io)); 2187 if (IS_ERR(priv->pdev_io_regs)) { 2188 err = PTR_ERR(priv->pdev_io_regs); 2189 goto fail_platform_led_register; 2190 } 2191 } 2192 2193 /* Add FAN driver. */ 2194 if (mlxplat_fan) { 2195 mlxplat_fan->regmap = priv->regmap; 2196 priv->pdev_fan = platform_device_register_resndata( 2197 &mlxplat_dev->dev, "mlxreg-fan", 2198 PLATFORM_DEVID_NONE, NULL, 0, 2199 mlxplat_fan, 2200 sizeof(*mlxplat_fan)); 2201 if (IS_ERR(priv->pdev_fan)) { 2202 err = PTR_ERR(priv->pdev_fan); 2203 goto fail_platform_io_regs_register; 2204 } 2205 } 2206 2207 /* Add WD drivers. */ 2208 for (j = 0; j < MLXPLAT_CPLD_WD_MAX_DEVS; j++) { 2209 if (mlxplat_wd_data[j]) { 2210 mlxplat_wd_data[j]->regmap = priv->regmap; 2211 priv->pdev_wd[j] = platform_device_register_resndata( 2212 &mlxplat_dev->dev, "mlx-wdt", 2213 j, NULL, 0, 2214 mlxplat_wd_data[j], 2215 sizeof(*mlxplat_wd_data[j])); 2216 if (IS_ERR(priv->pdev_wd[j])) { 2217 err = PTR_ERR(priv->pdev_wd[j]); 2218 goto fail_platform_wd_register; 2219 } 2220 } 2221 } 2222 2223 /* Sync registers with hardware. */ 2224 regcache_mark_dirty(priv->regmap); 2225 err = regcache_sync(priv->regmap); 2226 if (err) 2227 goto fail_platform_wd_register; 2228 2229 return 0; 2230 2231 fail_platform_wd_register: 2232 while (--j >= 0) 2233 platform_device_unregister(priv->pdev_wd[j]); 2234 if (mlxplat_fan) 2235 platform_device_unregister(priv->pdev_fan); 2236 fail_platform_io_regs_register: 2237 if (mlxplat_regs_io) 2238 platform_device_unregister(priv->pdev_io_regs); 2239 fail_platform_led_register: 2240 platform_device_unregister(priv->pdev_led); 2241 fail_platform_hotplug_register: 2242 platform_device_unregister(priv->pdev_hotplug); 2243 fail_platform_mux_register: 2244 while (--i >= 0) 2245 platform_device_unregister(priv->pdev_mux[i]); 2246 platform_device_unregister(priv->pdev_i2c); 2247 fail_alloc: 2248 platform_device_unregister(mlxplat_dev); 2249 2250 return err; 2251 } 2252 module_init(mlxplat_init); 2253 2254 static void __exit mlxplat_exit(void) 2255 { 2256 struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev); 2257 int i; 2258 2259 for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--) 2260 platform_device_unregister(priv->pdev_wd[i]); 2261 if (priv->pdev_fan) 2262 platform_device_unregister(priv->pdev_fan); 2263 if (priv->pdev_io_regs) 2264 platform_device_unregister(priv->pdev_io_regs); 2265 platform_device_unregister(priv->pdev_led); 2266 platform_device_unregister(priv->pdev_hotplug); 2267 2268 for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--) 2269 platform_device_unregister(priv->pdev_mux[i]); 2270 2271 platform_device_unregister(priv->pdev_i2c); 2272 platform_device_unregister(mlxplat_dev); 2273 } 2274 module_exit(mlxplat_exit); 2275 2276 MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)"); 2277 MODULE_DESCRIPTION("Mellanox platform driver"); 2278 MODULE_LICENSE("Dual BSD/GPL"); 2279