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