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