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