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