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