0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/device.h>
0009 #include <linux/i2c.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/irq.h>
0012 #include <linux/gpio.h>
0013 #include <linux/module.h>
0014 #include <linux/platform_data/mlxcpld.h>
0015 #include <linux/platform_data/mlxreg.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/regmap.h>
0018
0019
0020 #define NVSW_SN2201_CPLD_LPC_I2C_BASE_ADRR 0x2000
0021 #define NVSW_SN2201_CPLD_LPC_IO_RANGE 0x100
0022 #define NVSW_SN2201_HW_VER_ID_OFFSET 0x00
0023 #define NVSW_SN2201_BOARD_ID_OFFSET 0x01
0024 #define NVSW_SN2201_CPLD_VER_OFFSET 0x02
0025 #define NVSW_SN2201_CPLD_MVER_OFFSET 0x03
0026 #define NVSW_SN2201_CPLD_ID_OFFSET 0x04
0027 #define NVSW_SN2201_CPLD_PN_OFFSET 0x05
0028 #define NVSW_SN2201_CPLD_PN1_OFFSET 0x06
0029 #define NVSW_SN2201_PSU_CTRL_OFFSET 0x0a
0030 #define NVSW_SN2201_QSFP28_STATUS_OFFSET 0x0b
0031 #define NVSW_SN2201_QSFP28_INT_STATUS_OFFSET 0x0c
0032 #define NVSW_SN2201_QSFP28_LP_STATUS_OFFSET 0x0d
0033 #define NVSW_SN2201_QSFP28_RST_STATUS_OFFSET 0x0e
0034 #define NVSW_SN2201_SYS_STATUS_OFFSET 0x0f
0035 #define NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET 0x10
0036 #define NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET 0x12
0037 #define NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET 0x13
0038 #define NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET 0x14
0039 #define NVSW_SN2201_SYS_RST_STATUS_OFFSET 0x15
0040 #define NVSW_SN2201_SYS_INT_STATUS_OFFSET 0x21
0041 #define NVSW_SN2201_SYS_INT_MASK_OFFSET 0x22
0042 #define NVSW_SN2201_ASIC_STATUS_OFFSET 0x24
0043 #define NVSW_SN2201_ASIC_EVENT_OFFSET 0x25
0044 #define NVSW_SN2201_ASIC_MAKS_OFFSET 0x26
0045 #define NVSW_SN2201_THML_STATUS_OFFSET 0x27
0046 #define NVSW_SN2201_THML_EVENT_OFFSET 0x28
0047 #define NVSW_SN2201_THML_MASK_OFFSET 0x29
0048 #define NVSW_SN2201_PS_ALT_STATUS_OFFSET 0x2a
0049 #define NVSW_SN2201_PS_ALT_EVENT_OFFSET 0x2b
0050 #define NVSW_SN2201_PS_ALT_MASK_OFFSET 0x2c
0051 #define NVSW_SN2201_PS_PRSNT_STATUS_OFFSET 0x30
0052 #define NVSW_SN2201_PS_PRSNT_EVENT_OFFSET 0x31
0053 #define NVSW_SN2201_PS_PRSNT_MASK_OFFSET 0x32
0054 #define NVSW_SN2201_PS_DC_OK_STATUS_OFFSET 0x33
0055 #define NVSW_SN2201_PS_DC_OK_EVENT_OFFSET 0x34
0056 #define NVSW_SN2201_PS_DC_OK_MASK_OFFSET 0x35
0057 #define NVSW_SN2201_RST_CAUSE1_OFFSET 0x36
0058 #define NVSW_SN2201_RST_CAUSE2_OFFSET 0x37
0059 #define NVSW_SN2201_RST_SW_CTRL_OFFSET 0x38
0060 #define NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET 0x3a
0061 #define NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET 0x3b
0062 #define NVSW_SN2201_FAN_PRSNT_MASK_OFFSET 0x3c
0063 #define NVSW_SN2201_WD_TMR_OFFSET_LSB 0x40
0064 #define NVSW_SN2201_WD_TMR_OFFSET_MSB 0x41
0065 #define NVSW_SN2201_WD_ACT_OFFSET 0x42
0066 #define NVSW_SN2201_FAN_LED1_CTRL_OFFSET 0x50
0067 #define NVSW_SN2201_FAN_LED2_CTRL_OFFSET 0x51
0068 #define NVSW_SN2201_REG_MAX 0x52
0069
0070
0071 #define NVSW_SN2201_PHY_I2C_BUS_NUM 2
0072
0073 #define NVSW_SN2201_MAIN_MUX_CHNL_NUM 8
0074
0075 #define NVSW_SN2201_MAIN_NR 0
0076 #define NVSW_SN2201_MAIN_MUX_NR 1
0077 #define NVSW_SN2201_MAIN_MUX_DEFER_NR (NVSW_SN2201_PHY_I2C_BUS_NUM + \
0078 NVSW_SN2201_MAIN_MUX_CHNL_NUM - 1)
0079
0080 #define NVSW_SN2201_MAIN_MUX_CH0_NR NVSW_SN2201_PHY_I2C_BUS_NUM
0081 #define NVSW_SN2201_MAIN_MUX_CH1_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 1)
0082 #define NVSW_SN2201_MAIN_MUX_CH2_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 2)
0083 #define NVSW_SN2201_MAIN_MUX_CH3_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 3)
0084 #define NVSW_SN2201_MAIN_MUX_CH5_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 5)
0085 #define NVSW_SN2201_MAIN_MUX_CH6_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 6)
0086 #define NVSW_SN2201_MAIN_MUX_CH7_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 7)
0087
0088 #define NVSW_SN2201_CPLD_NR NVSW_SN2201_MAIN_MUX_CH0_NR
0089 #define NVSW_SN2201_NR_NONE -1
0090
0091
0092
0093
0094 #define NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF 0xe0
0095 #define NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF 0x04
0096 #define NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF 0x02
0097 #define NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF 0x10
0098 #define NVSW_SN2201_CPLD_AGGR_MASK_DEF \
0099 (NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF \
0100 | NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF \
0101 | NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF \
0102 | NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF)
0103
0104 #define NVSW_SN2201_CPLD_ASIC_MASK GENMASK(3, 1)
0105 #define NVSW_SN2201_CPLD_PSU_MASK GENMASK(1, 0)
0106 #define NVSW_SN2201_CPLD_PWR_MASK GENMASK(1, 0)
0107 #define NVSW_SN2201_CPLD_FAN_MASK GENMASK(3, 0)
0108
0109 #define NVSW_SN2201_CPLD_SYSIRQ 26
0110 #define NVSW_SN2201_LPC_SYSIRQ 28
0111 #define NVSW_SN2201_CPLD_I2CADDR 0x41
0112
0113 #define NVSW_SN2201_WD_DFLT_TIMEOUT 600
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 struct nvsw_sn2201 {
0133 struct device *dev;
0134 struct mlxreg_core_platform_data *io_data;
0135 struct mlxreg_core_platform_data *led_data;
0136 struct mlxreg_core_platform_data *wd_data;
0137 struct mlxreg_core_hotplug_platform_data *hotplug_data;
0138 struct mlxreg_core_hotplug_platform_data *i2c_data;
0139 struct platform_device *led;
0140 struct platform_device *wd;
0141 struct platform_device *io_regs;
0142 struct platform_device *pdev_hotplug;
0143 struct platform_device *pdev_i2c;
0144 struct mlxreg_hotplug_device *sn2201_devs;
0145 int sn2201_devs_num;
0146 struct mlxreg_hotplug_device *main_mux_devs;
0147 int main_mux_devs_num;
0148 struct mlxreg_hotplug_device *cpld_devs;
0149 int cpld_devs_num;
0150 int main_mux_deferred_nr;
0151 };
0152
0153 static bool nvsw_sn2201_writeable_reg(struct device *dev, unsigned int reg)
0154 {
0155 switch (reg) {
0156 case NVSW_SN2201_PSU_CTRL_OFFSET:
0157 case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET:
0158 case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET:
0159 case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET:
0160 case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET:
0161 case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET:
0162 case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET:
0163 case NVSW_SN2201_SYS_RST_STATUS_OFFSET:
0164 case NVSW_SN2201_SYS_INT_MASK_OFFSET:
0165 case NVSW_SN2201_ASIC_EVENT_OFFSET:
0166 case NVSW_SN2201_ASIC_MAKS_OFFSET:
0167 case NVSW_SN2201_THML_EVENT_OFFSET:
0168 case NVSW_SN2201_THML_MASK_OFFSET:
0169 case NVSW_SN2201_PS_ALT_EVENT_OFFSET:
0170 case NVSW_SN2201_PS_ALT_MASK_OFFSET:
0171 case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET:
0172 case NVSW_SN2201_PS_PRSNT_MASK_OFFSET:
0173 case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET:
0174 case NVSW_SN2201_PS_DC_OK_MASK_OFFSET:
0175 case NVSW_SN2201_RST_SW_CTRL_OFFSET:
0176 case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET:
0177 case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET:
0178 case NVSW_SN2201_WD_TMR_OFFSET_LSB:
0179 case NVSW_SN2201_WD_TMR_OFFSET_MSB:
0180 case NVSW_SN2201_WD_ACT_OFFSET:
0181 case NVSW_SN2201_FAN_LED1_CTRL_OFFSET:
0182 case NVSW_SN2201_FAN_LED2_CTRL_OFFSET:
0183 return true;
0184 }
0185 return false;
0186 }
0187
0188 static bool nvsw_sn2201_readable_reg(struct device *dev, unsigned int reg)
0189 {
0190 switch (reg) {
0191 case NVSW_SN2201_HW_VER_ID_OFFSET:
0192 case NVSW_SN2201_BOARD_ID_OFFSET:
0193 case NVSW_SN2201_CPLD_VER_OFFSET:
0194 case NVSW_SN2201_CPLD_MVER_OFFSET:
0195 case NVSW_SN2201_CPLD_ID_OFFSET:
0196 case NVSW_SN2201_CPLD_PN_OFFSET:
0197 case NVSW_SN2201_CPLD_PN1_OFFSET:
0198 case NVSW_SN2201_PSU_CTRL_OFFSET:
0199 case NVSW_SN2201_QSFP28_STATUS_OFFSET:
0200 case NVSW_SN2201_QSFP28_INT_STATUS_OFFSET:
0201 case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET:
0202 case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET:
0203 case NVSW_SN2201_SYS_STATUS_OFFSET:
0204 case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET:
0205 case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET:
0206 case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET:
0207 case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET:
0208 case NVSW_SN2201_SYS_RST_STATUS_OFFSET:
0209 case NVSW_SN2201_RST_CAUSE1_OFFSET:
0210 case NVSW_SN2201_RST_CAUSE2_OFFSET:
0211 case NVSW_SN2201_SYS_INT_STATUS_OFFSET:
0212 case NVSW_SN2201_SYS_INT_MASK_OFFSET:
0213 case NVSW_SN2201_ASIC_STATUS_OFFSET:
0214 case NVSW_SN2201_ASIC_EVENT_OFFSET:
0215 case NVSW_SN2201_ASIC_MAKS_OFFSET:
0216 case NVSW_SN2201_THML_STATUS_OFFSET:
0217 case NVSW_SN2201_THML_EVENT_OFFSET:
0218 case NVSW_SN2201_THML_MASK_OFFSET:
0219 case NVSW_SN2201_PS_ALT_STATUS_OFFSET:
0220 case NVSW_SN2201_PS_ALT_EVENT_OFFSET:
0221 case NVSW_SN2201_PS_ALT_MASK_OFFSET:
0222 case NVSW_SN2201_PS_PRSNT_STATUS_OFFSET:
0223 case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET:
0224 case NVSW_SN2201_PS_PRSNT_MASK_OFFSET:
0225 case NVSW_SN2201_PS_DC_OK_STATUS_OFFSET:
0226 case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET:
0227 case NVSW_SN2201_PS_DC_OK_MASK_OFFSET:
0228 case NVSW_SN2201_RST_SW_CTRL_OFFSET:
0229 case NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET:
0230 case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET:
0231 case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET:
0232 case NVSW_SN2201_WD_TMR_OFFSET_LSB:
0233 case NVSW_SN2201_WD_TMR_OFFSET_MSB:
0234 case NVSW_SN2201_WD_ACT_OFFSET:
0235 case NVSW_SN2201_FAN_LED1_CTRL_OFFSET:
0236 case NVSW_SN2201_FAN_LED2_CTRL_OFFSET:
0237 return true;
0238 }
0239 return false;
0240 }
0241
0242 static bool nvsw_sn2201_volatile_reg(struct device *dev, unsigned int reg)
0243 {
0244 switch (reg) {
0245 case NVSW_SN2201_HW_VER_ID_OFFSET:
0246 case NVSW_SN2201_BOARD_ID_OFFSET:
0247 case NVSW_SN2201_CPLD_VER_OFFSET:
0248 case NVSW_SN2201_CPLD_MVER_OFFSET:
0249 case NVSW_SN2201_CPLD_ID_OFFSET:
0250 case NVSW_SN2201_CPLD_PN_OFFSET:
0251 case NVSW_SN2201_CPLD_PN1_OFFSET:
0252 case NVSW_SN2201_PSU_CTRL_OFFSET:
0253 case NVSW_SN2201_QSFP28_STATUS_OFFSET:
0254 case NVSW_SN2201_QSFP28_INT_STATUS_OFFSET:
0255 case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET:
0256 case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET:
0257 case NVSW_SN2201_SYS_STATUS_OFFSET:
0258 case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET:
0259 case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET:
0260 case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET:
0261 case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET:
0262 case NVSW_SN2201_SYS_RST_STATUS_OFFSET:
0263 case NVSW_SN2201_RST_CAUSE1_OFFSET:
0264 case NVSW_SN2201_RST_CAUSE2_OFFSET:
0265 case NVSW_SN2201_SYS_INT_STATUS_OFFSET:
0266 case NVSW_SN2201_SYS_INT_MASK_OFFSET:
0267 case NVSW_SN2201_ASIC_STATUS_OFFSET:
0268 case NVSW_SN2201_ASIC_EVENT_OFFSET:
0269 case NVSW_SN2201_ASIC_MAKS_OFFSET:
0270 case NVSW_SN2201_THML_STATUS_OFFSET:
0271 case NVSW_SN2201_THML_EVENT_OFFSET:
0272 case NVSW_SN2201_THML_MASK_OFFSET:
0273 case NVSW_SN2201_PS_ALT_STATUS_OFFSET:
0274 case NVSW_SN2201_PS_ALT_EVENT_OFFSET:
0275 case NVSW_SN2201_PS_ALT_MASK_OFFSET:
0276 case NVSW_SN2201_PS_PRSNT_STATUS_OFFSET:
0277 case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET:
0278 case NVSW_SN2201_PS_PRSNT_MASK_OFFSET:
0279 case NVSW_SN2201_PS_DC_OK_STATUS_OFFSET:
0280 case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET:
0281 case NVSW_SN2201_PS_DC_OK_MASK_OFFSET:
0282 case NVSW_SN2201_RST_SW_CTRL_OFFSET:
0283 case NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET:
0284 case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET:
0285 case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET:
0286 case NVSW_SN2201_WD_TMR_OFFSET_LSB:
0287 case NVSW_SN2201_WD_TMR_OFFSET_MSB:
0288 case NVSW_SN2201_FAN_LED1_CTRL_OFFSET:
0289 case NVSW_SN2201_FAN_LED2_CTRL_OFFSET:
0290 return true;
0291 }
0292 return false;
0293 }
0294
0295 static const struct reg_default nvsw_sn2201_regmap_default[] = {
0296 { NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET, 0x00 },
0297 { NVSW_SN2201_WD_ACT_OFFSET, 0x00 },
0298 };
0299
0300
0301 static const struct regmap_config nvsw_sn2201_regmap_conf = {
0302 .reg_bits = 8,
0303 .val_bits = 8,
0304 .max_register = NVSW_SN2201_REG_MAX,
0305 .cache_type = REGCACHE_FLAT,
0306 .writeable_reg = nvsw_sn2201_writeable_reg,
0307 .readable_reg = nvsw_sn2201_readable_reg,
0308 .volatile_reg = nvsw_sn2201_volatile_reg,
0309 .reg_defaults = nvsw_sn2201_regmap_default,
0310 .num_reg_defaults = ARRAY_SIZE(nvsw_sn2201_regmap_default),
0311 };
0312
0313
0314 static const struct resource nvsw_sn2201_lpc_io_resources[] = {
0315 [0] = DEFINE_RES_NAMED(NVSW_SN2201_CPLD_LPC_I2C_BASE_ADRR,
0316 NVSW_SN2201_CPLD_LPC_IO_RANGE,
0317 "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO),
0318 };
0319
0320 static struct resource nvsw_sn2201_cpld_res[] = {
0321 [0] = DEFINE_RES_IRQ_NAMED(NVSW_SN2201_CPLD_SYSIRQ, "mlxreg-hotplug"),
0322 };
0323
0324 static struct resource nvsw_sn2201_lpc_res[] = {
0325 [0] = DEFINE_RES_IRQ_NAMED(NVSW_SN2201_LPC_SYSIRQ, "i2c-mlxcpld"),
0326 };
0327
0328
0329 static struct mlxreg_core_hotplug_platform_data nvsw_sn2201_i2c_data = {
0330 .irq = NVSW_SN2201_CPLD_SYSIRQ,
0331 };
0332
0333
0334 static struct i2c_board_info nvsw_sn2201_cpld_devices[] = {
0335 {
0336 I2C_BOARD_INFO("nvsw-sn2201", 0x41),
0337 },
0338 };
0339
0340
0341 static struct mlxreg_hotplug_device nvsw_sn2201_cpld_brdinfo[] = {
0342 {
0343 .brdinfo = &nvsw_sn2201_cpld_devices[0],
0344 .nr = NVSW_SN2201_CPLD_NR,
0345 },
0346 };
0347
0348
0349 static struct i2c_board_info nvsw_sn2201_main_mux_devices[] = {
0350 {
0351 I2C_BOARD_INFO("pca9548", 0x70),
0352 },
0353 };
0354
0355
0356 static struct mlxreg_hotplug_device nvsw_sn2201_main_mux_brdinfo[] = {
0357 {
0358 .brdinfo = &nvsw_sn2201_main_mux_devices[0],
0359 .nr = NVSW_SN2201_MAIN_MUX_NR,
0360 },
0361 };
0362
0363
0364 static struct i2c_board_info nvsw_sn2201_pwr_devices[] = {
0365 {
0366 I2C_BOARD_INFO("pmbus", 0x58),
0367 },
0368 {
0369 I2C_BOARD_INFO("pmbus", 0x58),
0370 },
0371 };
0372
0373
0374 static struct i2c_board_info nvsw_sn2201_fan_devices[] = {
0375 {
0376 I2C_BOARD_INFO("24c02", 0x50),
0377 },
0378 {
0379 I2C_BOARD_INFO("24c02", 0x51),
0380 },
0381 {
0382 I2C_BOARD_INFO("24c02", 0x52),
0383 },
0384 {
0385 I2C_BOARD_INFO("24c02", 0x53),
0386 },
0387 };
0388
0389
0390 static struct mlxreg_core_data nvsw_sn2201_psu_items_data[] = {
0391 {
0392 .label = "psu1",
0393 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET,
0394 .mask = BIT(0),
0395 .hpdev.nr = NVSW_SN2201_NR_NONE,
0396 },
0397 {
0398 .label = "psu2",
0399 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET,
0400 .mask = BIT(1),
0401 .hpdev.nr = NVSW_SN2201_NR_NONE,
0402 },
0403 };
0404
0405 static struct mlxreg_core_data nvsw_sn2201_pwr_items_data[] = {
0406 {
0407 .label = "pwr1",
0408 .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET,
0409 .mask = BIT(0),
0410 .hpdev.brdinfo = &nvsw_sn2201_pwr_devices[0],
0411 .hpdev.nr = NVSW_SN2201_MAIN_MUX_CH1_NR,
0412 },
0413 {
0414 .label = "pwr2",
0415 .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET,
0416 .mask = BIT(1),
0417 .hpdev.brdinfo = &nvsw_sn2201_pwr_devices[1],
0418 .hpdev.nr = NVSW_SN2201_MAIN_MUX_CH2_NR,
0419 },
0420 };
0421
0422 static struct mlxreg_core_data nvsw_sn2201_fan_items_data[] = {
0423 {
0424 .label = "fan1",
0425 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET,
0426 .mask = BIT(0),
0427 .hpdev.brdinfo = &nvsw_sn2201_fan_devices[0],
0428 .hpdev.nr = NVSW_SN2201_NR_NONE,
0429 },
0430 {
0431 .label = "fan2",
0432 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET,
0433 .mask = BIT(1),
0434 .hpdev.brdinfo = &nvsw_sn2201_fan_devices[1],
0435 .hpdev.nr = NVSW_SN2201_NR_NONE,
0436 },
0437 {
0438 .label = "fan3",
0439 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET,
0440 .mask = BIT(2),
0441 .hpdev.brdinfo = &nvsw_sn2201_fan_devices[2],
0442 .hpdev.nr = NVSW_SN2201_NR_NONE,
0443 },
0444 {
0445 .label = "fan4",
0446 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET,
0447 .mask = BIT(3),
0448 .hpdev.brdinfo = &nvsw_sn2201_fan_devices[3],
0449 .hpdev.nr = NVSW_SN2201_NR_NONE,
0450 },
0451 };
0452
0453 static struct mlxreg_core_data nvsw_sn2201_sys_items_data[] = {
0454 {
0455 .label = "nic_smb_alert",
0456 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET,
0457 .mask = BIT(1),
0458 .hpdev.nr = NVSW_SN2201_NR_NONE,
0459 },
0460 {
0461 .label = "cpu_sd",
0462 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET,
0463 .mask = BIT(2),
0464 .hpdev.nr = NVSW_SN2201_NR_NONE,
0465 },
0466 {
0467 .label = "mac_health",
0468 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET,
0469 .mask = BIT(3),
0470 .hpdev.nr = NVSW_SN2201_NR_NONE,
0471 },
0472 };
0473
0474 static struct mlxreg_core_item nvsw_sn2201_items[] = {
0475 {
0476 .data = nvsw_sn2201_psu_items_data,
0477 .aggr_mask = NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF,
0478 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET,
0479 .mask = NVSW_SN2201_CPLD_PSU_MASK,
0480 .count = ARRAY_SIZE(nvsw_sn2201_psu_items_data),
0481 .inversed = 1,
0482 .health = false,
0483 },
0484 {
0485 .data = nvsw_sn2201_pwr_items_data,
0486 .aggr_mask = NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF,
0487 .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET,
0488 .mask = NVSW_SN2201_CPLD_PWR_MASK,
0489 .count = ARRAY_SIZE(nvsw_sn2201_pwr_items_data),
0490 .inversed = 0,
0491 .health = false,
0492 },
0493 {
0494 .data = nvsw_sn2201_fan_items_data,
0495 .aggr_mask = NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF,
0496 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET,
0497 .mask = NVSW_SN2201_CPLD_FAN_MASK,
0498 .count = ARRAY_SIZE(nvsw_sn2201_fan_items_data),
0499 .inversed = 1,
0500 .health = false,
0501 },
0502 {
0503 .data = nvsw_sn2201_sys_items_data,
0504 .aggr_mask = NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF,
0505 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET,
0506 .mask = NVSW_SN2201_CPLD_ASIC_MASK,
0507 .count = ARRAY_SIZE(nvsw_sn2201_sys_items_data),
0508 .inversed = 1,
0509 .health = false,
0510 },
0511 };
0512
0513 static
0514 struct mlxreg_core_hotplug_platform_data nvsw_sn2201_hotplug = {
0515 .items = nvsw_sn2201_items,
0516 .counter = ARRAY_SIZE(nvsw_sn2201_items),
0517 .cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET,
0518 .mask = NVSW_SN2201_CPLD_AGGR_MASK_DEF,
0519 };
0520
0521
0522 static struct i2c_board_info nvsw_sn2201_static_devices[] = {
0523 {
0524 I2C_BOARD_INFO("24c02", 0x57),
0525 },
0526 {
0527 I2C_BOARD_INFO("lm75", 0x4b),
0528 },
0529 {
0530 I2C_BOARD_INFO("24c64", 0x56),
0531 },
0532 {
0533 I2C_BOARD_INFO("ads1015", 0x49),
0534 },
0535 {
0536 I2C_BOARD_INFO("pca9546", 0x71),
0537 },
0538 {
0539 I2C_BOARD_INFO("emc2305", 0x4d),
0540 },
0541 {
0542 I2C_BOARD_INFO("lm75", 0x49),
0543 },
0544 {
0545 I2C_BOARD_INFO("pca9555", 0x27),
0546 },
0547 {
0548 I2C_BOARD_INFO("powr1014", 0x37),
0549 },
0550 {
0551 I2C_BOARD_INFO("lm75", 0x4f),
0552 },
0553 {
0554 I2C_BOARD_INFO("pmbus", 0x40),
0555 },
0556 };
0557
0558
0559 static struct mlxreg_hotplug_device nvsw_sn2201_static_brdinfo[] = {
0560 {
0561 .brdinfo = &nvsw_sn2201_static_devices[0],
0562 .nr = NVSW_SN2201_MAIN_NR,
0563 },
0564 {
0565 .brdinfo = &nvsw_sn2201_static_devices[1],
0566 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
0567 },
0568 {
0569 .brdinfo = &nvsw_sn2201_static_devices[2],
0570 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
0571 },
0572 {
0573 .brdinfo = &nvsw_sn2201_static_devices[3],
0574 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR,
0575 },
0576 {
0577 .brdinfo = &nvsw_sn2201_static_devices[4],
0578 .nr = NVSW_SN2201_MAIN_MUX_CH3_NR,
0579 },
0580 {
0581 .brdinfo = &nvsw_sn2201_static_devices[5],
0582 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
0583 },
0584 {
0585 .brdinfo = &nvsw_sn2201_static_devices[6],
0586 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
0587 },
0588 {
0589 .brdinfo = &nvsw_sn2201_static_devices[7],
0590 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR,
0591 },
0592 {
0593 .brdinfo = &nvsw_sn2201_static_devices[8],
0594 .nr = NVSW_SN2201_MAIN_MUX_CH6_NR,
0595 },
0596 {
0597 .brdinfo = &nvsw_sn2201_static_devices[9],
0598 .nr = NVSW_SN2201_MAIN_MUX_CH6_NR,
0599 },
0600 {
0601 .brdinfo = &nvsw_sn2201_static_devices[10],
0602 .nr = NVSW_SN2201_MAIN_MUX_CH7_NR,
0603 },
0604 };
0605
0606
0607 static struct mlxreg_core_data nvsw_sn2201_led_data[] = {
0608 {
0609 .label = "status:green",
0610 .reg = NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET,
0611 .mask = GENMASK(7, 4),
0612 },
0613 {
0614 .label = "status:orange",
0615 .reg = NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET,
0616 .mask = GENMASK(7, 4),
0617 },
0618 {
0619 .label = "psu:green",
0620 .reg = NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET,
0621 .mask = GENMASK(7, 4),
0622 },
0623 {
0624 .label = "psu:orange",
0625 .reg = NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET,
0626 .mask = GENMASK(7, 4),
0627 },
0628 {
0629 .label = "uid:blue",
0630 .reg = NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET,
0631 .mask = GENMASK(7, 4),
0632 },
0633 {
0634 .label = "fan1:green",
0635 .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET,
0636 .mask = GENMASK(7, 4),
0637 },
0638 {
0639 .label = "fan1:orange",
0640 .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET,
0641 .mask = GENMASK(7, 4),
0642 },
0643 {
0644 .label = "fan2:green",
0645 .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET,
0646 .mask = GENMASK(3, 0),
0647 },
0648 {
0649 .label = "fan2:orange",
0650 .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET,
0651 .mask = GENMASK(3, 0),
0652 },
0653 {
0654 .label = "fan3:green",
0655 .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET,
0656 .mask = GENMASK(7, 4),
0657 },
0658 {
0659 .label = "fan3:orange",
0660 .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET,
0661 .mask = GENMASK(7, 4),
0662 },
0663 {
0664 .label = "fan4:green",
0665 .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET,
0666 .mask = GENMASK(3, 0),
0667 },
0668 {
0669 .label = "fan4:orange",
0670 .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET,
0671 .mask = GENMASK(3, 0),
0672 },
0673 };
0674
0675 static struct mlxreg_core_platform_data nvsw_sn2201_led = {
0676 .data = nvsw_sn2201_led_data,
0677 .counter = ARRAY_SIZE(nvsw_sn2201_led_data),
0678 };
0679
0680
0681 static struct mlxreg_core_data nvsw_sn2201_io_data[] = {
0682 {
0683 .label = "cpld1_version",
0684 .reg = NVSW_SN2201_CPLD_VER_OFFSET,
0685 .bit = GENMASK(7, 0),
0686 .mode = 0444,
0687 },
0688 {
0689 .label = "cpld1_version_min",
0690 .reg = NVSW_SN2201_CPLD_MVER_OFFSET,
0691 .bit = GENMASK(7, 0),
0692 .mode = 0444,
0693 },
0694 {
0695 .label = "cpld1_pn",
0696 .reg = NVSW_SN2201_CPLD_PN_OFFSET,
0697 .bit = GENMASK(15, 0),
0698 .mode = 0444,
0699 .regnum = 2,
0700 },
0701 {
0702 .label = "psu1_on",
0703 .reg = NVSW_SN2201_PSU_CTRL_OFFSET,
0704 .mask = GENMASK(7, 0) & ~BIT(0),
0705 .mode = 0644,
0706 },
0707 {
0708 .label = "psu2_on",
0709 .reg = NVSW_SN2201_PSU_CTRL_OFFSET,
0710 .mask = GENMASK(7, 0) & ~BIT(1),
0711 .mode = 0644,
0712 },
0713 {
0714 .label = "pwr_cycle",
0715 .reg = NVSW_SN2201_PSU_CTRL_OFFSET,
0716 .mask = GENMASK(7, 0) & ~BIT(2),
0717 .mode = 0644,
0718 },
0719 {
0720 .label = "asic_health",
0721 .reg = NVSW_SN2201_SYS_STATUS_OFFSET,
0722 .mask = GENMASK(4, 3),
0723 .bit = 4,
0724 .mode = 0444,
0725 },
0726 {
0727 .label = "qsfp_pwr_good",
0728 .reg = NVSW_SN2201_SYS_STATUS_OFFSET,
0729 .mask = GENMASK(7, 0) & ~BIT(0),
0730 .mode = 0444,
0731 },
0732 {
0733 .label = "phy_reset",
0734 .reg = NVSW_SN2201_SYS_RST_STATUS_OFFSET,
0735 .mask = GENMASK(7, 0) & ~BIT(3),
0736 .mode = 0644,
0737 },
0738 {
0739 .label = "mac_reset",
0740 .reg = NVSW_SN2201_SYS_RST_STATUS_OFFSET,
0741 .mask = GENMASK(7, 0) & ~BIT(2),
0742 .mode = 0644,
0743 },
0744 {
0745 .label = "pwr_down",
0746 .reg = NVSW_SN2201_RST_SW_CTRL_OFFSET,
0747 .mask = GENMASK(7, 0) & ~BIT(0),
0748 .mode = 0644,
0749 },
0750 {
0751 .label = "reset_long_pb",
0752 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0753 .mask = GENMASK(7, 0) & ~BIT(0),
0754 .mode = 0444,
0755 },
0756 {
0757 .label = "reset_short_pb",
0758 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0759 .mask = GENMASK(7, 0) & ~BIT(1),
0760 .mode = 0444,
0761 },
0762 {
0763 .label = "reset_aux_pwr_or_fu",
0764 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0765 .mask = GENMASK(7, 0) & ~BIT(2),
0766 .mode = 0444,
0767 },
0768 {
0769 .label = "reset_swb_dc_dc_pwr_fail",
0770 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0771 .mask = GENMASK(7, 0) & ~BIT(3),
0772 .mode = 0444,
0773 },
0774 {
0775 .label = "reset_sw_reset",
0776 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0777 .mask = GENMASK(7, 0) & ~BIT(4),
0778 .mode = 0444,
0779 },
0780 {
0781 .label = "reset_fw_reset",
0782 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0783 .mask = GENMASK(7, 0) & ~BIT(5),
0784 .mode = 0444,
0785 },
0786 {
0787 .label = "reset_swb_wd",
0788 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0789 .mask = GENMASK(7, 0) & ~BIT(6),
0790 .mode = 0444,
0791 },
0792 {
0793 .label = "reset_asic_thermal",
0794 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0795 .mask = GENMASK(7, 0) & ~BIT(7),
0796 .mode = 0444,
0797 },
0798 {
0799 .label = "reset_system",
0800 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET,
0801 .mask = GENMASK(7, 0) & ~BIT(1),
0802 .mode = 0444,
0803 },
0804 {
0805 .label = "reset_sw_pwr_off",
0806 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET,
0807 .mask = GENMASK(7, 0) & ~BIT(2),
0808 .mode = 0444,
0809 },
0810 {
0811 .label = "reset_cpu_pwr_fail_thermal",
0812 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET,
0813 .mask = GENMASK(7, 0) & ~BIT(4),
0814 .mode = 0444,
0815 },
0816 {
0817 .label = "reset_reload_bios",
0818 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET,
0819 .mask = GENMASK(7, 0) & ~BIT(5),
0820 .mode = 0444,
0821 },
0822 {
0823 .label = "reset_ac_pwr_fail",
0824 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET,
0825 .mask = GENMASK(7, 0) & ~BIT(6),
0826 .mode = 0444,
0827 },
0828 {
0829 .label = "psu1",
0830 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET,
0831 .mask = GENMASK(7, 0) & ~BIT(0),
0832 .mode = 0444,
0833 },
0834 {
0835 .label = "psu2",
0836 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET,
0837 .mask = GENMASK(7, 0) & ~BIT(1),
0838 .mode = 0444,
0839 },
0840 };
0841
0842 static struct mlxreg_core_platform_data nvsw_sn2201_regs_io = {
0843 .data = nvsw_sn2201_io_data,
0844 .counter = ARRAY_SIZE(nvsw_sn2201_io_data),
0845 };
0846
0847
0848 static struct mlxreg_core_data nvsw_sn2201_wd_data[] = {
0849 {
0850 .label = "action",
0851 .reg = NVSW_SN2201_WD_ACT_OFFSET,
0852 .mask = GENMASK(7, 1),
0853 .bit = 0,
0854 },
0855 {
0856 .label = "timeout",
0857 .reg = NVSW_SN2201_WD_TMR_OFFSET_LSB,
0858 .mask = 0,
0859 .health_cntr = NVSW_SN2201_WD_DFLT_TIMEOUT,
0860 },
0861 {
0862 .label = "timeleft",
0863 .reg = NVSW_SN2201_WD_TMR_OFFSET_LSB,
0864 .mask = 0,
0865 },
0866 {
0867 .label = "ping",
0868 .reg = NVSW_SN2201_WD_ACT_OFFSET,
0869 .mask = GENMASK(7, 1),
0870 .bit = 0,
0871 },
0872 {
0873 .label = "reset",
0874 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET,
0875 .mask = GENMASK(7, 0) & ~BIT(6),
0876 .bit = 6,
0877 },
0878 };
0879
0880 static struct mlxreg_core_platform_data nvsw_sn2201_wd = {
0881 .data = nvsw_sn2201_wd_data,
0882 .counter = ARRAY_SIZE(nvsw_sn2201_wd_data),
0883 .version = MLX_WDT_TYPE3,
0884 .identity = "mlx-wdt-main",
0885 };
0886
0887 static int
0888 nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201,
0889 struct mlxreg_hotplug_device *devs,
0890 int size)
0891 {
0892 struct mlxreg_hotplug_device *dev = devs;
0893 int ret;
0894 int i;
0895
0896
0897 for (i = 0; i < size; i++, dev++) {
0898 dev->client = i2c_new_client_device(dev->adapter, dev->brdinfo);
0899 if (IS_ERR(dev->client)) {
0900 dev_err(nvsw_sn2201->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
0901 dev->brdinfo->type,
0902 dev->nr, dev->brdinfo->addr);
0903
0904 dev->adapter = NULL;
0905 ret = PTR_ERR(dev->client);
0906 goto fail_create_static_devices;
0907 }
0908 }
0909
0910 return 0;
0911
0912 fail_create_static_devices:
0913 while (--i >= 0) {
0914 dev = devs + i;
0915 i2c_unregister_device(dev->client);
0916 dev->client = NULL;
0917 dev->adapter = NULL;
0918 }
0919 return ret;
0920 }
0921
0922 static void nvsw_sn2201_destroy_static_devices(struct nvsw_sn2201 *nvsw_sn2201,
0923 struct mlxreg_hotplug_device *devs, int size)
0924 {
0925 struct mlxreg_hotplug_device *dev = devs;
0926 int i;
0927
0928
0929 for (i = 0; i < size; i++, dev++) {
0930 if (dev->client) {
0931 i2c_unregister_device(dev->client);
0932 dev->client = NULL;
0933 i2c_put_adapter(dev->adapter);
0934 dev->adapter = NULL;
0935 }
0936 }
0937 }
0938
0939 static int nvsw_sn2201_config_post_init(struct nvsw_sn2201 *nvsw_sn2201)
0940 {
0941 struct mlxreg_hotplug_device *sn2201_dev;
0942 struct i2c_adapter *adap;
0943 struct device *dev;
0944 int i, err;
0945
0946 dev = nvsw_sn2201->dev;
0947 adap = i2c_get_adapter(nvsw_sn2201->main_mux_deferred_nr);
0948 if (!adap) {
0949 dev_err(dev, "Failed to get adapter for bus %d\n",
0950 nvsw_sn2201->main_mux_deferred_nr);
0951 return -ENODEV;
0952 }
0953 i2c_put_adapter(adap);
0954
0955
0956 sn2201_dev = nvsw_sn2201->sn2201_devs;
0957 for (i = 0; i < nvsw_sn2201->sn2201_devs_num; i++, sn2201_dev++) {
0958 sn2201_dev->adapter = i2c_get_adapter(sn2201_dev->nr);
0959 if (!sn2201_dev->adapter)
0960 return -ENODEV;
0961 i2c_put_adapter(sn2201_dev->adapter);
0962 }
0963
0964 err = nvsw_sn2201_create_static_devices(nvsw_sn2201, nvsw_sn2201->sn2201_devs,
0965 nvsw_sn2201->sn2201_devs_num);
0966 if (err)
0967 dev_err(dev, "Failed to create static devices\n");
0968
0969 return err;
0970 }
0971
0972 static int nvsw_sn2201_config_init(struct nvsw_sn2201 *nvsw_sn2201, void *regmap)
0973 {
0974 struct device *dev = nvsw_sn2201->dev;
0975 int err;
0976
0977 nvsw_sn2201->io_data = &nvsw_sn2201_regs_io;
0978 nvsw_sn2201->led_data = &nvsw_sn2201_led;
0979 nvsw_sn2201->wd_data = &nvsw_sn2201_wd;
0980 nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug;
0981
0982
0983 if (nvsw_sn2201->io_data) {
0984 nvsw_sn2201->io_data->regmap = regmap;
0985 nvsw_sn2201->io_regs =
0986 platform_device_register_resndata(dev, "mlxreg-io", PLATFORM_DEVID_NONE, NULL, 0,
0987 nvsw_sn2201->io_data,
0988 sizeof(*nvsw_sn2201->io_data));
0989 if (IS_ERR(nvsw_sn2201->io_regs)) {
0990 err = PTR_ERR(nvsw_sn2201->io_regs);
0991 goto fail_register_io;
0992 }
0993 }
0994
0995
0996 if (nvsw_sn2201->led_data) {
0997 nvsw_sn2201->led_data->regmap = regmap;
0998 nvsw_sn2201->led =
0999 platform_device_register_resndata(dev, "leds-mlxreg", PLATFORM_DEVID_NONE, NULL, 0,
1000 nvsw_sn2201->led_data,
1001 sizeof(*nvsw_sn2201->led_data));
1002 if (IS_ERR(nvsw_sn2201->led)) {
1003 err = PTR_ERR(nvsw_sn2201->led);
1004 goto fail_register_led;
1005 }
1006 }
1007
1008
1009 if (nvsw_sn2201->wd_data) {
1010 nvsw_sn2201->wd_data->regmap = regmap;
1011 nvsw_sn2201->wd =
1012 platform_device_register_resndata(dev, "mlx-wdt", PLATFORM_DEVID_NONE, NULL, 0,
1013 nvsw_sn2201->wd_data,
1014 sizeof(*nvsw_sn2201->wd_data));
1015 if (IS_ERR(nvsw_sn2201->wd)) {
1016 err = PTR_ERR(nvsw_sn2201->wd);
1017 goto fail_register_wd;
1018 }
1019 }
1020
1021
1022 if (nvsw_sn2201->hotplug_data) {
1023 nvsw_sn2201->hotplug_data->regmap = regmap;
1024 nvsw_sn2201->pdev_hotplug =
1025 platform_device_register_resndata(dev, "mlxreg-hotplug", PLATFORM_DEVID_NONE,
1026 nvsw_sn2201_cpld_res,
1027 ARRAY_SIZE(nvsw_sn2201_cpld_res),
1028 nvsw_sn2201->hotplug_data,
1029 sizeof(*nvsw_sn2201->hotplug_data));
1030 if (IS_ERR(nvsw_sn2201->pdev_hotplug)) {
1031 err = PTR_ERR(nvsw_sn2201->pdev_hotplug);
1032 goto fail_register_hotplug;
1033 }
1034 }
1035
1036 return nvsw_sn2201_config_post_init(nvsw_sn2201);
1037
1038 fail_register_hotplug:
1039 if (nvsw_sn2201->wd)
1040 platform_device_unregister(nvsw_sn2201->wd);
1041 fail_register_wd:
1042 if (nvsw_sn2201->led)
1043 platform_device_unregister(nvsw_sn2201->led);
1044 fail_register_led:
1045 if (nvsw_sn2201->io_regs)
1046 platform_device_unregister(nvsw_sn2201->io_regs);
1047 fail_register_io:
1048
1049 return err;
1050 }
1051
1052 static void nvsw_sn2201_config_exit(struct nvsw_sn2201 *nvsw_sn2201)
1053 {
1054
1055 if (nvsw_sn2201->pdev_hotplug)
1056 platform_device_unregister(nvsw_sn2201->pdev_hotplug);
1057
1058 if (nvsw_sn2201->wd)
1059 platform_device_unregister(nvsw_sn2201->wd);
1060
1061 if (nvsw_sn2201->led)
1062 platform_device_unregister(nvsw_sn2201->led);
1063
1064 if (nvsw_sn2201->io_regs)
1065 platform_device_unregister(nvsw_sn2201->io_regs);
1066 }
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076 static int nvsw_sn2201_i2c_completion_notify(void *handle, int id)
1077 {
1078 struct nvsw_sn2201 *nvsw_sn2201 = handle;
1079 void *regmap;
1080 int i, err;
1081
1082
1083 nvsw_sn2201->main_mux_devs->adapter = i2c_get_adapter(nvsw_sn2201->main_mux_devs->nr);
1084 if (!nvsw_sn2201->main_mux_devs->adapter) {
1085 err = -ENODEV;
1086 dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n",
1087 nvsw_sn2201->cpld_devs->nr);
1088 goto i2c_get_adapter_main_fail;
1089 }
1090
1091 nvsw_sn2201->main_mux_devs_num = ARRAY_SIZE(nvsw_sn2201_main_mux_brdinfo);
1092 err = nvsw_sn2201_create_static_devices(nvsw_sn2201, nvsw_sn2201->main_mux_devs,
1093 nvsw_sn2201->main_mux_devs_num);
1094 if (err) {
1095 dev_err(nvsw_sn2201->dev, "Failed to create main mux devices\n");
1096 goto nvsw_sn2201_create_static_devices_fail;
1097 }
1098
1099 nvsw_sn2201->cpld_devs->adapter = i2c_get_adapter(nvsw_sn2201->cpld_devs->nr);
1100 if (!nvsw_sn2201->cpld_devs->adapter) {
1101 err = -ENODEV;
1102 dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n",
1103 nvsw_sn2201->cpld_devs->nr);
1104 goto i2c_get_adapter_fail;
1105 }
1106
1107
1108 nvsw_sn2201->cpld_devs->client = i2c_new_dummy_device(nvsw_sn2201->cpld_devs->adapter,
1109 NVSW_SN2201_CPLD_I2CADDR);
1110 if (IS_ERR(nvsw_sn2201->cpld_devs->client)) {
1111 err = PTR_ERR(nvsw_sn2201->cpld_devs->client);
1112 dev_err(nvsw_sn2201->dev, "Failed to create %s cpld device at bus %d at addr 0x%02x\n",
1113 nvsw_sn2201->cpld_devs->brdinfo->type, nvsw_sn2201->cpld_devs->nr,
1114 nvsw_sn2201->cpld_devs->brdinfo->addr);
1115 goto i2c_new_dummy_fail;
1116 }
1117
1118 regmap = devm_regmap_init_i2c(nvsw_sn2201->cpld_devs->client, &nvsw_sn2201_regmap_conf);
1119 if (IS_ERR(regmap)) {
1120 err = PTR_ERR(regmap);
1121 dev_err(nvsw_sn2201->dev, "Failed to initialise managed register map\n");
1122 goto devm_regmap_init_i2c_fail;
1123 }
1124
1125
1126 for (i = 0; i < nvsw_sn2201_regmap_conf.num_reg_defaults; i++) {
1127 err = regmap_write(regmap, nvsw_sn2201_regmap_default[i].reg,
1128 nvsw_sn2201_regmap_default[i].def);
1129 if (err) {
1130 dev_err(nvsw_sn2201->dev, "Failed to set register at offset 0x%02x to default value: 0x%02x\n",
1131 nvsw_sn2201_regmap_default[i].reg,
1132 nvsw_sn2201_regmap_default[i].def);
1133 goto regmap_write_fail;
1134 }
1135 }
1136
1137
1138 regcache_mark_dirty(regmap);
1139 err = regcache_sync(regmap);
1140 if (err) {
1141 dev_err(nvsw_sn2201->dev, "Failed to Sync registers with hardware\n");
1142 goto regcache_sync_fail;
1143 }
1144
1145
1146 err = nvsw_sn2201_config_init(nvsw_sn2201, regmap);
1147 if (err) {
1148 dev_err(nvsw_sn2201->dev, "Failed to configure board\n");
1149 goto nvsw_sn2201_config_init_fail;
1150 }
1151
1152 return 0;
1153
1154 nvsw_sn2201_config_init_fail:
1155 nvsw_sn2201_config_exit(nvsw_sn2201);
1156 regcache_sync_fail:
1157 regmap_write_fail:
1158 devm_regmap_init_i2c_fail:
1159 i2c_new_dummy_fail:
1160 i2c_put_adapter(nvsw_sn2201->cpld_devs->adapter);
1161 nvsw_sn2201->cpld_devs->adapter = NULL;
1162 i2c_get_adapter_fail:
1163
1164 nvsw_sn2201_destroy_static_devices(nvsw_sn2201, nvsw_sn2201->sn2201_devs,
1165 nvsw_sn2201->sn2201_devs_num);
1166
1167 nvsw_sn2201_destroy_static_devices(nvsw_sn2201, nvsw_sn2201->main_mux_devs,
1168 nvsw_sn2201->main_mux_devs_num);
1169 nvsw_sn2201_create_static_devices_fail:
1170 i2c_put_adapter(nvsw_sn2201->main_mux_devs->adapter);
1171 i2c_get_adapter_main_fail:
1172 return err;
1173 }
1174
1175 static int nvsw_sn2201_config_pre_init(struct nvsw_sn2201 *nvsw_sn2201)
1176 {
1177 nvsw_sn2201->i2c_data = &nvsw_sn2201_i2c_data;
1178
1179
1180 nvsw_sn2201->i2c_data->handle = nvsw_sn2201;
1181 nvsw_sn2201->i2c_data->completion_notify = nvsw_sn2201_i2c_completion_notify;
1182 nvsw_sn2201->pdev_i2c = platform_device_register_resndata(nvsw_sn2201->dev, "i2c_mlxcpld",
1183 NVSW_SN2201_MAIN_MUX_NR,
1184 nvsw_sn2201_lpc_res,
1185 ARRAY_SIZE(nvsw_sn2201_lpc_res),
1186 nvsw_sn2201->i2c_data,
1187 sizeof(*nvsw_sn2201->i2c_data));
1188 if (IS_ERR(nvsw_sn2201->pdev_i2c))
1189 return PTR_ERR(nvsw_sn2201->pdev_i2c);
1190
1191 return 0;
1192 }
1193
1194 static int nvsw_sn2201_probe(struct platform_device *pdev)
1195 {
1196 struct nvsw_sn2201 *nvsw_sn2201;
1197
1198 nvsw_sn2201 = devm_kzalloc(&pdev->dev, sizeof(*nvsw_sn2201), GFP_KERNEL);
1199 if (!nvsw_sn2201)
1200 return -ENOMEM;
1201
1202 nvsw_sn2201->dev = &pdev->dev;
1203 platform_set_drvdata(pdev, nvsw_sn2201);
1204 platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources,
1205 ARRAY_SIZE(nvsw_sn2201_lpc_io_resources));
1206
1207 nvsw_sn2201->main_mux_deferred_nr = NVSW_SN2201_MAIN_MUX_DEFER_NR;
1208 nvsw_sn2201->main_mux_devs = nvsw_sn2201_main_mux_brdinfo;
1209 nvsw_sn2201->cpld_devs = nvsw_sn2201_cpld_brdinfo;
1210 nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo;
1211 nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo);
1212
1213 return nvsw_sn2201_config_pre_init(nvsw_sn2201);
1214 }
1215
1216 static int nvsw_sn2201_remove(struct platform_device *pdev)
1217 {
1218 struct nvsw_sn2201 *nvsw_sn2201 = platform_get_drvdata(pdev);
1219
1220
1221 nvsw_sn2201_config_exit(nvsw_sn2201);
1222
1223
1224 nvsw_sn2201_destroy_static_devices(nvsw_sn2201,
1225 nvsw_sn2201->sn2201_devs,
1226 nvsw_sn2201->sn2201_devs_num);
1227
1228 i2c_put_adapter(nvsw_sn2201->cpld_devs->adapter);
1229 nvsw_sn2201->cpld_devs->adapter = NULL;
1230
1231 nvsw_sn2201_destroy_static_devices(nvsw_sn2201,
1232 nvsw_sn2201->main_mux_devs,
1233 nvsw_sn2201->main_mux_devs_num);
1234
1235
1236 if (nvsw_sn2201->pdev_i2c)
1237 platform_device_unregister(nvsw_sn2201->pdev_i2c);
1238
1239 return 0;
1240 }
1241
1242 static const struct acpi_device_id nvsw_sn2201_acpi_ids[] = {
1243 {"NVSN2201", 0},
1244 {}
1245 };
1246
1247 MODULE_DEVICE_TABLE(acpi, nvsw_sn2201_acpi_ids);
1248
1249 static struct platform_driver nvsw_sn2201_driver = {
1250 .probe = nvsw_sn2201_probe,
1251 .remove = nvsw_sn2201_remove,
1252 .driver = {
1253 .name = "nvsw-sn2201",
1254 .acpi_match_table = nvsw_sn2201_acpi_ids,
1255 },
1256 };
1257
1258 module_platform_driver(nvsw_sn2201_driver);
1259
1260 MODULE_AUTHOR("Nvidia");
1261 MODULE_DESCRIPTION("Nvidia sn2201 platform driver");
1262 MODULE_LICENSE("Dual BSD/GPL");
1263 MODULE_ALIAS("platform:nvsw-sn2201");