1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Nvidia sn2201 driver 4 * 5 * Copyright (C) 2022 Nvidia Technologies Ltd. 6 */ 7 8 #include <linux/device.h> 9 #include <linux/dmi.h> 10 #include <linux/i2c.h> 11 #include <linux/interrupt.h> 12 #include <linux/irq.h> 13 #include <linux/gpio.h> 14 #include <linux/module.h> 15 #include <linux/platform_data/mlxcpld.h> 16 #include <linux/platform_data/mlxreg.h> 17 #include <linux/platform_device.h> 18 #include <linux/regmap.h> 19 20 /* SN2201 CPLD register offset. */ 21 #define NVSW_SN2201_CPLD_LPC_I2C_BASE_ADRR 0x2000 22 #define NVSW_SN2201_CPLD_LPC_IO_RANGE 0x100 23 #define NVSW_SN2201_HW_VER_ID_OFFSET 0x00 24 #define NVSW_SN2201_BOARD_ID_OFFSET 0x01 25 #define NVSW_SN2201_CPLD_VER_OFFSET 0x02 26 #define NVSW_SN2201_CPLD_MVER_OFFSET 0x03 27 #define NVSW_SN2201_CPLD_ID_OFFSET 0x04 28 #define NVSW_SN2201_CPLD_PN_OFFSET 0x05 29 #define NVSW_SN2201_CPLD_PN1_OFFSET 0x06 30 #define NVSW_SN2201_PSU_CTRL_OFFSET 0x0a 31 #define NVSW_SN2201_QSFP28_STATUS_OFFSET 0x0b 32 #define NVSW_SN2201_QSFP28_INT_STATUS_OFFSET 0x0c 33 #define NVSW_SN2201_QSFP28_LP_STATUS_OFFSET 0x0d 34 #define NVSW_SN2201_QSFP28_RST_STATUS_OFFSET 0x0e 35 #define NVSW_SN2201_SYS_STATUS_OFFSET 0x0f 36 #define NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET 0x10 37 #define NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET 0x12 38 #define NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET 0x13 39 #define NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET 0x14 40 #define NVSW_SN2201_SYS_RST_STATUS_OFFSET 0x15 41 #define NVSW_SN2201_SYS_INT_STATUS_OFFSET 0x21 42 #define NVSW_SN2201_SYS_INT_MASK_OFFSET 0x22 43 #define NVSW_SN2201_ASIC_STATUS_OFFSET 0x24 44 #define NVSW_SN2201_ASIC_EVENT_OFFSET 0x25 45 #define NVSW_SN2201_ASIC_MAKS_OFFSET 0x26 46 #define NVSW_SN2201_THML_STATUS_OFFSET 0x27 47 #define NVSW_SN2201_THML_EVENT_OFFSET 0x28 48 #define NVSW_SN2201_THML_MASK_OFFSET 0x29 49 #define NVSW_SN2201_PS_ALT_STATUS_OFFSET 0x2a 50 #define NVSW_SN2201_PS_ALT_EVENT_OFFSET 0x2b 51 #define NVSW_SN2201_PS_ALT_MASK_OFFSET 0x2c 52 #define NVSW_SN2201_PS_PRSNT_STATUS_OFFSET 0x30 53 #define NVSW_SN2201_PS_PRSNT_EVENT_OFFSET 0x31 54 #define NVSW_SN2201_PS_PRSNT_MASK_OFFSET 0x32 55 #define NVSW_SN2201_PS_DC_OK_STATUS_OFFSET 0x33 56 #define NVSW_SN2201_PS_DC_OK_EVENT_OFFSET 0x34 57 #define NVSW_SN2201_PS_DC_OK_MASK_OFFSET 0x35 58 #define NVSW_SN2201_RST_CAUSE1_OFFSET 0x36 59 #define NVSW_SN2201_RST_CAUSE2_OFFSET 0x37 60 #define NVSW_SN2201_RST_SW_CTRL_OFFSET 0x38 61 #define NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET 0x3a 62 #define NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET 0x3b 63 #define NVSW_SN2201_FAN_PRSNT_MASK_OFFSET 0x3c 64 #define NVSW_SN2201_WD_TMR_OFFSET_LSB 0x40 65 #define NVSW_SN2201_WD_TMR_OFFSET_MSB 0x41 66 #define NVSW_SN2201_WD_ACT_OFFSET 0x42 67 #define NVSW_SN2201_FAN_LED1_CTRL_OFFSET 0x50 68 #define NVSW_SN2201_FAN_LED2_CTRL_OFFSET 0x51 69 #define NVSW_SN2201_REG_MAX 0x52 70 71 /* Number of physical I2C busses. */ 72 #define NVSW_SN2201_PHY_I2C_BUS_NUM 2 73 /* Number of main mux channels. */ 74 #define NVSW_SN2201_MAIN_MUX_CHNL_NUM 8 75 76 #define NVSW_SN2201_MAIN_NR 0 77 #define NVSW_SN2201_MAIN_MUX_NR 1 78 #define NVSW_SN2201_MAIN_MUX_DEFER_NR (NVSW_SN2201_PHY_I2C_BUS_NUM + \ 79 NVSW_SN2201_MAIN_MUX_CHNL_NUM - 1) 80 81 #define NVSW_SN2201_MAIN_MUX_CH0_NR NVSW_SN2201_PHY_I2C_BUS_NUM 82 #define NVSW_SN2201_MAIN_MUX_CH1_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 1) 83 #define NVSW_SN2201_MAIN_MUX_CH2_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 2) 84 #define NVSW_SN2201_MAIN_MUX_CH3_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 3) 85 #define NVSW_SN2201_MAIN_MUX_CH5_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 5) 86 #define NVSW_SN2201_MAIN_MUX_CH6_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 6) 87 #define NVSW_SN2201_MAIN_MUX_CH7_NR (NVSW_SN2201_MAIN_MUX_CH0_NR + 7) 88 #define NVSW_SN2201_2ND_MUX_CH0_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 1) 89 #define NVSW_SN2201_2ND_MUX_CH1_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 2) 90 #define NVSW_SN2201_2ND_MUX_CH2_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 3) 91 #define NVSW_SN2201_2ND_MUX_CH3_NR (NVSW_SN2201_MAIN_MUX_CH7_NR + 4) 92 93 #define NVSW_SN2201_CPLD_NR NVSW_SN2201_MAIN_MUX_CH0_NR 94 #define NVSW_SN2201_NR_NONE -1 95 96 /* Masks for aggregation, PSU presence and power, ASIC events 97 * in CPLD related registers. 98 */ 99 #define NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF 0xe0 100 #define NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF 0x04 101 #define NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF 0x02 102 #define NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF 0x10 103 #define NVSW_SN2201_CPLD_AGGR_MASK_DEF \ 104 (NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF \ 105 | NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF \ 106 | NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF \ 107 | NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF) 108 #define NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF \ 109 (NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF \ 110 | NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF) 111 112 #define NVSW_SN2201_CPLD_ASIC_MASK GENMASK(3, 1) 113 #define NVSW_SN2201_CPLD_PSU_MASK GENMASK(1, 0) 114 #define NVSW_SN2201_CPLD_PWR_MASK GENMASK(1, 0) 115 #define NVSW_SN2201_CPLD_FAN_MASK GENMASK(3, 0) 116 117 #define NVSW_SN2201_CPLD_SYSIRQ 26 118 #define NVSW_SN2201_LPC_SYSIRQ 28 119 #define NVSW_SN2201_CPLD_I2CADDR 0x41 120 121 #define NVSW_SN2201_WD_DFLT_TIMEOUT 600 122 123 /* nvsw_sn2201 - device private data 124 * @dev: platform device; 125 * @io_data: register access platform data; 126 * @led_data: LED platform data; 127 * @hotplug_data: hotplug platform data; 128 * @i2c_data: I2C controller platform data; 129 * @led: LED device; 130 * @io_regs: register access device; 131 * @pdev_hotplug: hotplug device; 132 * @sn2201_devs: I2C devices for sn2201 devices; 133 * @sn2201_devs_num: number of I2C devices for sn2201 device; 134 * @main_mux_devs: I2C devices for main mux; 135 * @main_mux_devs_num: number of I2C devices for main mux; 136 * @cpld_devs: I2C devices for cpld; 137 * @cpld_devs_num: number of I2C devices for cpld; 138 * @main_mux_deferred_nr: I2C adapter number must be exist prior creating devices execution; 139 * @ext_pwr_source: true if system powered by external power supply; false - by internal; 140 */ 141 struct nvsw_sn2201 { 142 struct device *dev; 143 struct mlxreg_core_platform_data *io_data; 144 struct mlxreg_core_platform_data *led_data; 145 struct mlxreg_core_platform_data *wd_data; 146 struct mlxreg_core_hotplug_platform_data *hotplug_data; 147 struct mlxreg_core_hotplug_platform_data *i2c_data; 148 struct platform_device *led; 149 struct platform_device *wd; 150 struct platform_device *io_regs; 151 struct platform_device *pdev_hotplug; 152 struct platform_device *pdev_i2c; 153 struct mlxreg_hotplug_device *sn2201_devs; 154 int sn2201_devs_num; 155 struct mlxreg_hotplug_device *main_mux_devs; 156 int main_mux_devs_num; 157 struct mlxreg_hotplug_device *cpld_devs; 158 int cpld_devs_num; 159 int main_mux_deferred_nr; 160 bool ext_pwr_source; 161 }; 162 163 static bool nvsw_sn2201_writeable_reg(struct device *dev, unsigned int reg) 164 { 165 switch (reg) { 166 case NVSW_SN2201_PSU_CTRL_OFFSET: 167 case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET: 168 case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET: 169 case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET: 170 case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET: 171 case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET: 172 case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET: 173 case NVSW_SN2201_SYS_RST_STATUS_OFFSET: 174 case NVSW_SN2201_SYS_INT_MASK_OFFSET: 175 case NVSW_SN2201_ASIC_EVENT_OFFSET: 176 case NVSW_SN2201_ASIC_MAKS_OFFSET: 177 case NVSW_SN2201_THML_EVENT_OFFSET: 178 case NVSW_SN2201_THML_MASK_OFFSET: 179 case NVSW_SN2201_PS_ALT_EVENT_OFFSET: 180 case NVSW_SN2201_PS_ALT_MASK_OFFSET: 181 case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET: 182 case NVSW_SN2201_PS_PRSNT_MASK_OFFSET: 183 case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET: 184 case NVSW_SN2201_PS_DC_OK_MASK_OFFSET: 185 case NVSW_SN2201_RST_SW_CTRL_OFFSET: 186 case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET: 187 case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET: 188 case NVSW_SN2201_WD_TMR_OFFSET_LSB: 189 case NVSW_SN2201_WD_TMR_OFFSET_MSB: 190 case NVSW_SN2201_WD_ACT_OFFSET: 191 case NVSW_SN2201_FAN_LED1_CTRL_OFFSET: 192 case NVSW_SN2201_FAN_LED2_CTRL_OFFSET: 193 return true; 194 } 195 return false; 196 } 197 198 static bool nvsw_sn2201_readable_reg(struct device *dev, unsigned int reg) 199 { 200 switch (reg) { 201 case NVSW_SN2201_HW_VER_ID_OFFSET: 202 case NVSW_SN2201_BOARD_ID_OFFSET: 203 case NVSW_SN2201_CPLD_VER_OFFSET: 204 case NVSW_SN2201_CPLD_MVER_OFFSET: 205 case NVSW_SN2201_CPLD_ID_OFFSET: 206 case NVSW_SN2201_CPLD_PN_OFFSET: 207 case NVSW_SN2201_CPLD_PN1_OFFSET: 208 case NVSW_SN2201_PSU_CTRL_OFFSET: 209 case NVSW_SN2201_QSFP28_STATUS_OFFSET: 210 case NVSW_SN2201_QSFP28_INT_STATUS_OFFSET: 211 case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET: 212 case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET: 213 case NVSW_SN2201_SYS_STATUS_OFFSET: 214 case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET: 215 case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET: 216 case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET: 217 case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET: 218 case NVSW_SN2201_SYS_RST_STATUS_OFFSET: 219 case NVSW_SN2201_RST_CAUSE1_OFFSET: 220 case NVSW_SN2201_RST_CAUSE2_OFFSET: 221 case NVSW_SN2201_SYS_INT_STATUS_OFFSET: 222 case NVSW_SN2201_SYS_INT_MASK_OFFSET: 223 case NVSW_SN2201_ASIC_STATUS_OFFSET: 224 case NVSW_SN2201_ASIC_EVENT_OFFSET: 225 case NVSW_SN2201_ASIC_MAKS_OFFSET: 226 case NVSW_SN2201_THML_STATUS_OFFSET: 227 case NVSW_SN2201_THML_EVENT_OFFSET: 228 case NVSW_SN2201_THML_MASK_OFFSET: 229 case NVSW_SN2201_PS_ALT_STATUS_OFFSET: 230 case NVSW_SN2201_PS_ALT_EVENT_OFFSET: 231 case NVSW_SN2201_PS_ALT_MASK_OFFSET: 232 case NVSW_SN2201_PS_PRSNT_STATUS_OFFSET: 233 case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET: 234 case NVSW_SN2201_PS_PRSNT_MASK_OFFSET: 235 case NVSW_SN2201_PS_DC_OK_STATUS_OFFSET: 236 case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET: 237 case NVSW_SN2201_PS_DC_OK_MASK_OFFSET: 238 case NVSW_SN2201_RST_SW_CTRL_OFFSET: 239 case NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET: 240 case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET: 241 case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET: 242 case NVSW_SN2201_WD_TMR_OFFSET_LSB: 243 case NVSW_SN2201_WD_TMR_OFFSET_MSB: 244 case NVSW_SN2201_WD_ACT_OFFSET: 245 case NVSW_SN2201_FAN_LED1_CTRL_OFFSET: 246 case NVSW_SN2201_FAN_LED2_CTRL_OFFSET: 247 return true; 248 } 249 return false; 250 } 251 252 static bool nvsw_sn2201_volatile_reg(struct device *dev, unsigned int reg) 253 { 254 switch (reg) { 255 case NVSW_SN2201_HW_VER_ID_OFFSET: 256 case NVSW_SN2201_BOARD_ID_OFFSET: 257 case NVSW_SN2201_CPLD_VER_OFFSET: 258 case NVSW_SN2201_CPLD_MVER_OFFSET: 259 case NVSW_SN2201_CPLD_ID_OFFSET: 260 case NVSW_SN2201_CPLD_PN_OFFSET: 261 case NVSW_SN2201_CPLD_PN1_OFFSET: 262 case NVSW_SN2201_PSU_CTRL_OFFSET: 263 case NVSW_SN2201_QSFP28_STATUS_OFFSET: 264 case NVSW_SN2201_QSFP28_INT_STATUS_OFFSET: 265 case NVSW_SN2201_QSFP28_LP_STATUS_OFFSET: 266 case NVSW_SN2201_QSFP28_RST_STATUS_OFFSET: 267 case NVSW_SN2201_SYS_STATUS_OFFSET: 268 case NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET: 269 case NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET: 270 case NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET: 271 case NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET: 272 case NVSW_SN2201_SYS_RST_STATUS_OFFSET: 273 case NVSW_SN2201_RST_CAUSE1_OFFSET: 274 case NVSW_SN2201_RST_CAUSE2_OFFSET: 275 case NVSW_SN2201_SYS_INT_STATUS_OFFSET: 276 case NVSW_SN2201_SYS_INT_MASK_OFFSET: 277 case NVSW_SN2201_ASIC_STATUS_OFFSET: 278 case NVSW_SN2201_ASIC_EVENT_OFFSET: 279 case NVSW_SN2201_ASIC_MAKS_OFFSET: 280 case NVSW_SN2201_THML_STATUS_OFFSET: 281 case NVSW_SN2201_THML_EVENT_OFFSET: 282 case NVSW_SN2201_THML_MASK_OFFSET: 283 case NVSW_SN2201_PS_ALT_STATUS_OFFSET: 284 case NVSW_SN2201_PS_ALT_EVENT_OFFSET: 285 case NVSW_SN2201_PS_ALT_MASK_OFFSET: 286 case NVSW_SN2201_PS_PRSNT_STATUS_OFFSET: 287 case NVSW_SN2201_PS_PRSNT_EVENT_OFFSET: 288 case NVSW_SN2201_PS_PRSNT_MASK_OFFSET: 289 case NVSW_SN2201_PS_DC_OK_STATUS_OFFSET: 290 case NVSW_SN2201_PS_DC_OK_EVENT_OFFSET: 291 case NVSW_SN2201_PS_DC_OK_MASK_OFFSET: 292 case NVSW_SN2201_RST_SW_CTRL_OFFSET: 293 case NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET: 294 case NVSW_SN2201_FAN_PRSNT_EVENT_OFFSET: 295 case NVSW_SN2201_FAN_PRSNT_MASK_OFFSET: 296 case NVSW_SN2201_WD_TMR_OFFSET_LSB: 297 case NVSW_SN2201_WD_TMR_OFFSET_MSB: 298 case NVSW_SN2201_FAN_LED1_CTRL_OFFSET: 299 case NVSW_SN2201_FAN_LED2_CTRL_OFFSET: 300 return true; 301 } 302 return false; 303 } 304 305 static const struct reg_default nvsw_sn2201_regmap_default[] = { 306 { NVSW_SN2201_QSFP28_LED_TEST_STATUS_OFFSET, 0x00 }, 307 { NVSW_SN2201_WD_ACT_OFFSET, 0x00 }, 308 }; 309 310 /* Configuration for the register map of a device with 1 bytes address space. */ 311 static const struct regmap_config nvsw_sn2201_regmap_conf = { 312 .reg_bits = 8, 313 .val_bits = 8, 314 .max_register = NVSW_SN2201_REG_MAX, 315 .cache_type = REGCACHE_FLAT, 316 .writeable_reg = nvsw_sn2201_writeable_reg, 317 .readable_reg = nvsw_sn2201_readable_reg, 318 .volatile_reg = nvsw_sn2201_volatile_reg, 319 .reg_defaults = nvsw_sn2201_regmap_default, 320 .num_reg_defaults = ARRAY_SIZE(nvsw_sn2201_regmap_default), 321 }; 322 323 /* Regions for LPC I2C controller and LPC base register space. */ 324 static const struct resource nvsw_sn2201_lpc_io_resources[] = { 325 [0] = DEFINE_RES_NAMED(NVSW_SN2201_CPLD_LPC_I2C_BASE_ADRR, 326 NVSW_SN2201_CPLD_LPC_IO_RANGE, 327 "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO), 328 }; 329 330 static struct resource nvsw_sn2201_cpld_res[] = { 331 [0] = DEFINE_RES_IRQ_NAMED(NVSW_SN2201_CPLD_SYSIRQ, "mlxreg-hotplug"), 332 }; 333 334 static struct resource nvsw_sn2201_lpc_res[] = { 335 [0] = DEFINE_RES_IRQ_NAMED(NVSW_SN2201_LPC_SYSIRQ, "i2c-mlxcpld"), 336 }; 337 338 /* SN2201 I2C platform data. */ 339 static struct mlxreg_core_hotplug_platform_data nvsw_sn2201_i2c_data = { 340 .irq = NVSW_SN2201_CPLD_SYSIRQ, 341 }; 342 343 /* SN2201 CPLD device. */ 344 static struct i2c_board_info nvsw_sn2201_cpld_devices[] = { 345 { 346 I2C_BOARD_INFO("nvsw-sn2201", 0x41), 347 }, 348 }; 349 350 /* SN2201 CPLD board info. */ 351 static struct mlxreg_hotplug_device nvsw_sn2201_cpld_brdinfo[] = { 352 { 353 .brdinfo = &nvsw_sn2201_cpld_devices[0], 354 .nr = NVSW_SN2201_CPLD_NR, 355 }, 356 }; 357 358 /* SN2201 main mux device. */ 359 static struct i2c_board_info nvsw_sn2201_main_mux_devices[] = { 360 { 361 I2C_BOARD_INFO("pca9548", 0x70), 362 }, 363 }; 364 365 /* SN2201 main mux board info. */ 366 static struct mlxreg_hotplug_device nvsw_sn2201_main_mux_brdinfo[] = { 367 { 368 .brdinfo = &nvsw_sn2201_main_mux_devices[0], 369 .nr = NVSW_SN2201_MAIN_MUX_NR, 370 }, 371 }; 372 373 /* SN2201 power devices. */ 374 static struct i2c_board_info nvsw_sn2201_pwr_devices[] = { 375 { 376 I2C_BOARD_INFO("pmbus", 0x58), 377 }, 378 { 379 I2C_BOARD_INFO("pmbus", 0x58), 380 }, 381 }; 382 383 /* SN2201 fan devices. */ 384 static struct i2c_board_info nvsw_sn2201_fan_devices[] = { 385 { 386 I2C_BOARD_INFO("24c02", 0x50), 387 }, 388 { 389 I2C_BOARD_INFO("24c02", 0x51), 390 }, 391 { 392 I2C_BOARD_INFO("24c02", 0x52), 393 }, 394 { 395 I2C_BOARD_INFO("24c02", 0x53), 396 }, 397 }; 398 399 /* SN2201 hotplug default data. */ 400 static struct mlxreg_core_data nvsw_sn2201_psu_items_data[] = { 401 { 402 .label = "psu1", 403 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 404 .mask = BIT(0), 405 .hpdev.nr = NVSW_SN2201_NR_NONE, 406 }, 407 { 408 .label = "psu2", 409 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 410 .mask = BIT(1), 411 .hpdev.nr = NVSW_SN2201_NR_NONE, 412 }, 413 }; 414 415 static struct mlxreg_core_data nvsw_sn2201_pwr_items_data[] = { 416 { 417 .label = "pwr1", 418 .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET, 419 .mask = BIT(0), 420 .hpdev.brdinfo = &nvsw_sn2201_pwr_devices[0], 421 .hpdev.nr = NVSW_SN2201_MAIN_MUX_CH1_NR, 422 }, 423 { 424 .label = "pwr2", 425 .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET, 426 .mask = BIT(1), 427 .hpdev.brdinfo = &nvsw_sn2201_pwr_devices[1], 428 .hpdev.nr = NVSW_SN2201_MAIN_MUX_CH2_NR, 429 }, 430 }; 431 432 static struct mlxreg_core_data nvsw_sn2201_fan_items_data[] = { 433 { 434 .label = "fan1", 435 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 436 .mask = BIT(0), 437 .hpdev.brdinfo = &nvsw_sn2201_fan_devices[0], 438 .hpdev.nr = NVSW_SN2201_2ND_MUX_CH0_NR, 439 }, 440 { 441 .label = "fan2", 442 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 443 .mask = BIT(1), 444 .hpdev.brdinfo = &nvsw_sn2201_fan_devices[1], 445 .hpdev.nr = NVSW_SN2201_2ND_MUX_CH1_NR, 446 }, 447 { 448 .label = "fan3", 449 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 450 .mask = BIT(2), 451 .hpdev.brdinfo = &nvsw_sn2201_fan_devices[2], 452 .hpdev.nr = NVSW_SN2201_2ND_MUX_CH2_NR, 453 }, 454 { 455 .label = "fan4", 456 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 457 .mask = BIT(3), 458 .hpdev.brdinfo = &nvsw_sn2201_fan_devices[3], 459 .hpdev.nr = NVSW_SN2201_2ND_MUX_CH3_NR, 460 }, 461 }; 462 463 static struct mlxreg_core_data nvsw_sn2201_sys_items_data[] = { 464 { 465 .label = "nic_smb_alert", 466 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 467 .mask = BIT(1), 468 .hpdev.nr = NVSW_SN2201_NR_NONE, 469 }, 470 { 471 .label = "cpu_sd", 472 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 473 .mask = BIT(2), 474 .hpdev.nr = NVSW_SN2201_NR_NONE, 475 }, 476 { 477 .label = "mac_health", 478 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 479 .mask = BIT(3), 480 .hpdev.nr = NVSW_SN2201_NR_NONE, 481 }, 482 }; 483 484 static struct mlxreg_core_item nvsw_sn2201_items[] = { 485 { 486 .data = nvsw_sn2201_psu_items_data, 487 .aggr_mask = NVSW_SN2201_CPLD_AGGR_PSU_MASK_DEF, 488 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 489 .mask = NVSW_SN2201_CPLD_PSU_MASK, 490 .count = ARRAY_SIZE(nvsw_sn2201_psu_items_data), 491 .inversed = 1, 492 .health = false, 493 }, 494 { 495 .data = nvsw_sn2201_pwr_items_data, 496 .aggr_mask = NVSW_SN2201_CPLD_AGGR_PWR_MASK_DEF, 497 .reg = NVSW_SN2201_PS_DC_OK_STATUS_OFFSET, 498 .mask = NVSW_SN2201_CPLD_PWR_MASK, 499 .count = ARRAY_SIZE(nvsw_sn2201_pwr_items_data), 500 .inversed = 0, 501 .health = false, 502 }, 503 { 504 .data = nvsw_sn2201_fan_items_data, 505 .aggr_mask = NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF, 506 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 507 .mask = NVSW_SN2201_CPLD_FAN_MASK, 508 .count = ARRAY_SIZE(nvsw_sn2201_fan_items_data), 509 .inversed = 1, 510 .health = false, 511 }, 512 { 513 .data = nvsw_sn2201_sys_items_data, 514 .aggr_mask = NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF, 515 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 516 .mask = NVSW_SN2201_CPLD_ASIC_MASK, 517 .count = ARRAY_SIZE(nvsw_sn2201_sys_items_data), 518 .inversed = 1, 519 .health = false, 520 }, 521 }; 522 523 static 524 struct mlxreg_core_hotplug_platform_data nvsw_sn2201_hotplug = { 525 .items = nvsw_sn2201_items, 526 .count = ARRAY_SIZE(nvsw_sn2201_items), 527 .cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET, 528 .mask = NVSW_SN2201_CPLD_AGGR_MASK_DEF, 529 }; 530 531 static struct mlxreg_core_item nvsw_sn2201_busbar_items[] = { 532 { 533 .data = nvsw_sn2201_fan_items_data, 534 .aggr_mask = NVSW_SN2201_CPLD_AGGR_FAN_MASK_DEF, 535 .reg = NVSW_SN2201_FAN_PRSNT_STATUS_OFFSET, 536 .mask = NVSW_SN2201_CPLD_FAN_MASK, 537 .count = ARRAY_SIZE(nvsw_sn2201_fan_items_data), 538 .inversed = 1, 539 .health = false, 540 }, 541 { 542 .data = nvsw_sn2201_sys_items_data, 543 .aggr_mask = NVSW_SN2201_CPLD_AGGR_ASIC_MASK_DEF, 544 .reg = NVSW_SN2201_ASIC_STATUS_OFFSET, 545 .mask = NVSW_SN2201_CPLD_ASIC_MASK, 546 .count = ARRAY_SIZE(nvsw_sn2201_sys_items_data), 547 .inversed = 1, 548 .health = false, 549 }, 550 }; 551 552 static 553 struct mlxreg_core_hotplug_platform_data nvsw_sn2201_busbar_hotplug = { 554 .items = nvsw_sn2201_busbar_items, 555 .count = ARRAY_SIZE(nvsw_sn2201_busbar_items), 556 .cell = NVSW_SN2201_SYS_INT_STATUS_OFFSET, 557 .mask = NVSW_SN2201_CPLD_AGGR_BUSBAR_MASK_DEF, 558 }; 559 560 /* SN2201 static devices. */ 561 static struct i2c_board_info nvsw_sn2201_static_devices[] = { 562 { 563 I2C_BOARD_INFO("24c02", 0x57), 564 }, 565 { 566 I2C_BOARD_INFO("lm75", 0x4b), 567 }, 568 { 569 I2C_BOARD_INFO("24c64", 0x56), 570 }, 571 { 572 I2C_BOARD_INFO("ads1015", 0x49), 573 }, 574 { 575 I2C_BOARD_INFO("pca9546", 0x71), 576 }, 577 { 578 I2C_BOARD_INFO("emc2305", 0x4d), 579 }, 580 { 581 I2C_BOARD_INFO("lm75", 0x49), 582 }, 583 { 584 I2C_BOARD_INFO("pca9555", 0x27), 585 }, 586 { 587 I2C_BOARD_INFO("powr1014", 0x37), 588 }, 589 { 590 I2C_BOARD_INFO("lm75", 0x4f), 591 }, 592 { 593 I2C_BOARD_INFO("pmbus", 0x40), 594 }, 595 { 596 I2C_BOARD_INFO("lm5066i", 0x15), 597 }, 598 }; 599 600 /* SN2201 default static board info. */ 601 static struct mlxreg_hotplug_device nvsw_sn2201_static_brdinfo[] = { 602 { 603 .brdinfo = &nvsw_sn2201_static_devices[0], 604 .nr = NVSW_SN2201_MAIN_NR, 605 }, 606 { 607 .brdinfo = &nvsw_sn2201_static_devices[1], 608 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 609 }, 610 { 611 .brdinfo = &nvsw_sn2201_static_devices[2], 612 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 613 }, 614 { 615 .brdinfo = &nvsw_sn2201_static_devices[3], 616 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 617 }, 618 { 619 .brdinfo = &nvsw_sn2201_static_devices[4], 620 .nr = NVSW_SN2201_MAIN_MUX_CH3_NR, 621 }, 622 { 623 .brdinfo = &nvsw_sn2201_static_devices[5], 624 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 625 }, 626 { 627 .brdinfo = &nvsw_sn2201_static_devices[6], 628 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 629 }, 630 { 631 .brdinfo = &nvsw_sn2201_static_devices[7], 632 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 633 }, 634 { 635 .brdinfo = &nvsw_sn2201_static_devices[8], 636 .nr = NVSW_SN2201_MAIN_MUX_CH6_NR, 637 }, 638 { 639 .brdinfo = &nvsw_sn2201_static_devices[9], 640 .nr = NVSW_SN2201_MAIN_MUX_CH6_NR, 641 }, 642 { 643 .brdinfo = &nvsw_sn2201_static_devices[10], 644 .nr = NVSW_SN2201_MAIN_MUX_CH7_NR, 645 }, 646 }; 647 648 /* SN2201 default busbar static board info. */ 649 static struct mlxreg_hotplug_device nvsw_sn2201_busbar_static_brdinfo[] = { 650 { 651 .brdinfo = &nvsw_sn2201_static_devices[0], 652 .nr = NVSW_SN2201_MAIN_NR, 653 }, 654 { 655 .brdinfo = &nvsw_sn2201_static_devices[1], 656 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 657 }, 658 { 659 .brdinfo = &nvsw_sn2201_static_devices[2], 660 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 661 }, 662 { 663 .brdinfo = &nvsw_sn2201_static_devices[3], 664 .nr = NVSW_SN2201_MAIN_MUX_CH0_NR, 665 }, 666 { 667 .brdinfo = &nvsw_sn2201_static_devices[4], 668 .nr = NVSW_SN2201_MAIN_MUX_CH3_NR, 669 }, 670 { 671 .brdinfo = &nvsw_sn2201_static_devices[5], 672 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 673 }, 674 { 675 .brdinfo = &nvsw_sn2201_static_devices[6], 676 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 677 }, 678 { 679 .brdinfo = &nvsw_sn2201_static_devices[7], 680 .nr = NVSW_SN2201_MAIN_MUX_CH5_NR, 681 }, 682 { 683 .brdinfo = &nvsw_sn2201_static_devices[8], 684 .nr = NVSW_SN2201_MAIN_MUX_CH6_NR, 685 }, 686 { 687 .brdinfo = &nvsw_sn2201_static_devices[9], 688 .nr = NVSW_SN2201_MAIN_MUX_CH6_NR, 689 }, 690 { 691 .brdinfo = &nvsw_sn2201_static_devices[10], 692 .nr = NVSW_SN2201_MAIN_MUX_CH7_NR, 693 }, 694 { 695 .brdinfo = &nvsw_sn2201_static_devices[11], 696 .nr = NVSW_SN2201_MAIN_MUX_CH1_NR, 697 }, 698 }; 699 700 /* LED default data. */ 701 static struct mlxreg_core_data nvsw_sn2201_led_data[] = { 702 { 703 .label = "status:green", 704 .reg = NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET, 705 .mask = GENMASK(7, 4), 706 }, 707 { 708 .label = "status:orange", 709 .reg = NVSW_SN2201_FRONT_SYS_LED_CTRL_OFFSET, 710 .mask = GENMASK(7, 4), 711 }, 712 { 713 .label = "psu:green", 714 .reg = NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET, 715 .mask = GENMASK(7, 4), 716 }, 717 { 718 .label = "psu:orange", 719 .reg = NVSW_SN2201_FRONT_PSU_LED_CTRL_OFFSET, 720 .mask = GENMASK(7, 4), 721 }, 722 { 723 .label = "uid:blue", 724 .reg = NVSW_SN2201_FRONT_UID_LED_CTRL_OFFSET, 725 .mask = GENMASK(7, 4), 726 }, 727 { 728 .label = "fan1:green", 729 .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET, 730 .mask = GENMASK(7, 4), 731 }, 732 { 733 .label = "fan1:orange", 734 .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET, 735 .mask = GENMASK(7, 4), 736 }, 737 { 738 .label = "fan2:green", 739 .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET, 740 .mask = GENMASK(3, 0), 741 }, 742 { 743 .label = "fan2:orange", 744 .reg = NVSW_SN2201_FAN_LED1_CTRL_OFFSET, 745 .mask = GENMASK(3, 0), 746 }, 747 { 748 .label = "fan3:green", 749 .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET, 750 .mask = GENMASK(7, 4), 751 }, 752 { 753 .label = "fan3:orange", 754 .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET, 755 .mask = GENMASK(7, 4), 756 }, 757 { 758 .label = "fan4:green", 759 .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET, 760 .mask = GENMASK(3, 0), 761 }, 762 { 763 .label = "fan4:orange", 764 .reg = NVSW_SN2201_FAN_LED2_CTRL_OFFSET, 765 .mask = GENMASK(3, 0), 766 }, 767 }; 768 769 static struct mlxreg_core_platform_data nvsw_sn2201_led = { 770 .data = nvsw_sn2201_led_data, 771 .counter = ARRAY_SIZE(nvsw_sn2201_led_data), 772 }; 773 774 /* Default register access data. */ 775 static struct mlxreg_core_data nvsw_sn2201_io_data[] = { 776 { 777 .label = "cpld1_version", 778 .reg = NVSW_SN2201_CPLD_VER_OFFSET, 779 .bit = GENMASK(7, 0), 780 .mode = 0444, 781 }, 782 { 783 .label = "cpld1_version_min", 784 .reg = NVSW_SN2201_CPLD_MVER_OFFSET, 785 .bit = GENMASK(7, 0), 786 .mode = 0444, 787 }, 788 { 789 .label = "cpld1_pn", 790 .reg = NVSW_SN2201_CPLD_PN_OFFSET, 791 .bit = GENMASK(15, 0), 792 .mode = 0444, 793 .regnum = 2, 794 }, 795 { 796 .label = "psu1_on", 797 .reg = NVSW_SN2201_PSU_CTRL_OFFSET, 798 .mask = GENMASK(7, 0) & ~BIT(0), 799 .mode = 0644, 800 }, 801 { 802 .label = "psu2_on", 803 .reg = NVSW_SN2201_PSU_CTRL_OFFSET, 804 .mask = GENMASK(7, 0) & ~BIT(1), 805 .mode = 0644, 806 }, 807 { 808 .label = "pwr_cycle", 809 .reg = NVSW_SN2201_PSU_CTRL_OFFSET, 810 .mask = GENMASK(7, 0) & ~BIT(2), 811 .mode = 0644, 812 }, 813 { 814 .label = "asic_health", 815 .reg = NVSW_SN2201_SYS_STATUS_OFFSET, 816 .mask = GENMASK(4, 3), 817 .bit = 4, 818 .mode = 0444, 819 }, 820 { 821 .label = "qsfp_pwr_good", 822 .reg = NVSW_SN2201_SYS_STATUS_OFFSET, 823 .mask = GENMASK(7, 0) & ~BIT(0), 824 .mode = 0444, 825 }, 826 { 827 .label = "phy_reset", 828 .reg = NVSW_SN2201_SYS_RST_STATUS_OFFSET, 829 .mask = GENMASK(7, 0) & ~BIT(3), 830 .mode = 0644, 831 }, 832 { 833 .label = "mac_reset", 834 .reg = NVSW_SN2201_SYS_RST_STATUS_OFFSET, 835 .mask = GENMASK(7, 0) & ~BIT(2), 836 .mode = 0644, 837 }, 838 { 839 .label = "pwr_down", 840 .reg = NVSW_SN2201_RST_SW_CTRL_OFFSET, 841 .mask = GENMASK(7, 0) & ~BIT(0), 842 .mode = 0644, 843 }, 844 { 845 .label = "reset_long_pb", 846 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 847 .mask = GENMASK(7, 0) & ~BIT(0), 848 .mode = 0444, 849 }, 850 { 851 .label = "reset_short_pb", 852 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 853 .mask = GENMASK(7, 0) & ~BIT(1), 854 .mode = 0444, 855 }, 856 { 857 .label = "reset_aux_pwr_or_fu", 858 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 859 .mask = GENMASK(7, 0) & ~BIT(2), 860 .mode = 0444, 861 }, 862 { 863 .label = "reset_swb_dc_dc_pwr_fail", 864 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 865 .mask = GENMASK(7, 0) & ~BIT(3), 866 .mode = 0444, 867 }, 868 { 869 .label = "reset_sw_reset", 870 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 871 .mask = GENMASK(7, 0) & ~BIT(4), 872 .mode = 0444, 873 }, 874 { 875 .label = "reset_fw_reset", 876 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 877 .mask = GENMASK(7, 0) & ~BIT(5), 878 .mode = 0444, 879 }, 880 { 881 .label = "reset_swb_wd", 882 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 883 .mask = GENMASK(7, 0) & ~BIT(6), 884 .mode = 0444, 885 }, 886 { 887 .label = "reset_asic_thermal", 888 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 889 .mask = GENMASK(7, 0) & ~BIT(7), 890 .mode = 0444, 891 }, 892 { 893 .label = "reset_system", 894 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 895 .mask = GENMASK(7, 0) & ~BIT(1), 896 .mode = 0444, 897 }, 898 { 899 .label = "reset_sw_pwr_off", 900 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 901 .mask = GENMASK(7, 0) & ~BIT(2), 902 .mode = 0444, 903 }, 904 { 905 .label = "reset_cpu_pwr_fail_thermal", 906 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 907 .mask = GENMASK(7, 0) & ~BIT(4), 908 .mode = 0444, 909 }, 910 { 911 .label = "reset_reload_bios", 912 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 913 .mask = GENMASK(7, 0) & ~BIT(5), 914 .mode = 0444, 915 }, 916 { 917 .label = "reset_ac_pwr_fail", 918 .reg = NVSW_SN2201_RST_CAUSE2_OFFSET, 919 .mask = GENMASK(7, 0) & ~BIT(6), 920 .mode = 0444, 921 }, 922 { 923 .label = "psu1", 924 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 925 .mask = GENMASK(7, 0) & ~BIT(0), 926 .mode = 0444, 927 }, 928 { 929 .label = "psu2", 930 .reg = NVSW_SN2201_PS_PRSNT_STATUS_OFFSET, 931 .mask = GENMASK(7, 0) & ~BIT(1), 932 .mode = 0444, 933 }, 934 }; 935 936 static struct mlxreg_core_platform_data nvsw_sn2201_regs_io = { 937 .data = nvsw_sn2201_io_data, 938 .counter = ARRAY_SIZE(nvsw_sn2201_io_data), 939 }; 940 941 /* Default watchdog data. */ 942 static struct mlxreg_core_data nvsw_sn2201_wd_data[] = { 943 { 944 .label = "action", 945 .reg = NVSW_SN2201_WD_ACT_OFFSET, 946 .mask = GENMASK(7, 1), 947 .bit = 0, 948 }, 949 { 950 .label = "timeout", 951 .reg = NVSW_SN2201_WD_TMR_OFFSET_LSB, 952 .mask = 0, 953 .health_cntr = NVSW_SN2201_WD_DFLT_TIMEOUT, 954 }, 955 { 956 .label = "timeleft", 957 .reg = NVSW_SN2201_WD_TMR_OFFSET_LSB, 958 .mask = 0, 959 }, 960 { 961 .label = "ping", 962 .reg = NVSW_SN2201_WD_ACT_OFFSET, 963 .mask = GENMASK(7, 1), 964 .bit = 0, 965 }, 966 { 967 .label = "reset", 968 .reg = NVSW_SN2201_RST_CAUSE1_OFFSET, 969 .mask = GENMASK(7, 0) & ~BIT(6), 970 .bit = 6, 971 }, 972 }; 973 974 static struct mlxreg_core_platform_data nvsw_sn2201_wd = { 975 .data = nvsw_sn2201_wd_data, 976 .counter = ARRAY_SIZE(nvsw_sn2201_wd_data), 977 .version = MLX_WDT_TYPE3, 978 .identity = "mlx-wdt-main", 979 }; 980 981 static int 982 nvsw_sn2201_create_static_devices(struct nvsw_sn2201 *nvsw_sn2201, 983 struct mlxreg_hotplug_device *devs, 984 int size) 985 { 986 struct mlxreg_hotplug_device *dev = devs; 987 int ret; 988 int i; 989 990 /* Create I2C static devices. */ 991 for (i = 0; i < size; i++, dev++) { 992 dev->client = i2c_new_client_device(dev->adapter, dev->brdinfo); 993 if (IS_ERR(dev->client)) { 994 dev_err(nvsw_sn2201->dev, "Failed to create client %s at bus %d at addr 0x%02x\n", 995 dev->brdinfo->type, 996 dev->nr, dev->brdinfo->addr); 997 998 dev->adapter = NULL; 999 ret = PTR_ERR(dev->client); 1000 goto fail_create_static_devices; 1001 } 1002 } 1003 1004 return 0; 1005 1006 fail_create_static_devices: 1007 while (--i >= 0) { 1008 dev = devs + i; 1009 i2c_unregister_device(dev->client); 1010 dev->client = NULL; 1011 dev->adapter = NULL; 1012 } 1013 return ret; 1014 } 1015 1016 static void nvsw_sn2201_destroy_static_devices(struct nvsw_sn2201 *nvsw_sn2201, 1017 struct mlxreg_hotplug_device *devs, int size) 1018 { 1019 struct mlxreg_hotplug_device *dev = devs; 1020 int i; 1021 1022 /* Destroy static I2C device for SN2201 static devices. */ 1023 for (i = 0; i < size; i++, dev++) { 1024 if (dev->client) { 1025 i2c_unregister_device(dev->client); 1026 dev->client = NULL; 1027 i2c_put_adapter(dev->adapter); 1028 dev->adapter = NULL; 1029 } 1030 } 1031 } 1032 1033 static int nvsw_sn2201_config_post_init(struct nvsw_sn2201 *nvsw_sn2201) 1034 { 1035 struct mlxreg_hotplug_device *sn2201_dev; 1036 struct i2c_adapter *adap; 1037 struct device *dev; 1038 int i, err; 1039 1040 dev = nvsw_sn2201->dev; 1041 adap = i2c_get_adapter(nvsw_sn2201->main_mux_deferred_nr); 1042 if (!adap) { 1043 dev_err(dev, "Failed to get adapter for bus %d\n", 1044 nvsw_sn2201->main_mux_deferred_nr); 1045 return -ENODEV; 1046 } 1047 i2c_put_adapter(adap); 1048 1049 /* Update board info. */ 1050 sn2201_dev = nvsw_sn2201->sn2201_devs; 1051 for (i = 0; i < nvsw_sn2201->sn2201_devs_num; i++, sn2201_dev++) { 1052 sn2201_dev->adapter = i2c_get_adapter(sn2201_dev->nr); 1053 if (!sn2201_dev->adapter) 1054 return -ENODEV; 1055 i2c_put_adapter(sn2201_dev->adapter); 1056 } 1057 1058 err = nvsw_sn2201_create_static_devices(nvsw_sn2201, nvsw_sn2201->sn2201_devs, 1059 nvsw_sn2201->sn2201_devs_num); 1060 if (err) 1061 dev_err(dev, "Failed to create static devices\n"); 1062 1063 return err; 1064 } 1065 1066 static int nvsw_sn2201_config_init(struct nvsw_sn2201 *nvsw_sn2201, void *regmap) 1067 { 1068 struct device *dev = nvsw_sn2201->dev; 1069 int err; 1070 1071 nvsw_sn2201->io_data = &nvsw_sn2201_regs_io; 1072 nvsw_sn2201->led_data = &nvsw_sn2201_led; 1073 nvsw_sn2201->wd_data = &nvsw_sn2201_wd; 1074 if (nvsw_sn2201->ext_pwr_source) 1075 nvsw_sn2201->hotplug_data = &nvsw_sn2201_busbar_hotplug; 1076 else 1077 nvsw_sn2201->hotplug_data = &nvsw_sn2201_hotplug; 1078 1079 /* Register IO access driver. */ 1080 if (nvsw_sn2201->io_data) { 1081 nvsw_sn2201->io_data->regmap = regmap; 1082 nvsw_sn2201->io_regs = 1083 platform_device_register_resndata(dev, "mlxreg-io", PLATFORM_DEVID_NONE, NULL, 0, 1084 nvsw_sn2201->io_data, 1085 sizeof(*nvsw_sn2201->io_data)); 1086 if (IS_ERR(nvsw_sn2201->io_regs)) { 1087 err = PTR_ERR(nvsw_sn2201->io_regs); 1088 goto fail_register_io; 1089 } 1090 } 1091 1092 /* Register LED driver. */ 1093 if (nvsw_sn2201->led_data) { 1094 nvsw_sn2201->led_data->regmap = regmap; 1095 nvsw_sn2201->led = 1096 platform_device_register_resndata(dev, "leds-mlxreg", PLATFORM_DEVID_NONE, NULL, 0, 1097 nvsw_sn2201->led_data, 1098 sizeof(*nvsw_sn2201->led_data)); 1099 if (IS_ERR(nvsw_sn2201->led)) { 1100 err = PTR_ERR(nvsw_sn2201->led); 1101 goto fail_register_led; 1102 } 1103 } 1104 1105 /* Register WD driver. */ 1106 if (nvsw_sn2201->wd_data) { 1107 nvsw_sn2201->wd_data->regmap = regmap; 1108 nvsw_sn2201->wd = 1109 platform_device_register_resndata(dev, "mlx-wdt", PLATFORM_DEVID_NONE, NULL, 0, 1110 nvsw_sn2201->wd_data, 1111 sizeof(*nvsw_sn2201->wd_data)); 1112 if (IS_ERR(nvsw_sn2201->wd)) { 1113 err = PTR_ERR(nvsw_sn2201->wd); 1114 goto fail_register_wd; 1115 } 1116 } 1117 1118 /* Register hotplug driver. */ 1119 if (nvsw_sn2201->hotplug_data) { 1120 nvsw_sn2201->hotplug_data->regmap = regmap; 1121 nvsw_sn2201->pdev_hotplug = 1122 platform_device_register_resndata(dev, "mlxreg-hotplug", PLATFORM_DEVID_NONE, 1123 nvsw_sn2201_cpld_res, 1124 ARRAY_SIZE(nvsw_sn2201_cpld_res), 1125 nvsw_sn2201->hotplug_data, 1126 sizeof(*nvsw_sn2201->hotplug_data)); 1127 if (IS_ERR(nvsw_sn2201->pdev_hotplug)) { 1128 err = PTR_ERR(nvsw_sn2201->pdev_hotplug); 1129 goto fail_register_hotplug; 1130 } 1131 } 1132 1133 return nvsw_sn2201_config_post_init(nvsw_sn2201); 1134 1135 fail_register_hotplug: 1136 if (nvsw_sn2201->wd) 1137 platform_device_unregister(nvsw_sn2201->wd); 1138 fail_register_wd: 1139 if (nvsw_sn2201->led) 1140 platform_device_unregister(nvsw_sn2201->led); 1141 fail_register_led: 1142 if (nvsw_sn2201->io_regs) 1143 platform_device_unregister(nvsw_sn2201->io_regs); 1144 fail_register_io: 1145 1146 return err; 1147 } 1148 1149 static void nvsw_sn2201_config_exit(struct nvsw_sn2201 *nvsw_sn2201) 1150 { 1151 /* Unregister hotplug driver. */ 1152 if (nvsw_sn2201->pdev_hotplug) 1153 platform_device_unregister(nvsw_sn2201->pdev_hotplug); 1154 /* Unregister WD driver. */ 1155 if (nvsw_sn2201->wd) 1156 platform_device_unregister(nvsw_sn2201->wd); 1157 /* Unregister LED driver. */ 1158 if (nvsw_sn2201->led) 1159 platform_device_unregister(nvsw_sn2201->led); 1160 /* Unregister IO access driver. */ 1161 if (nvsw_sn2201->io_regs) 1162 platform_device_unregister(nvsw_sn2201->io_regs); 1163 } 1164 1165 /* 1166 * Initialization is divided into two parts: 1167 * - I2C main bus init. 1168 * - Mux creation and attaching devices to the mux, 1169 * which assumes that the main bus is already created. 1170 * This separation is required for synchronization between these two parts. 1171 * Completion notify callback is used to make this flow synchronized. 1172 */ 1173 static int nvsw_sn2201_i2c_completion_notify(void *handle, int id) 1174 { 1175 struct nvsw_sn2201 *nvsw_sn2201 = handle; 1176 void *regmap; 1177 int i, err; 1178 1179 /* Create main mux. */ 1180 nvsw_sn2201->main_mux_devs->adapter = i2c_get_adapter(nvsw_sn2201->main_mux_devs->nr); 1181 if (!nvsw_sn2201->main_mux_devs->adapter) { 1182 err = -ENODEV; 1183 dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n", 1184 nvsw_sn2201->main_mux_devs->nr); 1185 goto i2c_get_adapter_main_fail; 1186 } 1187 1188 nvsw_sn2201->main_mux_devs_num = ARRAY_SIZE(nvsw_sn2201_main_mux_brdinfo); 1189 err = nvsw_sn2201_create_static_devices(nvsw_sn2201, nvsw_sn2201->main_mux_devs, 1190 nvsw_sn2201->main_mux_devs_num); 1191 if (err) { 1192 dev_err(nvsw_sn2201->dev, "Failed to create main mux devices\n"); 1193 goto nvsw_sn2201_create_static_devices_fail; 1194 } 1195 1196 nvsw_sn2201->cpld_devs->adapter = i2c_get_adapter(nvsw_sn2201->cpld_devs->nr); 1197 if (!nvsw_sn2201->cpld_devs->adapter) { 1198 err = -ENODEV; 1199 dev_err(nvsw_sn2201->dev, "Failed to get adapter for bus %d\n", 1200 nvsw_sn2201->cpld_devs->nr); 1201 goto i2c_get_adapter_fail; 1202 } 1203 1204 /* Create CPLD device. */ 1205 nvsw_sn2201->cpld_devs->client = i2c_new_dummy_device(nvsw_sn2201->cpld_devs->adapter, 1206 NVSW_SN2201_CPLD_I2CADDR); 1207 if (IS_ERR(nvsw_sn2201->cpld_devs->client)) { 1208 err = PTR_ERR(nvsw_sn2201->cpld_devs->client); 1209 dev_err(nvsw_sn2201->dev, "Failed to create %s cpld device at bus %d at addr 0x%02x\n", 1210 nvsw_sn2201->cpld_devs->brdinfo->type, nvsw_sn2201->cpld_devs->nr, 1211 nvsw_sn2201->cpld_devs->brdinfo->addr); 1212 goto i2c_new_dummy_fail; 1213 } 1214 1215 regmap = devm_regmap_init_i2c(nvsw_sn2201->cpld_devs->client, &nvsw_sn2201_regmap_conf); 1216 if (IS_ERR(regmap)) { 1217 err = PTR_ERR(regmap); 1218 dev_err(nvsw_sn2201->dev, "Failed to initialise managed register map\n"); 1219 goto devm_regmap_init_i2c_fail; 1220 } 1221 1222 /* Set default registers. */ 1223 for (i = 0; i < nvsw_sn2201_regmap_conf.num_reg_defaults; i++) { 1224 err = regmap_write(regmap, nvsw_sn2201_regmap_default[i].reg, 1225 nvsw_sn2201_regmap_default[i].def); 1226 if (err) { 1227 dev_err(nvsw_sn2201->dev, "Failed to set register at offset 0x%02x to default value: 0x%02x\n", 1228 nvsw_sn2201_regmap_default[i].reg, 1229 nvsw_sn2201_regmap_default[i].def); 1230 goto regmap_write_fail; 1231 } 1232 } 1233 1234 /* Sync registers with hardware. */ 1235 regcache_mark_dirty(regmap); 1236 err = regcache_sync(regmap); 1237 if (err) { 1238 dev_err(nvsw_sn2201->dev, "Failed to Sync registers with hardware\n"); 1239 goto regcache_sync_fail; 1240 } 1241 1242 /* Configure SN2201 board. */ 1243 err = nvsw_sn2201_config_init(nvsw_sn2201, regmap); 1244 if (err) { 1245 dev_err(nvsw_sn2201->dev, "Failed to configure board\n"); 1246 goto nvsw_sn2201_config_init_fail; 1247 } 1248 1249 return 0; 1250 1251 nvsw_sn2201_config_init_fail: 1252 nvsw_sn2201_config_exit(nvsw_sn2201); 1253 regcache_sync_fail: 1254 regmap_write_fail: 1255 devm_regmap_init_i2c_fail: 1256 i2c_new_dummy_fail: 1257 i2c_put_adapter(nvsw_sn2201->cpld_devs->adapter); 1258 nvsw_sn2201->cpld_devs->adapter = NULL; 1259 i2c_get_adapter_fail: 1260 /* Destroy SN2201 static I2C devices. */ 1261 nvsw_sn2201_destroy_static_devices(nvsw_sn2201, nvsw_sn2201->sn2201_devs, 1262 nvsw_sn2201->sn2201_devs_num); 1263 /* Destroy main mux device. */ 1264 nvsw_sn2201_destroy_static_devices(nvsw_sn2201, nvsw_sn2201->main_mux_devs, 1265 nvsw_sn2201->main_mux_devs_num); 1266 nvsw_sn2201_create_static_devices_fail: 1267 i2c_put_adapter(nvsw_sn2201->main_mux_devs->adapter); 1268 i2c_get_adapter_main_fail: 1269 return err; 1270 } 1271 1272 static int nvsw_sn2201_config_pre_init(struct nvsw_sn2201 *nvsw_sn2201) 1273 { 1274 nvsw_sn2201->i2c_data = &nvsw_sn2201_i2c_data; 1275 1276 /* Register I2C controller. */ 1277 nvsw_sn2201->i2c_data->handle = nvsw_sn2201; 1278 nvsw_sn2201->i2c_data->completion_notify = nvsw_sn2201_i2c_completion_notify; 1279 nvsw_sn2201->pdev_i2c = platform_device_register_resndata(nvsw_sn2201->dev, "i2c_mlxcpld", 1280 NVSW_SN2201_MAIN_MUX_NR, 1281 nvsw_sn2201_lpc_res, 1282 ARRAY_SIZE(nvsw_sn2201_lpc_res), 1283 nvsw_sn2201->i2c_data, 1284 sizeof(*nvsw_sn2201->i2c_data)); 1285 if (IS_ERR(nvsw_sn2201->pdev_i2c)) 1286 return PTR_ERR(nvsw_sn2201->pdev_i2c); 1287 1288 return 0; 1289 } 1290 1291 static int nvsw_sn2201_probe(struct platform_device *pdev) 1292 { 1293 struct nvsw_sn2201 *nvsw_sn2201; 1294 const char *sku; 1295 int ret; 1296 1297 nvsw_sn2201 = devm_kzalloc(&pdev->dev, sizeof(*nvsw_sn2201), GFP_KERNEL); 1298 if (!nvsw_sn2201) 1299 return -ENOMEM; 1300 1301 /* Validate system powering type - only HI168 SKU supports external power. */ 1302 sku = dmi_get_system_info(DMI_PRODUCT_SKU); 1303 if (sku && !strcmp(sku, "HI168")) 1304 nvsw_sn2201->ext_pwr_source = true; 1305 1306 nvsw_sn2201->dev = &pdev->dev; 1307 platform_set_drvdata(pdev, nvsw_sn2201); 1308 ret = platform_device_add_resources(pdev, nvsw_sn2201_lpc_io_resources, 1309 ARRAY_SIZE(nvsw_sn2201_lpc_io_resources)); 1310 if (ret) 1311 return ret; 1312 1313 nvsw_sn2201->main_mux_deferred_nr = NVSW_SN2201_MAIN_MUX_DEFER_NR; 1314 nvsw_sn2201->main_mux_devs = nvsw_sn2201_main_mux_brdinfo; 1315 nvsw_sn2201->cpld_devs = nvsw_sn2201_cpld_brdinfo; 1316 if (nvsw_sn2201->ext_pwr_source) { 1317 nvsw_sn2201->sn2201_devs = nvsw_sn2201_busbar_static_brdinfo; 1318 nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_busbar_static_brdinfo); 1319 } else { 1320 nvsw_sn2201->sn2201_devs = nvsw_sn2201_static_brdinfo; 1321 nvsw_sn2201->sn2201_devs_num = ARRAY_SIZE(nvsw_sn2201_static_brdinfo); 1322 } 1323 1324 return nvsw_sn2201_config_pre_init(nvsw_sn2201); 1325 } 1326 1327 static void nvsw_sn2201_remove(struct platform_device *pdev) 1328 { 1329 struct nvsw_sn2201 *nvsw_sn2201 = platform_get_drvdata(pdev); 1330 1331 /* Unregister underlying drivers. */ 1332 nvsw_sn2201_config_exit(nvsw_sn2201); 1333 1334 /* Destroy SN2201 static I2C devices. */ 1335 nvsw_sn2201_destroy_static_devices(nvsw_sn2201, 1336 nvsw_sn2201->sn2201_devs, 1337 nvsw_sn2201->sn2201_devs_num); 1338 1339 i2c_put_adapter(nvsw_sn2201->cpld_devs->adapter); 1340 nvsw_sn2201->cpld_devs->adapter = NULL; 1341 /* Destroy main mux device. */ 1342 nvsw_sn2201_destroy_static_devices(nvsw_sn2201, 1343 nvsw_sn2201->main_mux_devs, 1344 nvsw_sn2201->main_mux_devs_num); 1345 1346 /* Unregister I2C controller. */ 1347 if (nvsw_sn2201->pdev_i2c) 1348 platform_device_unregister(nvsw_sn2201->pdev_i2c); 1349 } 1350 1351 static const struct acpi_device_id nvsw_sn2201_acpi_ids[] = { 1352 {"NVSN2201", 0}, 1353 {} 1354 }; 1355 1356 MODULE_DEVICE_TABLE(acpi, nvsw_sn2201_acpi_ids); 1357 1358 static struct platform_driver nvsw_sn2201_driver = { 1359 .probe = nvsw_sn2201_probe, 1360 .remove = nvsw_sn2201_remove, 1361 .driver = { 1362 .name = "nvsw-sn2201", 1363 .acpi_match_table = nvsw_sn2201_acpi_ids, 1364 }, 1365 }; 1366 1367 module_platform_driver(nvsw_sn2201_driver); 1368 1369 MODULE_AUTHOR("Nvidia"); 1370 MODULE_DESCRIPTION("Nvidia sn2201 platform driver"); 1371 MODULE_LICENSE("Dual BSD/GPL"); 1372 MODULE_ALIAS("platform:nvsw-sn2201"); 1373