nvsw-sn2201.c 35 KB

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