mlx-platform.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764
  1. /*
  2. * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
  3. * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the names of the copyright holders nor the names of its
  14. * contributors may be used to endorse or promote products derived from
  15. * this software without specific prior written permission.
  16. *
  17. * Alternatively, this software may be distributed under the terms of the
  18. * GNU General Public License ("GPL") version 2 as published by the Free
  19. * Software Foundation.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  25. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. * POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #include <linux/device.h>
  34. #include <linux/dmi.h>
  35. #include <linux/i2c.h>
  36. #include <linux/i2c-mux.h>
  37. #include <linux/io.h>
  38. #include <linux/module.h>
  39. #include <linux/platform_device.h>
  40. #include <linux/platform_data/i2c-mux-reg.h>
  41. #include <linux/platform_data/mlxreg.h>
  42. #include <linux/regmap.h>
  43. #define MLX_PLAT_DEVICE_NAME "mlxplat"
  44. /* LPC bus IO offsets */
  45. #define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000
  46. #define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500
  47. #define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET 0x00
  48. #define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET 0x01
  49. #define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET 0x1d
  50. #define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET 0x20
  51. #define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET 0x21
  52. #define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET 0x22
  53. #define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET 0x23
  54. #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24
  55. #define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET 0x30
  56. #define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31
  57. #define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32
  58. #define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET 0x33
  59. #define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET 0x37
  60. #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
  61. #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
  62. #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
  63. #define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET 0x41
  64. #define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50
  65. #define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET 0x51
  66. #define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET 0x52
  67. #define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET 0x58
  68. #define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET 0x59
  69. #define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET 0x5a
  70. #define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET 0x64
  71. #define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET 0x65
  72. #define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET 0x66
  73. #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
  74. #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89
  75. #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a
  76. #define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3
  77. #define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4
  78. #define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET 0xe5
  79. #define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET 0xe6
  80. #define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET 0xe7
  81. #define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET 0xe8
  82. #define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET 0xe9
  83. #define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET 0xea
  84. #define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET 0xeb
  85. #define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET 0xec
  86. #define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET 0xed
  87. #define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET 0xee
  88. #define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET 0xef
  89. #define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
  90. #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb
  91. #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda
  92. #define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL
  93. #define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
  94. MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
  95. MLXPLAT_CPLD_LPC_PIO_OFFSET)
  96. #define MLXPLAT_CPLD_LPC_REG2 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
  97. MLXPLAT_CPLD_LPC_I2C_CH2_OFF) | \
  98. MLXPLAT_CPLD_LPC_PIO_OFFSET)
  99. /* Masks for aggregation, psu, pwr and fan event in CPLD related registers. */
  100. #define MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF 0x04
  101. #define MLXPLAT_CPLD_AGGR_PSU_MASK_DEF 0x08
  102. #define MLXPLAT_CPLD_AGGR_PWR_MASK_DEF 0x08
  103. #define MLXPLAT_CPLD_AGGR_FAN_MASK_DEF 0x40
  104. #define MLXPLAT_CPLD_AGGR_MASK_DEF (MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \
  105. MLXPLAT_CPLD_AGGR_PSU_MASK_DEF | \
  106. MLXPLAT_CPLD_AGGR_FAN_MASK_DEF)
  107. #define MLXPLAT_CPLD_AGGR_ASIC_MASK_NG 0x01
  108. #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF 0x04
  109. #define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW 0xc1
  110. #define MLXPLAT_CPLD_PSU_MASK GENMASK(1, 0)
  111. #define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0)
  112. #define MLXPLAT_CPLD_FAN_MASK GENMASK(3, 0)
  113. #define MLXPLAT_CPLD_ASIC_MASK GENMASK(1, 0)
  114. #define MLXPLAT_CPLD_FAN_NG_MASK GENMASK(5, 0)
  115. #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK GENMASK(7, 4)
  116. #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK GENMASK(3, 0)
  117. /* Default I2C parent bus number */
  118. #define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR 1
  119. /* Maximum number of possible physical buses equipped on system */
  120. #define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM 16
  121. /* Number of channels in group */
  122. #define MLXPLAT_CPLD_GRP_CHNL_NUM 8
  123. /* Start channel numbers */
  124. #define MLXPLAT_CPLD_CH1 2
  125. #define MLXPLAT_CPLD_CH2 10
  126. /* Number of LPC attached MUX platform devices */
  127. #define MLXPLAT_CPLD_LPC_MUX_DEVS 2
  128. /* Hotplug devices adapter numbers */
  129. #define MLXPLAT_CPLD_NR_NONE -1
  130. #define MLXPLAT_CPLD_PSU_DEFAULT_NR 10
  131. #define MLXPLAT_CPLD_PSU_MSNXXXX_NR 4
  132. #define MLXPLAT_CPLD_FAN1_DEFAULT_NR 11
  133. #define MLXPLAT_CPLD_FAN2_DEFAULT_NR 12
  134. #define MLXPLAT_CPLD_FAN3_DEFAULT_NR 13
  135. #define MLXPLAT_CPLD_FAN4_DEFAULT_NR 14
  136. /* mlxplat_priv - platform private data
  137. * @pdev_i2c - i2c controller platform device
  138. * @pdev_mux - array of mux platform devices
  139. * @pdev_hotplug - hotplug platform devices
  140. * @pdev_led - led platform devices
  141. * @pdev_io_regs - register access platform devices
  142. * @pdev_fan - FAN platform devices
  143. */
  144. struct mlxplat_priv {
  145. struct platform_device *pdev_i2c;
  146. struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS];
  147. struct platform_device *pdev_hotplug;
  148. struct platform_device *pdev_led;
  149. struct platform_device *pdev_io_regs;
  150. struct platform_device *pdev_fan;
  151. };
  152. /* Regions for LPC I2C controller and LPC base register space */
  153. static const struct resource mlxplat_lpc_resources[] = {
  154. [0] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_I2C_BASE_ADRR,
  155. MLXPLAT_CPLD_LPC_IO_RANGE,
  156. "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO),
  157. [1] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_REG_BASE_ADRR,
  158. MLXPLAT_CPLD_LPC_IO_RANGE,
  159. "mlxplat_cpld_lpc_regs",
  160. IORESOURCE_IO),
  161. };
  162. /* Platform default channels */
  163. static const int mlxplat_default_channels[][MLXPLAT_CPLD_GRP_CHNL_NUM] = {
  164. {
  165. MLXPLAT_CPLD_CH1, MLXPLAT_CPLD_CH1 + 1, MLXPLAT_CPLD_CH1 + 2,
  166. MLXPLAT_CPLD_CH1 + 3, MLXPLAT_CPLD_CH1 + 4, MLXPLAT_CPLD_CH1 +
  167. 5, MLXPLAT_CPLD_CH1 + 6, MLXPLAT_CPLD_CH1 + 7
  168. },
  169. {
  170. MLXPLAT_CPLD_CH2, MLXPLAT_CPLD_CH2 + 1, MLXPLAT_CPLD_CH2 + 2,
  171. MLXPLAT_CPLD_CH2 + 3, MLXPLAT_CPLD_CH2 + 4, MLXPLAT_CPLD_CH2 +
  172. 5, MLXPLAT_CPLD_CH2 + 6, MLXPLAT_CPLD_CH2 + 7
  173. },
  174. };
  175. /* Platform channels for MSN21xx system family */
  176. static const int mlxplat_msn21xx_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  177. /* Platform mux data */
  178. static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = {
  179. {
  180. .parent = 1,
  181. .base_nr = MLXPLAT_CPLD_CH1,
  182. .write_only = 1,
  183. .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
  184. .reg_size = 1,
  185. .idle_in_use = 1,
  186. },
  187. {
  188. .parent = 1,
  189. .base_nr = MLXPLAT_CPLD_CH2,
  190. .write_only = 1,
  191. .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
  192. .reg_size = 1,
  193. .idle_in_use = 1,
  194. },
  195. };
  196. /* Platform hotplug devices */
  197. static struct i2c_board_info mlxplat_mlxcpld_psu[] = {
  198. {
  199. I2C_BOARD_INFO("24c02", 0x51),
  200. },
  201. {
  202. I2C_BOARD_INFO("24c02", 0x50),
  203. },
  204. };
  205. static struct i2c_board_info mlxplat_mlxcpld_ng_psu[] = {
  206. {
  207. I2C_BOARD_INFO("24c32", 0x51),
  208. },
  209. {
  210. I2C_BOARD_INFO("24c32", 0x50),
  211. },
  212. };
  213. static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
  214. {
  215. I2C_BOARD_INFO("dps460", 0x59),
  216. },
  217. {
  218. I2C_BOARD_INFO("dps460", 0x58),
  219. },
  220. };
  221. static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
  222. {
  223. I2C_BOARD_INFO("24c32", 0x50),
  224. },
  225. {
  226. I2C_BOARD_INFO("24c32", 0x50),
  227. },
  228. {
  229. I2C_BOARD_INFO("24c32", 0x50),
  230. },
  231. {
  232. I2C_BOARD_INFO("24c32", 0x50),
  233. },
  234. };
  235. /* Platform hotplug default data */
  236. static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data[] = {
  237. {
  238. .label = "psu1",
  239. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  240. .mask = BIT(0),
  241. .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
  242. .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
  243. },
  244. {
  245. .label = "psu2",
  246. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  247. .mask = BIT(1),
  248. .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
  249. .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
  250. },
  251. };
  252. static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = {
  253. {
  254. .label = "pwr1",
  255. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  256. .mask = BIT(0),
  257. .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
  258. .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
  259. },
  260. {
  261. .label = "pwr2",
  262. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  263. .mask = BIT(1),
  264. .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
  265. .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
  266. },
  267. };
  268. static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
  269. {
  270. .label = "fan1",
  271. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  272. .mask = BIT(0),
  273. .hpdev.brdinfo = &mlxplat_mlxcpld_fan[0],
  274. .hpdev.nr = MLXPLAT_CPLD_FAN1_DEFAULT_NR,
  275. },
  276. {
  277. .label = "fan2",
  278. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  279. .mask = BIT(1),
  280. .hpdev.brdinfo = &mlxplat_mlxcpld_fan[1],
  281. .hpdev.nr = MLXPLAT_CPLD_FAN2_DEFAULT_NR,
  282. },
  283. {
  284. .label = "fan3",
  285. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  286. .mask = BIT(2),
  287. .hpdev.brdinfo = &mlxplat_mlxcpld_fan[2],
  288. .hpdev.nr = MLXPLAT_CPLD_FAN3_DEFAULT_NR,
  289. },
  290. {
  291. .label = "fan4",
  292. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  293. .mask = BIT(3),
  294. .hpdev.brdinfo = &mlxplat_mlxcpld_fan[3],
  295. .hpdev.nr = MLXPLAT_CPLD_FAN4_DEFAULT_NR,
  296. },
  297. };
  298. static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data[] = {
  299. {
  300. .label = "asic1",
  301. .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
  302. .mask = MLXPLAT_CPLD_ASIC_MASK,
  303. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  304. },
  305. };
  306. static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
  307. {
  308. .data = mlxplat_mlxcpld_default_psu_items_data,
  309. .aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
  310. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  311. .mask = MLXPLAT_CPLD_PSU_MASK,
  312. .count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
  313. .inversed = 1,
  314. .health = false,
  315. },
  316. {
  317. .data = mlxplat_mlxcpld_default_pwr_items_data,
  318. .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
  319. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  320. .mask = MLXPLAT_CPLD_PWR_MASK,
  321. .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
  322. .inversed = 0,
  323. .health = false,
  324. },
  325. {
  326. .data = mlxplat_mlxcpld_default_fan_items_data,
  327. .aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
  328. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  329. .mask = MLXPLAT_CPLD_FAN_MASK,
  330. .count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
  331. .inversed = 1,
  332. .health = false,
  333. },
  334. {
  335. .data = mlxplat_mlxcpld_default_asic_items_data,
  336. .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
  337. .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
  338. .mask = MLXPLAT_CPLD_ASIC_MASK,
  339. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
  340. .inversed = 0,
  341. .health = true,
  342. },
  343. };
  344. static
  345. struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
  346. .items = mlxplat_mlxcpld_default_items,
  347. .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
  348. .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
  349. .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
  350. .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
  351. .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
  352. };
  353. static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data[] = {
  354. {
  355. .label = "pwr1",
  356. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  357. .mask = BIT(0),
  358. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  359. },
  360. {
  361. .label = "pwr2",
  362. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  363. .mask = BIT(1),
  364. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  365. },
  366. };
  367. /* Platform hotplug MSN21xx system family data */
  368. static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
  369. {
  370. .data = mlxplat_mlxcpld_msn21xx_pwr_items_data,
  371. .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
  372. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  373. .mask = MLXPLAT_CPLD_PWR_MASK,
  374. .count = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_pwr_items_data),
  375. .inversed = 0,
  376. .health = false,
  377. },
  378. {
  379. .data = mlxplat_mlxcpld_default_asic_items_data,
  380. .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
  381. .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
  382. .mask = MLXPLAT_CPLD_ASIC_MASK,
  383. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
  384. .inversed = 0,
  385. .health = true,
  386. },
  387. };
  388. static
  389. struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
  390. .items = mlxplat_mlxcpld_msn21xx_items,
  391. .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
  392. .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
  393. .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
  394. .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
  395. .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
  396. };
  397. /* Platform hotplug msn274x system family data */
  398. static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_psu_items_data[] = {
  399. {
  400. .label = "psu1",
  401. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  402. .mask = BIT(0),
  403. .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
  404. .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
  405. },
  406. {
  407. .label = "psu2",
  408. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  409. .mask = BIT(1),
  410. .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
  411. .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
  412. },
  413. };
  414. static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_pwr_items_data[] = {
  415. {
  416. .label = "pwr1",
  417. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  418. .mask = BIT(0),
  419. .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
  420. .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
  421. },
  422. {
  423. .label = "pwr2",
  424. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  425. .mask = BIT(1),
  426. .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
  427. .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
  428. },
  429. };
  430. static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_fan_items_data[] = {
  431. {
  432. .label = "fan1",
  433. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  434. .mask = BIT(0),
  435. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  436. },
  437. {
  438. .label = "fan2",
  439. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  440. .mask = BIT(1),
  441. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  442. },
  443. {
  444. .label = "fan3",
  445. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  446. .mask = BIT(2),
  447. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  448. },
  449. {
  450. .label = "fan4",
  451. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  452. .mask = BIT(3),
  453. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  454. },
  455. };
  456. static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items[] = {
  457. {
  458. .data = mlxplat_mlxcpld_msn274x_psu_items_data,
  459. .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  460. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  461. .mask = MLXPLAT_CPLD_PSU_MASK,
  462. .count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_psu_items_data),
  463. .inversed = 1,
  464. .health = false,
  465. },
  466. {
  467. .data = mlxplat_mlxcpld_default_ng_pwr_items_data,
  468. .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  469. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  470. .mask = MLXPLAT_CPLD_PWR_MASK,
  471. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
  472. .inversed = 0,
  473. .health = false,
  474. },
  475. {
  476. .data = mlxplat_mlxcpld_msn274x_fan_items_data,
  477. .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  478. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  479. .mask = MLXPLAT_CPLD_FAN_MASK,
  480. .count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_fan_items_data),
  481. .inversed = 1,
  482. .health = false,
  483. },
  484. {
  485. .data = mlxplat_mlxcpld_default_asic_items_data,
  486. .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  487. .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
  488. .mask = MLXPLAT_CPLD_ASIC_MASK,
  489. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
  490. .inversed = 0,
  491. .health = true,
  492. },
  493. };
  494. static
  495. struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn274x_data = {
  496. .items = mlxplat_mlxcpld_msn274x_items,
  497. .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items),
  498. .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
  499. .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  500. .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
  501. .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
  502. };
  503. /* Platform hotplug MSN201x system family data */
  504. static struct mlxreg_core_data mlxplat_mlxcpld_msn201x_pwr_items_data[] = {
  505. {
  506. .label = "pwr1",
  507. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  508. .mask = BIT(0),
  509. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  510. },
  511. {
  512. .label = "pwr2",
  513. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  514. .mask = BIT(1),
  515. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  516. },
  517. };
  518. static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = {
  519. {
  520. .data = mlxplat_mlxcpld_msn201x_pwr_items_data,
  521. .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
  522. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  523. .mask = MLXPLAT_CPLD_PWR_MASK,
  524. .count = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_pwr_items_data),
  525. .inversed = 0,
  526. .health = false,
  527. },
  528. {
  529. .data = mlxplat_mlxcpld_default_asic_items_data,
  530. .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
  531. .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
  532. .mask = MLXPLAT_CPLD_ASIC_MASK,
  533. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
  534. .inversed = 0,
  535. .health = true,
  536. },
  537. };
  538. static
  539. struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = {
  540. .items = mlxplat_mlxcpld_msn201x_items,
  541. .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
  542. .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
  543. .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
  544. .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
  545. .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
  546. };
  547. /* Platform hotplug next generation system family data */
  548. static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_psu_items_data[] = {
  549. {
  550. .label = "psu1",
  551. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  552. .mask = BIT(0),
  553. .hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[0],
  554. .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
  555. },
  556. {
  557. .label = "psu2",
  558. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  559. .mask = BIT(1),
  560. .hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[1],
  561. .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
  562. },
  563. };
  564. static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data[] = {
  565. {
  566. .label = "fan1",
  567. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  568. .mask = BIT(0),
  569. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  570. },
  571. {
  572. .label = "fan2",
  573. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  574. .mask = BIT(1),
  575. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  576. },
  577. {
  578. .label = "fan3",
  579. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  580. .mask = BIT(2),
  581. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  582. },
  583. {
  584. .label = "fan4",
  585. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  586. .mask = BIT(3),
  587. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  588. },
  589. {
  590. .label = "fan5",
  591. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  592. .mask = BIT(4),
  593. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  594. },
  595. {
  596. .label = "fan6",
  597. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  598. .mask = BIT(5),
  599. .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
  600. },
  601. };
  602. static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items[] = {
  603. {
  604. .data = mlxplat_mlxcpld_default_ng_psu_items_data,
  605. .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  606. .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
  607. .mask = MLXPLAT_CPLD_PSU_MASK,
  608. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_psu_items_data),
  609. .inversed = 1,
  610. .health = false,
  611. },
  612. {
  613. .data = mlxplat_mlxcpld_default_ng_pwr_items_data,
  614. .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  615. .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
  616. .mask = MLXPLAT_CPLD_PWR_MASK,
  617. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
  618. .inversed = 0,
  619. .health = false,
  620. },
  621. {
  622. .data = mlxplat_mlxcpld_default_ng_fan_items_data,
  623. .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  624. .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
  625. .mask = MLXPLAT_CPLD_FAN_NG_MASK,
  626. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
  627. .inversed = 1,
  628. .health = false,
  629. },
  630. {
  631. .data = mlxplat_mlxcpld_default_asic_items_data,
  632. .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  633. .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
  634. .mask = MLXPLAT_CPLD_ASIC_MASK,
  635. .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
  636. .inversed = 0,
  637. .health = true,
  638. },
  639. };
  640. static
  641. struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
  642. .items = mlxplat_mlxcpld_default_ng_items,
  643. .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items),
  644. .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
  645. .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
  646. .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
  647. .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
  648. };
  649. /* Platform led default data */
  650. static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
  651. {
  652. .label = "status:green",
  653. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  654. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  655. },
  656. {
  657. .label = "status:red",
  658. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  659. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
  660. },
  661. {
  662. .label = "psu:green",
  663. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  664. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  665. },
  666. {
  667. .label = "psu:red",
  668. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  669. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  670. },
  671. {
  672. .label = "fan1:green",
  673. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  674. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  675. },
  676. {
  677. .label = "fan1:red",
  678. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  679. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  680. },
  681. {
  682. .label = "fan2:green",
  683. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  684. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  685. },
  686. {
  687. .label = "fan2:red",
  688. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  689. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  690. },
  691. {
  692. .label = "fan3:green",
  693. .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
  694. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  695. },
  696. {
  697. .label = "fan3:red",
  698. .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
  699. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  700. },
  701. {
  702. .label = "fan4:green",
  703. .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
  704. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  705. },
  706. {
  707. .label = "fan4:red",
  708. .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
  709. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  710. },
  711. };
  712. static struct mlxreg_core_platform_data mlxplat_default_led_data = {
  713. .data = mlxplat_mlxcpld_default_led_data,
  714. .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_data),
  715. };
  716. /* Platform led MSN21xx system family data */
  717. static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data[] = {
  718. {
  719. .label = "status:green",
  720. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  721. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  722. },
  723. {
  724. .label = "status:red",
  725. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  726. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
  727. },
  728. {
  729. .label = "fan:green",
  730. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  731. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  732. },
  733. {
  734. .label = "fan:red",
  735. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  736. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  737. },
  738. {
  739. .label = "psu1:green",
  740. .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
  741. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  742. },
  743. {
  744. .label = "psu1:red",
  745. .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
  746. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  747. },
  748. {
  749. .label = "psu2:green",
  750. .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
  751. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  752. },
  753. {
  754. .label = "psu2:red",
  755. .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
  756. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  757. },
  758. {
  759. .label = "uid:blue",
  760. .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
  761. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  762. },
  763. };
  764. static struct mlxreg_core_platform_data mlxplat_msn21xx_led_data = {
  765. .data = mlxplat_mlxcpld_msn21xx_led_data,
  766. .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_led_data),
  767. };
  768. /* Platform led for default data for 200GbE systems */
  769. static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = {
  770. {
  771. .label = "status:green",
  772. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  773. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  774. },
  775. {
  776. .label = "status:orange",
  777. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  778. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
  779. },
  780. {
  781. .label = "psu:green",
  782. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  783. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  784. },
  785. {
  786. .label = "psu:orange",
  787. .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
  788. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  789. },
  790. {
  791. .label = "fan1:green",
  792. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  793. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  794. },
  795. {
  796. .label = "fan1:orange",
  797. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  798. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  799. },
  800. {
  801. .label = "fan2:green",
  802. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  803. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  804. },
  805. {
  806. .label = "fan2:orange",
  807. .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
  808. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  809. },
  810. {
  811. .label = "fan3:green",
  812. .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
  813. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  814. },
  815. {
  816. .label = "fan3:orange",
  817. .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
  818. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  819. },
  820. {
  821. .label = "fan4:green",
  822. .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
  823. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  824. },
  825. {
  826. .label = "fan4:orange",
  827. .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
  828. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  829. },
  830. {
  831. .label = "fan5:green",
  832. .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
  833. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  834. },
  835. {
  836. .label = "fan5:orange",
  837. .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
  838. .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
  839. },
  840. {
  841. .label = "fan6:green",
  842. .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
  843. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  844. },
  845. {
  846. .label = "fan6:orange",
  847. .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
  848. .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
  849. },
  850. };
  851. static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
  852. .data = mlxplat_mlxcpld_default_ng_led_data,
  853. .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data),
  854. };
  855. /* Platform register access default */
  856. static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = {
  857. {
  858. .label = "cpld1_version",
  859. .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
  860. .bit = GENMASK(7, 0),
  861. .mode = 0444,
  862. },
  863. {
  864. .label = "cpld2_version",
  865. .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
  866. .bit = GENMASK(7, 0),
  867. .mode = 0444,
  868. },
  869. {
  870. .label = "reset_long_pb",
  871. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  872. .mask = GENMASK(7, 0) & ~BIT(0),
  873. .mode = 0444,
  874. },
  875. {
  876. .label = "reset_short_pb",
  877. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  878. .mask = GENMASK(7, 0) & ~BIT(1),
  879. .mode = 0444,
  880. },
  881. {
  882. .label = "reset_aux_pwr_or_ref",
  883. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  884. .mask = GENMASK(7, 0) & ~BIT(2),
  885. .mode = 0444,
  886. },
  887. {
  888. .label = "reset_main_pwr_fail",
  889. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  890. .mask = GENMASK(7, 0) & ~BIT(3),
  891. .mode = 0444,
  892. },
  893. {
  894. .label = "reset_sw_reset",
  895. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  896. .mask = GENMASK(7, 0) & ~BIT(4),
  897. .mode = 0444,
  898. },
  899. {
  900. .label = "reset_fw_reset",
  901. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  902. .mask = GENMASK(7, 0) & ~BIT(5),
  903. .mode = 0444,
  904. },
  905. {
  906. .label = "reset_hotswap_or_wd",
  907. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  908. .mask = GENMASK(7, 0) & ~BIT(6),
  909. .mode = 0444,
  910. },
  911. {
  912. .label = "reset_asic_thermal",
  913. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  914. .mask = GENMASK(7, 0) & ~BIT(7),
  915. .mode = 0444,
  916. },
  917. {
  918. .label = "psu1_on",
  919. .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
  920. .mask = GENMASK(7, 0) & ~BIT(0),
  921. .mode = 0200,
  922. },
  923. {
  924. .label = "psu2_on",
  925. .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
  926. .mask = GENMASK(7, 0) & ~BIT(1),
  927. .mode = 0200,
  928. },
  929. {
  930. .label = "pwr_cycle",
  931. .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
  932. .mask = GENMASK(7, 0) & ~BIT(2),
  933. .mode = 0200,
  934. },
  935. {
  936. .label = "pwr_down",
  937. .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
  938. .mask = GENMASK(7, 0) & ~BIT(3),
  939. .mode = 0200,
  940. },
  941. {
  942. .label = "select_iio",
  943. .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
  944. .mask = GENMASK(7, 0) & ~BIT(6),
  945. .mode = 0644,
  946. },
  947. {
  948. .label = "asic_health",
  949. .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
  950. .mask = MLXPLAT_CPLD_ASIC_MASK,
  951. .bit = 1,
  952. .mode = 0444,
  953. },
  954. };
  955. static struct mlxreg_core_platform_data mlxplat_default_regs_io_data = {
  956. .data = mlxplat_mlxcpld_default_regs_io_data,
  957. .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data),
  958. };
  959. /* Platform register access MSN21xx, MSN201x, MSN274x systems families data */
  960. static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data[] = {
  961. {
  962. .label = "cpld1_version",
  963. .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
  964. .bit = GENMASK(7, 0),
  965. .mode = 0444,
  966. },
  967. {
  968. .label = "cpld2_version",
  969. .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
  970. .bit = GENMASK(7, 0),
  971. .mode = 0444,
  972. },
  973. {
  974. .label = "reset_long_pb",
  975. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  976. .mask = GENMASK(7, 0) & ~BIT(0),
  977. .mode = 0444,
  978. },
  979. {
  980. .label = "reset_short_pb",
  981. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  982. .mask = GENMASK(7, 0) & ~BIT(1),
  983. .mode = 0444,
  984. },
  985. {
  986. .label = "reset_aux_pwr_or_ref",
  987. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  988. .mask = GENMASK(7, 0) & ~BIT(2),
  989. .mode = 0444,
  990. },
  991. {
  992. .label = "reset_sw_reset",
  993. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  994. .mask = GENMASK(7, 0) & ~BIT(3),
  995. .mode = 0444,
  996. },
  997. {
  998. .label = "reset_main_pwr_fail",
  999. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  1000. .mask = GENMASK(7, 0) & ~BIT(4),
  1001. .mode = 0444,
  1002. },
  1003. {
  1004. .label = "reset_asic_thermal",
  1005. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  1006. .mask = GENMASK(7, 0) & ~BIT(5),
  1007. .mode = 0444,
  1008. },
  1009. {
  1010. .label = "reset_hotswap_or_halt",
  1011. .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
  1012. .mask = GENMASK(7, 0) & ~BIT(6),
  1013. .mode = 0444,
  1014. },
  1015. {
  1016. .label = "psu1_on",
  1017. .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
  1018. .mask = GENMASK(7, 0) & ~BIT(0),
  1019. .mode = 0200,
  1020. },
  1021. {
  1022. .label = "psu2_on",
  1023. .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
  1024. .mask = GENMASK(7, 0) & ~BIT(1),
  1025. .mode = 0200,
  1026. },
  1027. {
  1028. .label = "pwr_cycle",
  1029. .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
  1030. .mask = GENMASK(7, 0) & ~BIT(2),
  1031. .mode = 0200,
  1032. },
  1033. {
  1034. .label = "pwr_down",
  1035. .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
  1036. .mask = GENMASK(7, 0) & ~BIT(3),
  1037. .mode = 0200,
  1038. },
  1039. {
  1040. .label = "asic_health",
  1041. .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
  1042. .mask = MLXPLAT_CPLD_ASIC_MASK,
  1043. .bit = 1,
  1044. .mode = 0444,
  1045. },
  1046. };
  1047. static struct mlxreg_core_platform_data mlxplat_msn21xx_regs_io_data = {
  1048. .data = mlxplat_mlxcpld_msn21xx_regs_io_data,
  1049. .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_regs_io_data),
  1050. };
  1051. /* Platform FAN default */
  1052. static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
  1053. {
  1054. .label = "pwm1",
  1055. .reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
  1056. },
  1057. {
  1058. .label = "tacho1",
  1059. .reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
  1060. .mask = GENMASK(7, 0),
  1061. },
  1062. {
  1063. .label = "tacho2",
  1064. .reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
  1065. .mask = GENMASK(7, 0),
  1066. },
  1067. {
  1068. .label = "tacho3",
  1069. .reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
  1070. .mask = GENMASK(7, 0),
  1071. },
  1072. {
  1073. .label = "tacho4",
  1074. .reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
  1075. .mask = GENMASK(7, 0),
  1076. },
  1077. {
  1078. .label = "tacho5",
  1079. .reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
  1080. .mask = GENMASK(7, 0),
  1081. },
  1082. {
  1083. .label = "tacho6",
  1084. .reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
  1085. .mask = GENMASK(7, 0),
  1086. },
  1087. {
  1088. .label = "tacho7",
  1089. .reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
  1090. .mask = GENMASK(7, 0),
  1091. },
  1092. {
  1093. .label = "tacho8",
  1094. .reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
  1095. .mask = GENMASK(7, 0),
  1096. },
  1097. {
  1098. .label = "tacho9",
  1099. .reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
  1100. .mask = GENMASK(7, 0),
  1101. },
  1102. {
  1103. .label = "tacho10",
  1104. .reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
  1105. .mask = GENMASK(7, 0),
  1106. },
  1107. {
  1108. .label = "tacho11",
  1109. .reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
  1110. .mask = GENMASK(7, 0),
  1111. },
  1112. {
  1113. .label = "tacho12",
  1114. .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
  1115. .mask = GENMASK(7, 0),
  1116. },
  1117. };
  1118. static struct mlxreg_core_platform_data mlxplat_default_fan_data = {
  1119. .data = mlxplat_mlxcpld_default_fan_data,
  1120. .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
  1121. };
  1122. static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
  1123. {
  1124. switch (reg) {
  1125. case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
  1126. case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
  1127. case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
  1128. case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
  1129. case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
  1130. case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
  1131. case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
  1132. case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
  1133. case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
  1134. case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
  1135. case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
  1136. case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
  1137. case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
  1138. case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
  1139. case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
  1140. case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
  1141. case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
  1142. case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
  1143. case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
  1144. case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
  1145. case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
  1146. return true;
  1147. }
  1148. return false;
  1149. }
  1150. static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
  1151. {
  1152. switch (reg) {
  1153. case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
  1154. case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
  1155. case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
  1156. case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
  1157. case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
  1158. case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
  1159. case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
  1160. case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
  1161. case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
  1162. case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
  1163. case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
  1164. case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
  1165. case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
  1166. case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
  1167. case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
  1168. case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
  1169. case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
  1170. case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
  1171. case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
  1172. case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
  1173. case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
  1174. case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
  1175. case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
  1176. case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
  1177. case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
  1178. case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
  1179. case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
  1180. case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
  1181. case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
  1182. case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
  1183. case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
  1184. case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
  1185. case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
  1186. case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
  1187. case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
  1188. case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
  1189. case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
  1190. case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
  1191. case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
  1192. case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
  1193. case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
  1194. case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
  1195. return true;
  1196. }
  1197. return false;
  1198. }
  1199. static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
  1200. {
  1201. switch (reg) {
  1202. case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
  1203. case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
  1204. case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
  1205. case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
  1206. case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
  1207. case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
  1208. case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
  1209. case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
  1210. case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
  1211. case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
  1212. case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
  1213. case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
  1214. case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
  1215. case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
  1216. case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
  1217. case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
  1218. case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
  1219. case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
  1220. case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
  1221. case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
  1222. case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
  1223. case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
  1224. case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
  1225. case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
  1226. case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
  1227. case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
  1228. case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
  1229. case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
  1230. case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
  1231. case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
  1232. case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
  1233. case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
  1234. case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
  1235. case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
  1236. case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
  1237. case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
  1238. case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
  1239. case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
  1240. case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
  1241. case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
  1242. return true;
  1243. }
  1244. return false;
  1245. }
  1246. static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
  1247. { MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
  1248. { MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
  1249. { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
  1250. };
  1251. struct mlxplat_mlxcpld_regmap_context {
  1252. void __iomem *base;
  1253. };
  1254. static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx;
  1255. static int
  1256. mlxplat_mlxcpld_reg_read(void *context, unsigned int reg, unsigned int *val)
  1257. {
  1258. struct mlxplat_mlxcpld_regmap_context *ctx = context;
  1259. *val = ioread8(ctx->base + reg);
  1260. return 0;
  1261. }
  1262. static int
  1263. mlxplat_mlxcpld_reg_write(void *context, unsigned int reg, unsigned int val)
  1264. {
  1265. struct mlxplat_mlxcpld_regmap_context *ctx = context;
  1266. iowrite8(val, ctx->base + reg);
  1267. return 0;
  1268. }
  1269. static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
  1270. .reg_bits = 8,
  1271. .val_bits = 8,
  1272. .max_register = 255,
  1273. .cache_type = REGCACHE_FLAT,
  1274. .writeable_reg = mlxplat_mlxcpld_writeable_reg,
  1275. .readable_reg = mlxplat_mlxcpld_readable_reg,
  1276. .volatile_reg = mlxplat_mlxcpld_volatile_reg,
  1277. .reg_defaults = mlxplat_mlxcpld_regmap_default,
  1278. .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_default),
  1279. .reg_read = mlxplat_mlxcpld_reg_read,
  1280. .reg_write = mlxplat_mlxcpld_reg_write,
  1281. };
  1282. static struct resource mlxplat_mlxcpld_resources[] = {
  1283. [0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
  1284. };
  1285. static struct platform_device *mlxplat_dev;
  1286. static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
  1287. static struct mlxreg_core_platform_data *mlxplat_led;
  1288. static struct mlxreg_core_platform_data *mlxplat_regs_io;
  1289. static struct mlxreg_core_platform_data *mlxplat_fan;
  1290. static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
  1291. {
  1292. int i;
  1293. for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
  1294. mlxplat_mux_data[i].values = mlxplat_default_channels[i];
  1295. mlxplat_mux_data[i].n_values =
  1296. ARRAY_SIZE(mlxplat_default_channels[i]);
  1297. }
  1298. mlxplat_hotplug = &mlxplat_mlxcpld_default_data;
  1299. mlxplat_hotplug->deferred_nr =
  1300. mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
  1301. mlxplat_led = &mlxplat_default_led_data;
  1302. mlxplat_regs_io = &mlxplat_default_regs_io_data;
  1303. return 1;
  1304. };
  1305. static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
  1306. {
  1307. int i;
  1308. for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
  1309. mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
  1310. mlxplat_mux_data[i].n_values =
  1311. ARRAY_SIZE(mlxplat_msn21xx_channels);
  1312. }
  1313. mlxplat_hotplug = &mlxplat_mlxcpld_msn21xx_data;
  1314. mlxplat_hotplug->deferred_nr =
  1315. mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
  1316. mlxplat_led = &mlxplat_msn21xx_led_data;
  1317. mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
  1318. return 1;
  1319. };
  1320. static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
  1321. {
  1322. int i;
  1323. for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
  1324. mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
  1325. mlxplat_mux_data[i].n_values =
  1326. ARRAY_SIZE(mlxplat_msn21xx_channels);
  1327. }
  1328. mlxplat_hotplug = &mlxplat_mlxcpld_msn274x_data;
  1329. mlxplat_hotplug->deferred_nr =
  1330. mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
  1331. mlxplat_led = &mlxplat_default_led_data;
  1332. mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
  1333. return 1;
  1334. };
  1335. static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
  1336. {
  1337. int i;
  1338. for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
  1339. mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
  1340. mlxplat_mux_data[i].n_values =
  1341. ARRAY_SIZE(mlxplat_msn21xx_channels);
  1342. }
  1343. mlxplat_hotplug = &mlxplat_mlxcpld_msn201x_data;
  1344. mlxplat_hotplug->deferred_nr =
  1345. mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
  1346. mlxplat_led = &mlxplat_default_ng_led_data;
  1347. mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
  1348. return 1;
  1349. };
  1350. static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
  1351. {
  1352. int i;
  1353. for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
  1354. mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
  1355. mlxplat_mux_data[i].n_values =
  1356. ARRAY_SIZE(mlxplat_msn21xx_channels);
  1357. }
  1358. mlxplat_hotplug = &mlxplat_mlxcpld_default_ng_data;
  1359. mlxplat_hotplug->deferred_nr =
  1360. mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
  1361. mlxplat_led = &mlxplat_msn21xx_led_data;
  1362. mlxplat_fan = &mlxplat_default_fan_data;
  1363. return 1;
  1364. };
  1365. static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
  1366. {
  1367. .callback = mlxplat_dmi_msn274x_matched,
  1368. .matches = {
  1369. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1370. DMI_MATCH(DMI_PRODUCT_NAME, "MSN274"),
  1371. },
  1372. },
  1373. {
  1374. .callback = mlxplat_dmi_default_matched,
  1375. .matches = {
  1376. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1377. DMI_MATCH(DMI_PRODUCT_NAME, "MSN24"),
  1378. },
  1379. },
  1380. {
  1381. .callback = mlxplat_dmi_default_matched,
  1382. .matches = {
  1383. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1384. DMI_MATCH(DMI_PRODUCT_NAME, "MSN27"),
  1385. },
  1386. },
  1387. {
  1388. .callback = mlxplat_dmi_default_matched,
  1389. .matches = {
  1390. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1391. DMI_MATCH(DMI_PRODUCT_NAME, "MSB"),
  1392. },
  1393. },
  1394. {
  1395. .callback = mlxplat_dmi_default_matched,
  1396. .matches = {
  1397. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1398. DMI_MATCH(DMI_PRODUCT_NAME, "MSX"),
  1399. },
  1400. },
  1401. {
  1402. .callback = mlxplat_dmi_msn21xx_matched,
  1403. .matches = {
  1404. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1405. DMI_MATCH(DMI_PRODUCT_NAME, "MSN21"),
  1406. },
  1407. },
  1408. {
  1409. .callback = mlxplat_dmi_msn201x_matched,
  1410. .matches = {
  1411. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1412. DMI_MATCH(DMI_PRODUCT_NAME, "MSN201"),
  1413. },
  1414. },
  1415. {
  1416. .callback = mlxplat_dmi_qmb7xx_matched,
  1417. .matches = {
  1418. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1419. DMI_MATCH(DMI_PRODUCT_NAME, "QMB7"),
  1420. },
  1421. },
  1422. {
  1423. .callback = mlxplat_dmi_qmb7xx_matched,
  1424. .matches = {
  1425. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1426. DMI_MATCH(DMI_PRODUCT_NAME, "SN37"),
  1427. },
  1428. },
  1429. {
  1430. .callback = mlxplat_dmi_qmb7xx_matched,
  1431. .matches = {
  1432. DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
  1433. DMI_MATCH(DMI_PRODUCT_NAME, "SN34"),
  1434. },
  1435. },
  1436. {
  1437. .callback = mlxplat_dmi_default_matched,
  1438. .matches = {
  1439. DMI_MATCH(DMI_BOARD_NAME, "VMOD0001"),
  1440. },
  1441. },
  1442. {
  1443. .callback = mlxplat_dmi_msn21xx_matched,
  1444. .matches = {
  1445. DMI_MATCH(DMI_BOARD_NAME, "VMOD0002"),
  1446. },
  1447. },
  1448. {
  1449. .callback = mlxplat_dmi_msn274x_matched,
  1450. .matches = {
  1451. DMI_MATCH(DMI_BOARD_NAME, "VMOD0003"),
  1452. },
  1453. },
  1454. {
  1455. .callback = mlxplat_dmi_msn201x_matched,
  1456. .matches = {
  1457. DMI_MATCH(DMI_BOARD_NAME, "VMOD0004"),
  1458. },
  1459. },
  1460. {
  1461. .callback = mlxplat_dmi_qmb7xx_matched,
  1462. .matches = {
  1463. DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"),
  1464. },
  1465. },
  1466. { }
  1467. };
  1468. MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table);
  1469. static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
  1470. {
  1471. struct i2c_adapter *search_adap;
  1472. int shift, i;
  1473. /* Scan adapters from expected id to verify it is free. */
  1474. *nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR;
  1475. for (i = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; i <
  1476. MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM; i++) {
  1477. search_adap = i2c_get_adapter(i);
  1478. if (search_adap) {
  1479. i2c_put_adapter(search_adap);
  1480. continue;
  1481. }
  1482. /* Return if expected parent adapter is free. */
  1483. if (i == MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR)
  1484. return 0;
  1485. break;
  1486. }
  1487. /* Return with error if free id for adapter is not found. */
  1488. if (i == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM)
  1489. return -ENODEV;
  1490. /* Shift adapter ids, since expected parent adapter is not free. */
  1491. *nr = i;
  1492. for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
  1493. shift = *nr - mlxplat_mux_data[i].parent;
  1494. mlxplat_mux_data[i].parent = *nr;
  1495. mlxplat_mux_data[i].base_nr += shift;
  1496. if (shift > 0)
  1497. mlxplat_hotplug->shift_nr = shift;
  1498. }
  1499. return 0;
  1500. }
  1501. static int __init mlxplat_init(void)
  1502. {
  1503. struct mlxplat_priv *priv;
  1504. int i, j, nr, err;
  1505. if (!dmi_check_system(mlxplat_dmi_table))
  1506. return -ENODEV;
  1507. mlxplat_dev = platform_device_register_simple(MLX_PLAT_DEVICE_NAME, -1,
  1508. mlxplat_lpc_resources,
  1509. ARRAY_SIZE(mlxplat_lpc_resources));
  1510. if (IS_ERR(mlxplat_dev))
  1511. return PTR_ERR(mlxplat_dev);
  1512. priv = devm_kzalloc(&mlxplat_dev->dev, sizeof(struct mlxplat_priv),
  1513. GFP_KERNEL);
  1514. if (!priv) {
  1515. err = -ENOMEM;
  1516. goto fail_alloc;
  1517. }
  1518. platform_set_drvdata(mlxplat_dev, priv);
  1519. err = mlxplat_mlxcpld_verify_bus_topology(&nr);
  1520. if (nr < 0)
  1521. goto fail_alloc;
  1522. nr = (nr == MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM) ? -1 : nr;
  1523. priv->pdev_i2c = platform_device_register_simple("i2c_mlxcpld", nr,
  1524. NULL, 0);
  1525. if (IS_ERR(priv->pdev_i2c)) {
  1526. err = PTR_ERR(priv->pdev_i2c);
  1527. goto fail_alloc;
  1528. }
  1529. for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
  1530. priv->pdev_mux[i] = platform_device_register_resndata(
  1531. &mlxplat_dev->dev,
  1532. "i2c-mux-reg", i, NULL,
  1533. 0, &mlxplat_mux_data[i],
  1534. sizeof(mlxplat_mux_data[i]));
  1535. if (IS_ERR(priv->pdev_mux[i])) {
  1536. err = PTR_ERR(priv->pdev_mux[i]);
  1537. goto fail_platform_mux_register;
  1538. }
  1539. }
  1540. mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev,
  1541. mlxplat_lpc_resources[1].start, 1);
  1542. if (!mlxplat_mlxcpld_regmap_ctx.base) {
  1543. err = -ENOMEM;
  1544. goto fail_platform_mux_register;
  1545. }
  1546. mlxplat_hotplug->regmap = devm_regmap_init(&mlxplat_dev->dev, NULL,
  1547. &mlxplat_mlxcpld_regmap_ctx,
  1548. &mlxplat_mlxcpld_regmap_config);
  1549. if (IS_ERR(mlxplat_hotplug->regmap)) {
  1550. err = PTR_ERR(mlxplat_hotplug->regmap);
  1551. goto fail_platform_mux_register;
  1552. }
  1553. priv->pdev_hotplug = platform_device_register_resndata(
  1554. &mlxplat_dev->dev, "mlxreg-hotplug",
  1555. PLATFORM_DEVID_NONE,
  1556. mlxplat_mlxcpld_resources,
  1557. ARRAY_SIZE(mlxplat_mlxcpld_resources),
  1558. mlxplat_hotplug, sizeof(*mlxplat_hotplug));
  1559. if (IS_ERR(priv->pdev_hotplug)) {
  1560. err = PTR_ERR(priv->pdev_hotplug);
  1561. goto fail_platform_mux_register;
  1562. }
  1563. /* Set default registers. */
  1564. for (j = 0; j < mlxplat_mlxcpld_regmap_config.num_reg_defaults; j++) {
  1565. err = regmap_write(mlxplat_hotplug->regmap,
  1566. mlxplat_mlxcpld_regmap_default[j].reg,
  1567. mlxplat_mlxcpld_regmap_default[j].def);
  1568. if (err)
  1569. goto fail_platform_mux_register;
  1570. }
  1571. /* Add LED driver. */
  1572. mlxplat_led->regmap = mlxplat_hotplug->regmap;
  1573. priv->pdev_led = platform_device_register_resndata(
  1574. &mlxplat_dev->dev, "leds-mlxreg",
  1575. PLATFORM_DEVID_NONE, NULL, 0,
  1576. mlxplat_led, sizeof(*mlxplat_led));
  1577. if (IS_ERR(priv->pdev_led)) {
  1578. err = PTR_ERR(priv->pdev_led);
  1579. goto fail_platform_hotplug_register;
  1580. }
  1581. /* Add registers io access driver. */
  1582. if (mlxplat_regs_io) {
  1583. mlxplat_regs_io->regmap = mlxplat_hotplug->regmap;
  1584. priv->pdev_io_regs = platform_device_register_resndata(
  1585. &mlxplat_dev->dev, "mlxreg-io",
  1586. PLATFORM_DEVID_NONE, NULL, 0,
  1587. mlxplat_regs_io,
  1588. sizeof(*mlxplat_regs_io));
  1589. if (IS_ERR(priv->pdev_io_regs)) {
  1590. err = PTR_ERR(priv->pdev_io_regs);
  1591. goto fail_platform_led_register;
  1592. }
  1593. }
  1594. /* Add FAN driver. */
  1595. if (mlxplat_fan) {
  1596. mlxplat_fan->regmap = mlxplat_hotplug->regmap;
  1597. priv->pdev_fan = platform_device_register_resndata(
  1598. &mlxplat_dev->dev, "mlxreg-fan",
  1599. PLATFORM_DEVID_NONE, NULL, 0,
  1600. mlxplat_fan,
  1601. sizeof(*mlxplat_fan));
  1602. if (IS_ERR(priv->pdev_fan)) {
  1603. err = PTR_ERR(priv->pdev_fan);
  1604. goto fail_platform_io_regs_register;
  1605. }
  1606. }
  1607. /* Sync registers with hardware. */
  1608. regcache_mark_dirty(mlxplat_hotplug->regmap);
  1609. err = regcache_sync(mlxplat_hotplug->regmap);
  1610. if (err)
  1611. goto fail_platform_fan_register;
  1612. return 0;
  1613. fail_platform_fan_register:
  1614. if (mlxplat_fan)
  1615. platform_device_unregister(priv->pdev_fan);
  1616. fail_platform_io_regs_register:
  1617. if (mlxplat_regs_io)
  1618. platform_device_unregister(priv->pdev_io_regs);
  1619. fail_platform_led_register:
  1620. platform_device_unregister(priv->pdev_led);
  1621. fail_platform_hotplug_register:
  1622. platform_device_unregister(priv->pdev_hotplug);
  1623. fail_platform_mux_register:
  1624. while (--i >= 0)
  1625. platform_device_unregister(priv->pdev_mux[i]);
  1626. platform_device_unregister(priv->pdev_i2c);
  1627. fail_alloc:
  1628. platform_device_unregister(mlxplat_dev);
  1629. return err;
  1630. }
  1631. module_init(mlxplat_init);
  1632. static void __exit mlxplat_exit(void)
  1633. {
  1634. struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
  1635. int i;
  1636. if (priv->pdev_fan)
  1637. platform_device_unregister(priv->pdev_fan);
  1638. if (priv->pdev_io_regs)
  1639. platform_device_unregister(priv->pdev_io_regs);
  1640. platform_device_unregister(priv->pdev_led);
  1641. platform_device_unregister(priv->pdev_hotplug);
  1642. for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--)
  1643. platform_device_unregister(priv->pdev_mux[i]);
  1644. platform_device_unregister(priv->pdev_i2c);
  1645. platform_device_unregister(mlxplat_dev);
  1646. }
  1647. module_exit(mlxplat_exit);
  1648. MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)");
  1649. MODULE_DESCRIPTION("Mellanox platform driver");
  1650. MODULE_LICENSE("Dual BSD/GPL");