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