mlxreg-lc.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Nvidia line card driver
  4. *
  5. * Copyright (C) 2020 Nvidia Technologies Ltd.
  6. */
  7. #include <linux/device.h>
  8. #include <linux/i2c.h>
  9. #include <linux/module.h>
  10. #include <linux/platform_data/mlxcpld.h>
  11. #include <linux/platform_data/mlxreg.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/regmap.h>
  14. /* I2C bus IO offsets */
  15. #define MLXREG_LC_REG_CPLD1_VER_OFFSET 0x2500
  16. #define MLXREG_LC_REG_FPGA1_VER_OFFSET 0x2501
  17. #define MLXREG_LC_REG_CPLD1_PN_OFFSET 0x2504
  18. #define MLXREG_LC_REG_FPGA1_PN_OFFSET 0x2506
  19. #define MLXREG_LC_REG_RESET_CAUSE_OFFSET 0x251d
  20. #define MLXREG_LC_REG_LED1_OFFSET 0x2520
  21. #define MLXREG_LC_REG_GP0_OFFSET 0x252e
  22. #define MLXREG_LC_REG_FIELD_UPGRADE 0x2534
  23. #define MLXREG_LC_CHANNEL_I2C_REG 0x25dc
  24. #define MLXREG_LC_REG_CPLD1_MVER_OFFSET 0x25de
  25. #define MLXREG_LC_REG_FPGA1_MVER_OFFSET 0x25df
  26. #define MLXREG_LC_REG_MAX_POWER_OFFSET 0x25f1
  27. #define MLXREG_LC_REG_CONFIG_OFFSET 0x25fb
  28. #define MLXREG_LC_REG_MAX 0x3fff
  29. /**
  30. * enum mlxreg_lc_type - line cards types
  31. *
  32. * @MLXREG_LC_SN4800_C16: 100GbE line card with 16 QSFP28 ports;
  33. */
  34. enum mlxreg_lc_type {
  35. MLXREG_LC_SN4800_C16 = 0x0000,
  36. };
  37. /**
  38. * enum mlxreg_lc_state - line cards state
  39. *
  40. * @MLXREG_LC_INITIALIZED: line card is initialized;
  41. * @MLXREG_LC_POWERED: line card is powered;
  42. * @MLXREG_LC_SYNCED: line card is synchronized between hardware and firmware;
  43. */
  44. enum mlxreg_lc_state {
  45. MLXREG_LC_INITIALIZED = BIT(0),
  46. MLXREG_LC_POWERED = BIT(1),
  47. MLXREG_LC_SYNCED = BIT(2),
  48. };
  49. #define MLXREG_LC_CONFIGURED (MLXREG_LC_INITIALIZED | MLXREG_LC_POWERED | MLXREG_LC_SYNCED)
  50. /* mlxreg_lc - device private data
  51. * @dev: platform device;
  52. * @lock: line card lock;
  53. * @par_regmap: parent device regmap handle;
  54. * @data: pltaform core data;
  55. * @io_data: register access platform data;
  56. * @led_data: LED platform data ;
  57. * @mux_data: MUX platform data;
  58. * @led: LED device;
  59. * @io_regs: register access device;
  60. * @mux_brdinfo: mux configuration;
  61. * @mux: mux devices;
  62. * @aux_devs: I2C devices feeding by auxiliary power;
  63. * @aux_devs_num: number of I2C devices feeding by auxiliary power;
  64. * @main_devs: I2C devices feeding by main power;
  65. * @main_devs_num: number of I2C devices feeding by main power;
  66. * @state: line card state;
  67. */
  68. struct mlxreg_lc {
  69. struct device *dev;
  70. struct mutex lock; /* line card access lock */
  71. void *par_regmap;
  72. struct mlxreg_core_data *data;
  73. struct mlxreg_core_platform_data *io_data;
  74. struct mlxreg_core_platform_data *led_data;
  75. struct mlxcpld_mux_plat_data *mux_data;
  76. struct platform_device *led;
  77. struct platform_device *io_regs;
  78. struct i2c_board_info *mux_brdinfo;
  79. struct platform_device *mux;
  80. struct mlxreg_hotplug_device *aux_devs;
  81. int aux_devs_num;
  82. struct mlxreg_hotplug_device *main_devs;
  83. int main_devs_num;
  84. enum mlxreg_lc_state state;
  85. };
  86. static bool mlxreg_lc_writeable_reg(struct device *dev, unsigned int reg)
  87. {
  88. switch (reg) {
  89. case MLXREG_LC_REG_LED1_OFFSET:
  90. case MLXREG_LC_REG_GP0_OFFSET:
  91. case MLXREG_LC_REG_FIELD_UPGRADE:
  92. case MLXREG_LC_CHANNEL_I2C_REG:
  93. return true;
  94. }
  95. return false;
  96. }
  97. static bool mlxreg_lc_readable_reg(struct device *dev, unsigned int reg)
  98. {
  99. switch (reg) {
  100. case MLXREG_LC_REG_CPLD1_VER_OFFSET:
  101. case MLXREG_LC_REG_FPGA1_VER_OFFSET:
  102. case MLXREG_LC_REG_CPLD1_PN_OFFSET:
  103. case MLXREG_LC_REG_FPGA1_PN_OFFSET:
  104. case MLXREG_LC_REG_RESET_CAUSE_OFFSET:
  105. case MLXREG_LC_REG_LED1_OFFSET:
  106. case MLXREG_LC_REG_GP0_OFFSET:
  107. case MLXREG_LC_REG_FIELD_UPGRADE:
  108. case MLXREG_LC_CHANNEL_I2C_REG:
  109. case MLXREG_LC_REG_CPLD1_MVER_OFFSET:
  110. case MLXREG_LC_REG_FPGA1_MVER_OFFSET:
  111. case MLXREG_LC_REG_MAX_POWER_OFFSET:
  112. case MLXREG_LC_REG_CONFIG_OFFSET:
  113. return true;
  114. }
  115. return false;
  116. }
  117. static bool mlxreg_lc_volatile_reg(struct device *dev, unsigned int reg)
  118. {
  119. switch (reg) {
  120. case MLXREG_LC_REG_CPLD1_VER_OFFSET:
  121. case MLXREG_LC_REG_FPGA1_VER_OFFSET:
  122. case MLXREG_LC_REG_CPLD1_PN_OFFSET:
  123. case MLXREG_LC_REG_FPGA1_PN_OFFSET:
  124. case MLXREG_LC_REG_RESET_CAUSE_OFFSET:
  125. case MLXREG_LC_REG_LED1_OFFSET:
  126. case MLXREG_LC_REG_GP0_OFFSET:
  127. case MLXREG_LC_REG_FIELD_UPGRADE:
  128. case MLXREG_LC_CHANNEL_I2C_REG:
  129. case MLXREG_LC_REG_CPLD1_MVER_OFFSET:
  130. case MLXREG_LC_REG_FPGA1_MVER_OFFSET:
  131. case MLXREG_LC_REG_MAX_POWER_OFFSET:
  132. case MLXREG_LC_REG_CONFIG_OFFSET:
  133. return true;
  134. }
  135. return false;
  136. }
  137. static const struct reg_default mlxreg_lc_regmap_default[] = {
  138. { MLXREG_LC_CHANNEL_I2C_REG, 0x00 },
  139. };
  140. /* Configuration for the register map of a device with 2 bytes address space. */
  141. static const struct regmap_config mlxreg_lc_regmap_conf = {
  142. .reg_bits = 16,
  143. .val_bits = 8,
  144. .max_register = MLXREG_LC_REG_MAX,
  145. .cache_type = REGCACHE_FLAT,
  146. .writeable_reg = mlxreg_lc_writeable_reg,
  147. .readable_reg = mlxreg_lc_readable_reg,
  148. .volatile_reg = mlxreg_lc_volatile_reg,
  149. .reg_defaults = mlxreg_lc_regmap_default,
  150. .num_reg_defaults = ARRAY_SIZE(mlxreg_lc_regmap_default),
  151. };
  152. /* Default channels vector.
  153. * It contains only the channels, which physically connected to the devices,
  154. * empty channels are skipped.
  155. */
  156. static int mlxreg_lc_chan[] = {
  157. 0x04, 0x05, 0x06, 0x07, 0x08, 0x10, 0x20, 0x21, 0x22, 0x23, 0x40, 0x41,
  158. 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d,
  159. 0x4e, 0x4f
  160. };
  161. /* Defaul mux configuration. */
  162. static struct mlxcpld_mux_plat_data mlxreg_lc_mux_data[] = {
  163. {
  164. .chan_ids = mlxreg_lc_chan,
  165. .num_adaps = ARRAY_SIZE(mlxreg_lc_chan),
  166. .sel_reg_addr = MLXREG_LC_CHANNEL_I2C_REG,
  167. .reg_size = 2,
  168. },
  169. };
  170. /* Defaul mux board info. */
  171. static struct i2c_board_info mlxreg_lc_mux_brdinfo = {
  172. I2C_BOARD_INFO("i2c-mux-mlxcpld", 0x32),
  173. };
  174. /* Line card default auxiliary power static devices. */
  175. static struct i2c_board_info mlxreg_lc_aux_pwr_devices[] = {
  176. {
  177. I2C_BOARD_INFO("24c32", 0x51),
  178. },
  179. {
  180. I2C_BOARD_INFO("24c32", 0x51),
  181. },
  182. };
  183. /* Line card default auxiliary power board info. */
  184. static struct mlxreg_hotplug_device mlxreg_lc_aux_pwr_brdinfo[] = {
  185. {
  186. .brdinfo = &mlxreg_lc_aux_pwr_devices[0],
  187. .nr = 3,
  188. },
  189. {
  190. .brdinfo = &mlxreg_lc_aux_pwr_devices[1],
  191. .nr = 4,
  192. },
  193. };
  194. /* Line card default main power static devices. */
  195. static struct i2c_board_info mlxreg_lc_main_pwr_devices[] = {
  196. {
  197. I2C_BOARD_INFO("mp2975", 0x62),
  198. },
  199. {
  200. I2C_BOARD_INFO("mp2975", 0x64),
  201. },
  202. {
  203. I2C_BOARD_INFO("max11603", 0x6d),
  204. },
  205. {
  206. I2C_BOARD_INFO("lm25066", 0x15),
  207. },
  208. };
  209. /* Line card default main power board info. */
  210. static struct mlxreg_hotplug_device mlxreg_lc_main_pwr_brdinfo[] = {
  211. {
  212. .brdinfo = &mlxreg_lc_main_pwr_devices[0],
  213. .nr = 0,
  214. },
  215. {
  216. .brdinfo = &mlxreg_lc_main_pwr_devices[1],
  217. .nr = 0,
  218. },
  219. {
  220. .brdinfo = &mlxreg_lc_main_pwr_devices[2],
  221. .nr = 1,
  222. },
  223. {
  224. .brdinfo = &mlxreg_lc_main_pwr_devices[3],
  225. .nr = 2,
  226. },
  227. };
  228. /* LED default data. */
  229. static struct mlxreg_core_data mlxreg_lc_led_data[] = {
  230. {
  231. .label = "status:green",
  232. .reg = MLXREG_LC_REG_LED1_OFFSET,
  233. .mask = GENMASK(7, 4),
  234. },
  235. {
  236. .label = "status:orange",
  237. .reg = MLXREG_LC_REG_LED1_OFFSET,
  238. .mask = GENMASK(7, 4),
  239. },
  240. };
  241. static struct mlxreg_core_platform_data mlxreg_lc_led = {
  242. .identity = "pci",
  243. .data = mlxreg_lc_led_data,
  244. .counter = ARRAY_SIZE(mlxreg_lc_led_data),
  245. };
  246. /* Default register access data. */
  247. static struct mlxreg_core_data mlxreg_lc_io_data[] = {
  248. {
  249. .label = "cpld1_version",
  250. .reg = MLXREG_LC_REG_CPLD1_VER_OFFSET,
  251. .bit = GENMASK(7, 0),
  252. .mode = 0444,
  253. },
  254. {
  255. .label = "fpga1_version",
  256. .reg = MLXREG_LC_REG_FPGA1_VER_OFFSET,
  257. .bit = GENMASK(7, 0),
  258. .mode = 0444,
  259. },
  260. {
  261. .label = "cpld1_pn",
  262. .reg = MLXREG_LC_REG_CPLD1_PN_OFFSET,
  263. .bit = GENMASK(15, 0),
  264. .mode = 0444,
  265. .regnum = 2,
  266. },
  267. {
  268. .label = "fpga1_pn",
  269. .reg = MLXREG_LC_REG_FPGA1_PN_OFFSET,
  270. .bit = GENMASK(15, 0),
  271. .mode = 0444,
  272. .regnum = 2,
  273. },
  274. {
  275. .label = "cpld1_version_min",
  276. .reg = MLXREG_LC_REG_CPLD1_MVER_OFFSET,
  277. .bit = GENMASK(7, 0),
  278. .mode = 0444,
  279. },
  280. {
  281. .label = "fpga1_version_min",
  282. .reg = MLXREG_LC_REG_FPGA1_MVER_OFFSET,
  283. .bit = GENMASK(7, 0),
  284. .mode = 0444,
  285. },
  286. {
  287. .label = "reset_fpga_not_done",
  288. .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
  289. .mask = GENMASK(7, 0) & ~BIT(1),
  290. .mode = 0444,
  291. },
  292. {
  293. .label = "reset_aux_pwr_or_ref",
  294. .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
  295. .mask = GENMASK(7, 0) & ~BIT(2),
  296. .mode = 0444,
  297. },
  298. {
  299. .label = "reset_dc_dc_pwr_fail",
  300. .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
  301. .mask = GENMASK(7, 0) & ~BIT(3),
  302. .mode = 0444,
  303. },
  304. {
  305. .label = "reset_from_chassis",
  306. .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
  307. .mask = GENMASK(7, 0) & ~BIT(4),
  308. .mode = 0444,
  309. },
  310. {
  311. .label = "reset_pwr_off_from_chassis",
  312. .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
  313. .mask = GENMASK(7, 0) & ~BIT(5),
  314. .mode = 0444,
  315. },
  316. {
  317. .label = "reset_line_card",
  318. .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
  319. .mask = GENMASK(7, 0) & ~BIT(6),
  320. .mode = 0444,
  321. },
  322. {
  323. .label = "reset_line_card_pwr_en",
  324. .reg = MLXREG_LC_REG_RESET_CAUSE_OFFSET,
  325. .mask = GENMASK(7, 0) & ~BIT(7),
  326. .mode = 0444,
  327. },
  328. {
  329. .label = "cpld_upgrade_en",
  330. .reg = MLXREG_LC_REG_FIELD_UPGRADE,
  331. .mask = GENMASK(7, 0) & ~BIT(0),
  332. .mode = 0644,
  333. .secured = 1,
  334. },
  335. {
  336. .label = "fpga_upgrade_en",
  337. .reg = MLXREG_LC_REG_FIELD_UPGRADE,
  338. .mask = GENMASK(7, 0) & ~BIT(1),
  339. .mode = 0644,
  340. .secured = 1,
  341. },
  342. {
  343. .label = "qsfp_pwr_en",
  344. .reg = MLXREG_LC_REG_GP0_OFFSET,
  345. .mask = GENMASK(7, 0) & ~BIT(0),
  346. .mode = 0644,
  347. },
  348. {
  349. .label = "vpd_wp",
  350. .reg = MLXREG_LC_REG_GP0_OFFSET,
  351. .mask = GENMASK(7, 0) & ~BIT(3),
  352. .mode = 0644,
  353. .secured = 1,
  354. },
  355. {
  356. .label = "agb_spi_burn_en",
  357. .reg = MLXREG_LC_REG_GP0_OFFSET,
  358. .mask = GENMASK(7, 0) & ~BIT(5),
  359. .mode = 0644,
  360. .secured = 1,
  361. },
  362. {
  363. .label = "fpga_spi_burn_en",
  364. .reg = MLXREG_LC_REG_GP0_OFFSET,
  365. .mask = GENMASK(7, 0) & ~BIT(6),
  366. .mode = 0644,
  367. .secured = 1,
  368. },
  369. {
  370. .label = "max_power",
  371. .reg = MLXREG_LC_REG_MAX_POWER_OFFSET,
  372. .bit = GENMASK(15, 0),
  373. .mode = 0444,
  374. .regnum = 2,
  375. },
  376. {
  377. .label = "config",
  378. .reg = MLXREG_LC_REG_CONFIG_OFFSET,
  379. .bit = GENMASK(15, 0),
  380. .mode = 0444,
  381. .regnum = 2,
  382. },
  383. };
  384. static struct mlxreg_core_platform_data mlxreg_lc_regs_io = {
  385. .data = mlxreg_lc_io_data,
  386. .counter = ARRAY_SIZE(mlxreg_lc_io_data),
  387. };
  388. static int
  389. mlxreg_lc_create_static_devices(struct mlxreg_lc *mlxreg_lc, struct mlxreg_hotplug_device *devs,
  390. int size)
  391. {
  392. struct mlxreg_hotplug_device *dev = devs;
  393. int i, ret;
  394. /* Create static I2C device feeding by auxiliary or main power. */
  395. for (i = 0; i < size; i++, dev++) {
  396. dev->client = i2c_new_client_device(dev->adapter, dev->brdinfo);
  397. if (IS_ERR(dev->client)) {
  398. dev_err(mlxreg_lc->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
  399. dev->brdinfo->type, dev->nr, dev->brdinfo->addr);
  400. dev->adapter = NULL;
  401. ret = PTR_ERR(dev->client);
  402. goto fail_create_static_devices;
  403. }
  404. }
  405. return 0;
  406. fail_create_static_devices:
  407. while (--i >= 0) {
  408. dev = devs + i;
  409. i2c_unregister_device(dev->client);
  410. dev->client = NULL;
  411. }
  412. return ret;
  413. }
  414. static void
  415. mlxreg_lc_destroy_static_devices(struct mlxreg_lc *mlxreg_lc, struct mlxreg_hotplug_device *devs,
  416. int size)
  417. {
  418. struct mlxreg_hotplug_device *dev = devs;
  419. int i;
  420. /* Destroy static I2C device feeding by auxiliary or main power. */
  421. for (i = 0; i < size; i++, dev++) {
  422. if (dev->client) {
  423. i2c_unregister_device(dev->client);
  424. dev->client = NULL;
  425. }
  426. }
  427. }
  428. static int mlxreg_lc_power_on_off(struct mlxreg_lc *mlxreg_lc, u8 action)
  429. {
  430. u32 regval;
  431. int err;
  432. err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, &regval);
  433. if (err)
  434. goto regmap_read_fail;
  435. if (action)
  436. regval |= BIT(mlxreg_lc->data->slot - 1);
  437. else
  438. regval &= ~BIT(mlxreg_lc->data->slot - 1);
  439. err = regmap_write(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, regval);
  440. regmap_read_fail:
  441. return err;
  442. }
  443. static int mlxreg_lc_enable_disable(struct mlxreg_lc *mlxreg_lc, bool action)
  444. {
  445. u32 regval;
  446. int err;
  447. /*
  448. * Hardware holds the line card after powering on in the disabled state. Holding line card
  449. * in disabled state protects access to the line components, like FPGA and gearboxes.
  450. * Line card should be enabled in order to get it in operational state. Line card could be
  451. * disabled for moving it to non-operational state. Enabling line card does not affect the
  452. * line card which is already has been enabled. Disabling does not affect the disabled line
  453. * card.
  454. */
  455. err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_ena, &regval);
  456. if (err)
  457. goto regmap_read_fail;
  458. if (action)
  459. regval |= BIT(mlxreg_lc->data->slot - 1);
  460. else
  461. regval &= ~BIT(mlxreg_lc->data->slot - 1);
  462. err = regmap_write(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_ena, regval);
  463. regmap_read_fail:
  464. return err;
  465. }
  466. static int
  467. mlxreg_lc_sn4800_c16_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
  468. struct mlxreg_core_data *data)
  469. {
  470. struct device *dev = &data->hpdev.client->dev;
  471. /* Set line card configuration according to the type. */
  472. mlxreg_lc->mux_data = mlxreg_lc_mux_data;
  473. mlxreg_lc->io_data = &mlxreg_lc_regs_io;
  474. mlxreg_lc->led_data = &mlxreg_lc_led;
  475. mlxreg_lc->mux_brdinfo = &mlxreg_lc_mux_brdinfo;
  476. mlxreg_lc->aux_devs = devm_kmemdup(dev, mlxreg_lc_aux_pwr_brdinfo,
  477. sizeof(mlxreg_lc_aux_pwr_brdinfo), GFP_KERNEL);
  478. if (!mlxreg_lc->aux_devs)
  479. return -ENOMEM;
  480. mlxreg_lc->aux_devs_num = ARRAY_SIZE(mlxreg_lc_aux_pwr_brdinfo);
  481. mlxreg_lc->main_devs = devm_kmemdup(dev, mlxreg_lc_main_pwr_brdinfo,
  482. sizeof(mlxreg_lc_main_pwr_brdinfo), GFP_KERNEL);
  483. if (!mlxreg_lc->main_devs)
  484. return -ENOMEM;
  485. mlxreg_lc->main_devs_num = ARRAY_SIZE(mlxreg_lc_main_pwr_brdinfo);
  486. return 0;
  487. }
  488. static void
  489. mlxreg_lc_state_update(struct mlxreg_lc *mlxreg_lc, enum mlxreg_lc_state state, u8 action)
  490. {
  491. if (action)
  492. mlxreg_lc->state |= state;
  493. else
  494. mlxreg_lc->state &= ~state;
  495. }
  496. static void
  497. mlxreg_lc_state_update_locked(struct mlxreg_lc *mlxreg_lc, enum mlxreg_lc_state state, u8 action)
  498. {
  499. mutex_lock(&mlxreg_lc->lock);
  500. if (action)
  501. mlxreg_lc->state |= state;
  502. else
  503. mlxreg_lc->state &= ~state;
  504. mutex_unlock(&mlxreg_lc->lock);
  505. }
  506. /*
  507. * Callback is to be called from mlxreg-hotplug driver to notify about line card about received
  508. * event.
  509. */
  510. static int mlxreg_lc_event_handler(void *handle, enum mlxreg_hotplug_kind kind, u8 action)
  511. {
  512. struct mlxreg_lc *mlxreg_lc = handle;
  513. int err = 0;
  514. dev_info(mlxreg_lc->dev, "linecard#%d state %d event kind %d action %d\n",
  515. mlxreg_lc->data->slot, mlxreg_lc->state, kind, action);
  516. mutex_lock(&mlxreg_lc->lock);
  517. if (!(mlxreg_lc->state & MLXREG_LC_INITIALIZED))
  518. goto mlxreg_lc_non_initialzed_exit;
  519. switch (kind) {
  520. case MLXREG_HOTPLUG_LC_SYNCED:
  521. /*
  522. * Synchronization event - hardware and firmware are synchronized. Power on/off
  523. * line card - to allow/disallow main power source.
  524. */
  525. mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_SYNCED, action);
  526. /* Power line card if it is not powered yet. */
  527. if (!(mlxreg_lc->state & MLXREG_LC_POWERED) && action) {
  528. err = mlxreg_lc_power_on_off(mlxreg_lc, 1);
  529. if (err)
  530. goto mlxreg_lc_power_on_off_fail;
  531. }
  532. /* In case line card is configured - enable it. */
  533. if (mlxreg_lc->state & MLXREG_LC_CONFIGURED && action)
  534. err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
  535. break;
  536. case MLXREG_HOTPLUG_LC_POWERED:
  537. /* Power event - attach or de-attach line card device feeding by the main power. */
  538. if (action) {
  539. /* Do not create devices, if line card is already powered. */
  540. if (mlxreg_lc->state & MLXREG_LC_POWERED) {
  541. /* In case line card is configured - enable it. */
  542. if (mlxreg_lc->state & MLXREG_LC_CONFIGURED)
  543. err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
  544. goto mlxreg_lc_enable_disable_exit;
  545. }
  546. err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
  547. mlxreg_lc->main_devs_num);
  548. if (err)
  549. goto mlxreg_lc_create_static_devices_fail;
  550. /* In case line card is already in ready state - enable it. */
  551. if (mlxreg_lc->state & MLXREG_LC_CONFIGURED)
  552. err = mlxreg_lc_enable_disable(mlxreg_lc, 1);
  553. } else {
  554. mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
  555. mlxreg_lc->main_devs_num);
  556. }
  557. mlxreg_lc_state_update(mlxreg_lc, MLXREG_LC_POWERED, action);
  558. break;
  559. case MLXREG_HOTPLUG_LC_READY:
  560. /*
  561. * Ready event – enable line card by releasing it from reset or disable it by put
  562. * to reset state.
  563. */
  564. err = mlxreg_lc_enable_disable(mlxreg_lc, !!action);
  565. break;
  566. case MLXREG_HOTPLUG_LC_THERMAL:
  567. /* Thermal shutdown event – power off line card. */
  568. if (action)
  569. err = mlxreg_lc_power_on_off(mlxreg_lc, 0);
  570. break;
  571. default:
  572. break;
  573. }
  574. mlxreg_lc_enable_disable_exit:
  575. mlxreg_lc_power_on_off_fail:
  576. mlxreg_lc_create_static_devices_fail:
  577. mlxreg_lc_non_initialzed_exit:
  578. mutex_unlock(&mlxreg_lc->lock);
  579. return err;
  580. }
  581. /*
  582. * Callback is to be called from i2c-mux-mlxcpld driver to indicate that all adapter devices has
  583. * been created.
  584. */
  585. static int mlxreg_lc_completion_notify(void *handle, struct i2c_adapter *parent,
  586. struct i2c_adapter *adapters[])
  587. {
  588. struct mlxreg_hotplug_device *main_dev, *aux_dev;
  589. struct mlxreg_lc *mlxreg_lc = handle;
  590. u32 regval;
  591. int i, err;
  592. /* Update I2C devices feeding by auxiliary power. */
  593. aux_dev = mlxreg_lc->aux_devs;
  594. for (i = 0; i < mlxreg_lc->aux_devs_num; i++, aux_dev++) {
  595. aux_dev->adapter = adapters[aux_dev->nr];
  596. aux_dev->nr = adapters[aux_dev->nr]->nr;
  597. }
  598. err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->aux_devs,
  599. mlxreg_lc->aux_devs_num);
  600. if (err)
  601. return err;
  602. /* Update I2C devices feeding by main power. */
  603. main_dev = mlxreg_lc->main_devs;
  604. for (i = 0; i < mlxreg_lc->main_devs_num; i++, main_dev++) {
  605. main_dev->adapter = adapters[main_dev->nr];
  606. main_dev->nr = adapters[main_dev->nr]->nr;
  607. }
  608. /* Verify if line card is powered. */
  609. err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_pwr, &regval);
  610. if (err)
  611. goto mlxreg_lc_regmap_read_power_fail;
  612. if (regval & mlxreg_lc->data->mask) {
  613. err = mlxreg_lc_create_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
  614. mlxreg_lc->main_devs_num);
  615. if (err)
  616. goto mlxreg_lc_create_static_devices_failed;
  617. mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_POWERED, 1);
  618. }
  619. /* Verify if line card is synchronized. */
  620. err = regmap_read(mlxreg_lc->par_regmap, mlxreg_lc->data->reg_sync, &regval);
  621. if (err)
  622. goto mlxreg_lc_regmap_read_sync_fail;
  623. /* Power on line card if necessary. */
  624. if (regval & mlxreg_lc->data->mask) {
  625. mlxreg_lc->state |= MLXREG_LC_SYNCED;
  626. mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_SYNCED, 1);
  627. if (mlxreg_lc->state & ~MLXREG_LC_POWERED) {
  628. err = mlxreg_lc_power_on_off(mlxreg_lc, 1);
  629. if (err)
  630. goto mlxreg_lc_regmap_power_on_off_fail;
  631. }
  632. }
  633. mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_INITIALIZED, 1);
  634. return 0;
  635. mlxreg_lc_regmap_power_on_off_fail:
  636. mlxreg_lc_regmap_read_sync_fail:
  637. if (mlxreg_lc->state & MLXREG_LC_POWERED)
  638. mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
  639. mlxreg_lc->main_devs_num);
  640. mlxreg_lc_create_static_devices_failed:
  641. mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num);
  642. mlxreg_lc_regmap_read_power_fail:
  643. return err;
  644. }
  645. static int
  646. mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
  647. struct mlxreg_core_data *data)
  648. {
  649. struct device *dev = &data->hpdev.client->dev;
  650. int lsb, err;
  651. u32 regval;
  652. /* Validate line card type. */
  653. err = regmap_read(regmap, MLXREG_LC_REG_CONFIG_OFFSET, &lsb);
  654. err = (!err) ? regmap_read(regmap, MLXREG_LC_REG_CONFIG_OFFSET, &regval) : err;
  655. if (err)
  656. return err;
  657. regval = (regval & GENMASK(7, 0)) << 8 | (lsb & GENMASK(7, 0));
  658. switch (regval) {
  659. case MLXREG_LC_SN4800_C16:
  660. err = mlxreg_lc_sn4800_c16_config_init(mlxreg_lc, regmap, data);
  661. if (err) {
  662. dev_err(dev, "Failed to config client %s at bus %d at addr 0x%02x\n",
  663. data->hpdev.brdinfo->type, data->hpdev.nr,
  664. data->hpdev.brdinfo->addr);
  665. return err;
  666. }
  667. break;
  668. default:
  669. return -ENODEV;
  670. }
  671. /* Create mux infrastructure. */
  672. mlxreg_lc->mux_data->handle = mlxreg_lc;
  673. mlxreg_lc->mux_data->completion_notify = mlxreg_lc_completion_notify;
  674. mlxreg_lc->mux_brdinfo->platform_data = mlxreg_lc->mux_data;
  675. mlxreg_lc->mux = platform_device_register_resndata(dev, "i2c-mux-mlxcpld", data->hpdev.nr,
  676. NULL, 0, mlxreg_lc->mux_data,
  677. sizeof(*mlxreg_lc->mux_data));
  678. if (IS_ERR(mlxreg_lc->mux)) {
  679. dev_err(dev, "Failed to create mux infra for client %s at bus %d at addr 0x%02x\n",
  680. data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
  681. return PTR_ERR(mlxreg_lc->mux);
  682. }
  683. /* Register IO access driver. */
  684. if (mlxreg_lc->io_data) {
  685. mlxreg_lc->io_data->regmap = regmap;
  686. mlxreg_lc->io_regs =
  687. platform_device_register_resndata(dev, "mlxreg-io", data->hpdev.nr, NULL, 0,
  688. mlxreg_lc->io_data, sizeof(*mlxreg_lc->io_data));
  689. if (IS_ERR(mlxreg_lc->io_regs)) {
  690. dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n",
  691. data->hpdev.brdinfo->type, data->hpdev.nr,
  692. data->hpdev.brdinfo->addr);
  693. err = PTR_ERR(mlxreg_lc->io_regs);
  694. goto fail_register_io;
  695. }
  696. }
  697. /* Register LED driver. */
  698. if (mlxreg_lc->led_data) {
  699. mlxreg_lc->led_data->regmap = regmap;
  700. mlxreg_lc->led =
  701. platform_device_register_resndata(dev, "leds-mlxreg", data->hpdev.nr, NULL, 0,
  702. mlxreg_lc->led_data,
  703. sizeof(*mlxreg_lc->led_data));
  704. if (IS_ERR(mlxreg_lc->led)) {
  705. dev_err(dev, "Failed to create LED objects for client %s at bus %d at addr 0x%02x\n",
  706. data->hpdev.brdinfo->type, data->hpdev.nr,
  707. data->hpdev.brdinfo->addr);
  708. err = PTR_ERR(mlxreg_lc->led);
  709. goto fail_register_led;
  710. }
  711. }
  712. return 0;
  713. fail_register_led:
  714. if (mlxreg_lc->io_regs)
  715. platform_device_unregister(mlxreg_lc->io_regs);
  716. fail_register_io:
  717. if (mlxreg_lc->mux)
  718. platform_device_unregister(mlxreg_lc->mux);
  719. return err;
  720. }
  721. static void mlxreg_lc_config_exit(struct mlxreg_lc *mlxreg_lc)
  722. {
  723. /* Unregister LED driver. */
  724. if (mlxreg_lc->led)
  725. platform_device_unregister(mlxreg_lc->led);
  726. /* Unregister IO access driver. */
  727. if (mlxreg_lc->io_regs)
  728. platform_device_unregister(mlxreg_lc->io_regs);
  729. /* Remove mux infrastructure. */
  730. if (mlxreg_lc->mux)
  731. platform_device_unregister(mlxreg_lc->mux);
  732. }
  733. static int mlxreg_lc_probe(struct platform_device *pdev)
  734. {
  735. struct mlxreg_core_hotplug_platform_data *par_pdata;
  736. struct mlxreg_core_data *data;
  737. struct mlxreg_lc *mlxreg_lc;
  738. void *regmap;
  739. int i, err;
  740. data = dev_get_platdata(&pdev->dev);
  741. if (!data)
  742. return -EINVAL;
  743. mlxreg_lc = devm_kzalloc(&pdev->dev, sizeof(*mlxreg_lc), GFP_KERNEL);
  744. if (!mlxreg_lc)
  745. return -ENOMEM;
  746. mutex_init(&mlxreg_lc->lock);
  747. /* Set event notification callback. */
  748. data->notifier->user_handler = mlxreg_lc_event_handler;
  749. data->notifier->handle = mlxreg_lc;
  750. data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
  751. if (!data->hpdev.adapter) {
  752. dev_err(&pdev->dev, "Failed to get adapter for bus %d\n",
  753. data->hpdev.nr);
  754. err = -EFAULT;
  755. goto i2c_get_adapter_fail;
  756. }
  757. /* Create device at the top of line card I2C tree.*/
  758. data->hpdev.client = i2c_new_client_device(data->hpdev.adapter,
  759. data->hpdev.brdinfo);
  760. if (IS_ERR(data->hpdev.client)) {
  761. dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
  762. data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
  763. err = PTR_ERR(data->hpdev.client);
  764. goto i2c_new_device_fail;
  765. }
  766. regmap = devm_regmap_init_i2c(data->hpdev.client,
  767. &mlxreg_lc_regmap_conf);
  768. if (IS_ERR(regmap)) {
  769. dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n",
  770. data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
  771. err = PTR_ERR(regmap);
  772. goto devm_regmap_init_i2c_fail;
  773. }
  774. /* Set default registers. */
  775. for (i = 0; i < mlxreg_lc_regmap_conf.num_reg_defaults; i++) {
  776. err = regmap_write(regmap, mlxreg_lc_regmap_default[i].reg,
  777. mlxreg_lc_regmap_default[i].def);
  778. if (err) {
  779. dev_err(&pdev->dev, "Failed to set default regmap %d for client %s at bus %d at addr 0x%02x\n",
  780. i, data->hpdev.brdinfo->type, data->hpdev.nr,
  781. data->hpdev.brdinfo->addr);
  782. goto regmap_write_fail;
  783. }
  784. }
  785. /* Sync registers with hardware. */
  786. regcache_mark_dirty(regmap);
  787. err = regcache_sync(regmap);
  788. if (err) {
  789. dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n",
  790. data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
  791. goto regcache_sync_fail;
  792. }
  793. par_pdata = data->hpdev.brdinfo->platform_data;
  794. mlxreg_lc->par_regmap = par_pdata->regmap;
  795. mlxreg_lc->data = data;
  796. mlxreg_lc->dev = &pdev->dev;
  797. platform_set_drvdata(pdev, mlxreg_lc);
  798. /* Configure line card. */
  799. err = mlxreg_lc_config_init(mlxreg_lc, regmap, data);
  800. if (err)
  801. goto mlxreg_lc_config_init_fail;
  802. return 0;
  803. mlxreg_lc_config_init_fail:
  804. regcache_sync_fail:
  805. regmap_write_fail:
  806. devm_regmap_init_i2c_fail:
  807. i2c_unregister_device(data->hpdev.client);
  808. data->hpdev.client = NULL;
  809. i2c_new_device_fail:
  810. i2c_put_adapter(data->hpdev.adapter);
  811. data->hpdev.adapter = NULL;
  812. i2c_get_adapter_fail:
  813. /* Clear event notification callback and handle. */
  814. if (data->notifier) {
  815. data->notifier->user_handler = NULL;
  816. data->notifier->handle = NULL;
  817. }
  818. return err;
  819. }
  820. static int mlxreg_lc_remove(struct platform_device *pdev)
  821. {
  822. struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev);
  823. struct mlxreg_lc *mlxreg_lc = platform_get_drvdata(pdev);
  824. mlxreg_lc_state_update_locked(mlxreg_lc, MLXREG_LC_INITIALIZED, 0);
  825. /*
  826. * Probing and removing are invoked by hotplug events raised upon line card insertion and
  827. * removing. If probing procedure fails all data is cleared. However, hotplug event still
  828. * will be raised on line card removing and activate removing procedure. In this case there
  829. * is nothing to remove.
  830. */
  831. if (!data->notifier || !data->notifier->handle)
  832. return 0;
  833. /* Clear event notification callback and handle. */
  834. data->notifier->user_handler = NULL;
  835. data->notifier->handle = NULL;
  836. /* Destroy static I2C device feeding by main power. */
  837. mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
  838. mlxreg_lc->main_devs_num);
  839. /* Destroy static I2C device feeding by auxiliary power. */
  840. mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->aux_devs, mlxreg_lc->aux_devs_num);
  841. /* Unregister underlying drivers. */
  842. mlxreg_lc_config_exit(mlxreg_lc);
  843. if (data->hpdev.client) {
  844. i2c_unregister_device(data->hpdev.client);
  845. data->hpdev.client = NULL;
  846. i2c_put_adapter(data->hpdev.adapter);
  847. data->hpdev.adapter = NULL;
  848. }
  849. return 0;
  850. }
  851. static struct platform_driver mlxreg_lc_driver = {
  852. .probe = mlxreg_lc_probe,
  853. .remove = mlxreg_lc_remove,
  854. .driver = {
  855. .name = "mlxreg-lc",
  856. },
  857. };
  858. module_platform_driver(mlxreg_lc_driver);
  859. MODULE_AUTHOR("Vadim Pasternak <[email protected]>");
  860. MODULE_DESCRIPTION("Nvidia line card platform driver");
  861. MODULE_LICENSE("Dual BSD/GPL");
  862. MODULE_ALIAS("platform:mlxreg-lc");