smpro-errmon.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Ampere Computing SoC's SMpro Error Monitoring Driver
  4. *
  5. * Copyright (c) 2022, Ampere Computing LLC
  6. *
  7. */
  8. #include <linux/mod_devicetable.h>
  9. #include <linux/module.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/regmap.h>
  12. /* GPI RAS Error Registers */
  13. #define GPI_RAS_ERR 0x7E
  14. /* Core and L2C Error Registers */
  15. #define CORE_CE_ERR_CNT 0x80
  16. #define CORE_CE_ERR_LEN 0x81
  17. #define CORE_CE_ERR_DATA 0x82
  18. #define CORE_UE_ERR_CNT 0x83
  19. #define CORE_UE_ERR_LEN 0x84
  20. #define CORE_UE_ERR_DATA 0x85
  21. /* Memory Error Registers */
  22. #define MEM_CE_ERR_CNT 0x90
  23. #define MEM_CE_ERR_LEN 0x91
  24. #define MEM_CE_ERR_DATA 0x92
  25. #define MEM_UE_ERR_CNT 0x93
  26. #define MEM_UE_ERR_LEN 0x94
  27. #define MEM_UE_ERR_DATA 0x95
  28. /* RAS Error/Warning Registers */
  29. #define ERR_SMPRO_TYPE 0xA0
  30. #define ERR_PMPRO_TYPE 0xA1
  31. #define ERR_SMPRO_INFO_LO 0xA2
  32. #define ERR_SMPRO_INFO_HI 0xA3
  33. #define ERR_SMPRO_DATA_LO 0xA4
  34. #define ERR_SMPRO_DATA_HI 0xA5
  35. #define WARN_SMPRO_INFO_LO 0xAA
  36. #define WARN_SMPRO_INFO_HI 0xAB
  37. #define ERR_PMPRO_INFO_LO 0xA6
  38. #define ERR_PMPRO_INFO_HI 0xA7
  39. #define ERR_PMPRO_DATA_LO 0xA8
  40. #define ERR_PMPRO_DATA_HI 0xA9
  41. #define WARN_PMPRO_INFO_LO 0xAC
  42. #define WARN_PMPRO_INFO_HI 0xAD
  43. /* Boot Stage Register */
  44. #define BOOTSTAGE 0xB0
  45. #define DIMM_SYNDROME_SEL 0xB4
  46. #define DIMM_SYNDROME_ERR 0xB5
  47. #define DIMM_SYNDROME_STAGE 4
  48. /* PCIE Error Registers */
  49. #define PCIE_CE_ERR_CNT 0xC0
  50. #define PCIE_CE_ERR_LEN 0xC1
  51. #define PCIE_CE_ERR_DATA 0xC2
  52. #define PCIE_UE_ERR_CNT 0xC3
  53. #define PCIE_UE_ERR_LEN 0xC4
  54. #define PCIE_UE_ERR_DATA 0xC5
  55. /* Other Error Registers */
  56. #define OTHER_CE_ERR_CNT 0xD0
  57. #define OTHER_CE_ERR_LEN 0xD1
  58. #define OTHER_CE_ERR_DATA 0xD2
  59. #define OTHER_UE_ERR_CNT 0xD8
  60. #define OTHER_UE_ERR_LEN 0xD9
  61. #define OTHER_UE_ERR_DATA 0xDA
  62. /* Event Data Registers */
  63. #define VRD_WARN_FAULT_EVENT_DATA 0x78
  64. #define VRD_HOT_EVENT_DATA 0x79
  65. #define DIMM_HOT_EVENT_DATA 0x7A
  66. #define DIMM_2X_REFRESH_EVENT_DATA 0x96
  67. #define MAX_READ_BLOCK_LENGTH 48
  68. #define RAS_SMPRO_ERR 0
  69. #define RAS_PMPRO_ERR 1
  70. enum RAS_48BYTES_ERR_TYPES {
  71. CORE_CE_ERR,
  72. CORE_UE_ERR,
  73. MEM_CE_ERR,
  74. MEM_UE_ERR,
  75. PCIE_CE_ERR,
  76. PCIE_UE_ERR,
  77. OTHER_CE_ERR,
  78. OTHER_UE_ERR,
  79. NUM_48BYTES_ERR_TYPE,
  80. };
  81. struct smpro_error_hdr {
  82. u8 count; /* Number of the RAS errors */
  83. u8 len; /* Number of data bytes */
  84. u8 data; /* Start of 48-byte data */
  85. u8 max_cnt; /* Max num of errors */
  86. };
  87. /*
  88. * Included Address of registers to get Count, Length of data and Data
  89. * of the 48 bytes error data
  90. */
  91. static struct smpro_error_hdr smpro_error_table[] = {
  92. [CORE_CE_ERR] = {
  93. .count = CORE_CE_ERR_CNT,
  94. .len = CORE_CE_ERR_LEN,
  95. .data = CORE_CE_ERR_DATA,
  96. .max_cnt = 32
  97. },
  98. [CORE_UE_ERR] = {
  99. .count = CORE_UE_ERR_CNT,
  100. .len = CORE_UE_ERR_LEN,
  101. .data = CORE_UE_ERR_DATA,
  102. .max_cnt = 32
  103. },
  104. [MEM_CE_ERR] = {
  105. .count = MEM_CE_ERR_CNT,
  106. .len = MEM_CE_ERR_LEN,
  107. .data = MEM_CE_ERR_DATA,
  108. .max_cnt = 16
  109. },
  110. [MEM_UE_ERR] = {
  111. .count = MEM_UE_ERR_CNT,
  112. .len = MEM_UE_ERR_LEN,
  113. .data = MEM_UE_ERR_DATA,
  114. .max_cnt = 16
  115. },
  116. [PCIE_CE_ERR] = {
  117. .count = PCIE_CE_ERR_CNT,
  118. .len = PCIE_CE_ERR_LEN,
  119. .data = PCIE_CE_ERR_DATA,
  120. .max_cnt = 96
  121. },
  122. [PCIE_UE_ERR] = {
  123. .count = PCIE_UE_ERR_CNT,
  124. .len = PCIE_UE_ERR_LEN,
  125. .data = PCIE_UE_ERR_DATA,
  126. .max_cnt = 96
  127. },
  128. [OTHER_CE_ERR] = {
  129. .count = OTHER_CE_ERR_CNT,
  130. .len = OTHER_CE_ERR_LEN,
  131. .data = OTHER_CE_ERR_DATA,
  132. .max_cnt = 8
  133. },
  134. [OTHER_UE_ERR] = {
  135. .count = OTHER_UE_ERR_CNT,
  136. .len = OTHER_UE_ERR_LEN,
  137. .data = OTHER_UE_ERR_DATA,
  138. .max_cnt = 8
  139. },
  140. };
  141. /*
  142. * List of SCP registers which are used to get
  143. * one type of RAS Internal errors.
  144. */
  145. struct smpro_int_error_hdr {
  146. u8 type;
  147. u8 info_l;
  148. u8 info_h;
  149. u8 data_l;
  150. u8 data_h;
  151. u8 warn_l;
  152. u8 warn_h;
  153. };
  154. static struct smpro_int_error_hdr list_smpro_int_error_hdr[] = {
  155. [RAS_SMPRO_ERR] = {
  156. .type = ERR_SMPRO_TYPE,
  157. .info_l = ERR_SMPRO_INFO_LO,
  158. .info_h = ERR_SMPRO_INFO_HI,
  159. .data_l = ERR_SMPRO_DATA_LO,
  160. .data_h = ERR_SMPRO_DATA_HI,
  161. .warn_l = WARN_SMPRO_INFO_LO,
  162. .warn_h = WARN_SMPRO_INFO_HI,
  163. },
  164. [RAS_PMPRO_ERR] = {
  165. .type = ERR_PMPRO_TYPE,
  166. .info_l = ERR_PMPRO_INFO_LO,
  167. .info_h = ERR_PMPRO_INFO_HI,
  168. .data_l = ERR_PMPRO_DATA_LO,
  169. .data_h = ERR_PMPRO_DATA_HI,
  170. .warn_l = WARN_PMPRO_INFO_LO,
  171. .warn_h = WARN_PMPRO_INFO_HI,
  172. },
  173. };
  174. struct smpro_errmon {
  175. struct regmap *regmap;
  176. };
  177. enum EVENT_TYPES {
  178. VRD_WARN_FAULT_EVENT,
  179. VRD_HOT_EVENT,
  180. DIMM_HOT_EVENT,
  181. DIMM_2X_REFRESH_EVENT,
  182. NUM_EVENTS_TYPE,
  183. };
  184. /* Included Address of event source and data registers */
  185. static u8 smpro_event_table[NUM_EVENTS_TYPE] = {
  186. VRD_WARN_FAULT_EVENT_DATA,
  187. VRD_HOT_EVENT_DATA,
  188. DIMM_HOT_EVENT_DATA,
  189. DIMM_2X_REFRESH_EVENT_DATA,
  190. };
  191. static ssize_t smpro_event_data_read(struct device *dev,
  192. struct device_attribute *da, char *buf,
  193. int channel)
  194. {
  195. struct smpro_errmon *errmon = dev_get_drvdata(dev);
  196. s32 event_data;
  197. int ret;
  198. ret = regmap_read(errmon->regmap, smpro_event_table[channel], &event_data);
  199. if (ret)
  200. return ret;
  201. /* Clear event after read */
  202. if (event_data != 0)
  203. regmap_write(errmon->regmap, smpro_event_table[channel], event_data);
  204. return sysfs_emit(buf, "%04x\n", event_data);
  205. }
  206. static ssize_t smpro_overflow_data_read(struct device *dev, struct device_attribute *da,
  207. char *buf, int channel)
  208. {
  209. struct smpro_errmon *errmon = dev_get_drvdata(dev);
  210. struct smpro_error_hdr *err_info;
  211. s32 err_count;
  212. int ret;
  213. err_info = &smpro_error_table[channel];
  214. ret = regmap_read(errmon->regmap, err_info->count, &err_count);
  215. if (ret)
  216. return ret;
  217. /* Bit 8 indicates the overflow status */
  218. return sysfs_emit(buf, "%d\n", (err_count & BIT(8)) ? 1 : 0);
  219. }
  220. static ssize_t smpro_error_data_read(struct device *dev, struct device_attribute *da,
  221. char *buf, int channel)
  222. {
  223. struct smpro_errmon *errmon = dev_get_drvdata(dev);
  224. unsigned char err_data[MAX_READ_BLOCK_LENGTH];
  225. struct smpro_error_hdr *err_info;
  226. s32 err_count, err_length;
  227. int ret;
  228. err_info = &smpro_error_table[channel];
  229. ret = regmap_read(errmon->regmap, err_info->count, &err_count);
  230. /* Error count is the low byte */
  231. err_count &= 0xff;
  232. if (ret || !err_count || err_count > err_info->max_cnt)
  233. return ret;
  234. ret = regmap_read(errmon->regmap, err_info->len, &err_length);
  235. if (ret || err_length <= 0)
  236. return ret;
  237. if (err_length > MAX_READ_BLOCK_LENGTH)
  238. err_length = MAX_READ_BLOCK_LENGTH;
  239. memset(err_data, 0x00, MAX_READ_BLOCK_LENGTH);
  240. ret = regmap_noinc_read(errmon->regmap, err_info->data, err_data, err_length);
  241. if (ret < 0)
  242. return ret;
  243. /* clear the error */
  244. ret = regmap_write(errmon->regmap, err_info->count, 0x100);
  245. if (ret)
  246. return ret;
  247. /*
  248. * The output of Core/Memory/PCIe/Others UE/CE errors follows the format
  249. * specified in section 5.8.1 CE/UE Error Data record in
  250. * Altra SOC BMC Interface specification.
  251. */
  252. return sysfs_emit(buf, "%*phN\n", MAX_READ_BLOCK_LENGTH, err_data);
  253. }
  254. /*
  255. * Output format:
  256. * <4-byte hex value of error info><4-byte hex value of error extensive data>
  257. * Where:
  258. * + error info : The error information
  259. * + error data : Extensive data (32 bits)
  260. * Reference to section 5.10 RAS Internal Error Register Definition in
  261. * Altra SOC BMC Interface specification
  262. */
  263. static ssize_t smpro_internal_err_read(struct device *dev, struct device_attribute *da,
  264. char *buf, int channel)
  265. {
  266. struct smpro_errmon *errmon = dev_get_drvdata(dev);
  267. struct smpro_int_error_hdr *err_info;
  268. unsigned int err[4] = { 0 };
  269. unsigned int err_type;
  270. unsigned int val;
  271. int ret;
  272. /* read error status */
  273. ret = regmap_read(errmon->regmap, GPI_RAS_ERR, &val);
  274. if (ret)
  275. return ret;
  276. if ((channel == RAS_SMPRO_ERR && !(val & BIT(0))) ||
  277. (channel == RAS_PMPRO_ERR && !(val & BIT(1))))
  278. return 0;
  279. err_info = &list_smpro_int_error_hdr[channel];
  280. ret = regmap_read(errmon->regmap, err_info->type, &val);
  281. if (ret)
  282. return ret;
  283. err_type = (val & BIT(1)) ? BIT(1) :
  284. (val & BIT(2)) ? BIT(2) : 0;
  285. if (!err_type)
  286. return 0;
  287. ret = regmap_read(errmon->regmap, err_info->info_l, err + 1);
  288. if (ret)
  289. return ret;
  290. ret = regmap_read(errmon->regmap, err_info->info_h, err);
  291. if (ret)
  292. return ret;
  293. if (err_type & BIT(2)) {
  294. /* Error with data type */
  295. ret = regmap_read(errmon->regmap, err_info->data_l, err + 3);
  296. if (ret)
  297. return ret;
  298. ret = regmap_read(errmon->regmap, err_info->data_h, err + 2);
  299. if (ret)
  300. return ret;
  301. }
  302. /* clear the read errors */
  303. ret = regmap_write(errmon->regmap, err_info->type, err_type);
  304. if (ret)
  305. return ret;
  306. return sysfs_emit(buf, "%*phN\n", (int)sizeof(err), err);
  307. }
  308. /*
  309. * Output format:
  310. * <4-byte hex value of warining info>
  311. * Reference to section 5.10 RAS Internal Error Register Definition in
  312. * Altra SOC BMC Interface specification
  313. */
  314. static ssize_t smpro_internal_warn_read(struct device *dev, struct device_attribute *da,
  315. char *buf, int channel)
  316. {
  317. struct smpro_errmon *errmon = dev_get_drvdata(dev);
  318. struct smpro_int_error_hdr *err_info;
  319. unsigned int warn[2] = { 0 };
  320. unsigned int val;
  321. int ret;
  322. /* read error status */
  323. ret = regmap_read(errmon->regmap, GPI_RAS_ERR, &val);
  324. if (ret)
  325. return ret;
  326. if ((channel == RAS_SMPRO_ERR && !(val & BIT(0))) ||
  327. (channel == RAS_PMPRO_ERR && !(val & BIT(1))))
  328. return 0;
  329. err_info = &list_smpro_int_error_hdr[channel];
  330. ret = regmap_read(errmon->regmap, err_info->type, &val);
  331. if (ret)
  332. return ret;
  333. if (!(val & BIT(0)))
  334. return 0;
  335. ret = regmap_read(errmon->regmap, err_info->warn_l, warn + 1);
  336. if (ret)
  337. return ret;
  338. ret = regmap_read(errmon->regmap, err_info->warn_h, warn);
  339. if (ret)
  340. return ret;
  341. /* clear the warning */
  342. ret = regmap_write(errmon->regmap, err_info->type, BIT(0));
  343. if (ret)
  344. return ret;
  345. return sysfs_emit(buf, "%*phN\n", (int)sizeof(warn), warn);
  346. }
  347. #define ERROR_OVERFLOW_RO(_error, _index) \
  348. static ssize_t overflow_##_error##_show(struct device *dev, \
  349. struct device_attribute *da, \
  350. char *buf) \
  351. { \
  352. return smpro_overflow_data_read(dev, da, buf, _index); \
  353. } \
  354. static DEVICE_ATTR_RO(overflow_##_error)
  355. ERROR_OVERFLOW_RO(core_ce, CORE_CE_ERR);
  356. ERROR_OVERFLOW_RO(core_ue, CORE_UE_ERR);
  357. ERROR_OVERFLOW_RO(mem_ce, MEM_CE_ERR);
  358. ERROR_OVERFLOW_RO(mem_ue, MEM_UE_ERR);
  359. ERROR_OVERFLOW_RO(pcie_ce, PCIE_CE_ERR);
  360. ERROR_OVERFLOW_RO(pcie_ue, PCIE_UE_ERR);
  361. ERROR_OVERFLOW_RO(other_ce, OTHER_CE_ERR);
  362. ERROR_OVERFLOW_RO(other_ue, OTHER_UE_ERR);
  363. #define ERROR_RO(_error, _index) \
  364. static ssize_t error_##_error##_show(struct device *dev, \
  365. struct device_attribute *da, \
  366. char *buf) \
  367. { \
  368. return smpro_error_data_read(dev, da, buf, _index); \
  369. } \
  370. static DEVICE_ATTR_RO(error_##_error)
  371. ERROR_RO(core_ce, CORE_CE_ERR);
  372. ERROR_RO(core_ue, CORE_UE_ERR);
  373. ERROR_RO(mem_ce, MEM_CE_ERR);
  374. ERROR_RO(mem_ue, MEM_UE_ERR);
  375. ERROR_RO(pcie_ce, PCIE_CE_ERR);
  376. ERROR_RO(pcie_ue, PCIE_UE_ERR);
  377. ERROR_RO(other_ce, OTHER_CE_ERR);
  378. ERROR_RO(other_ue, OTHER_UE_ERR);
  379. static ssize_t error_smpro_show(struct device *dev, struct device_attribute *da, char *buf)
  380. {
  381. return smpro_internal_err_read(dev, da, buf, RAS_SMPRO_ERR);
  382. }
  383. static DEVICE_ATTR_RO(error_smpro);
  384. static ssize_t error_pmpro_show(struct device *dev, struct device_attribute *da, char *buf)
  385. {
  386. return smpro_internal_err_read(dev, da, buf, RAS_PMPRO_ERR);
  387. }
  388. static DEVICE_ATTR_RO(error_pmpro);
  389. static ssize_t warn_smpro_show(struct device *dev, struct device_attribute *da, char *buf)
  390. {
  391. return smpro_internal_warn_read(dev, da, buf, RAS_SMPRO_ERR);
  392. }
  393. static DEVICE_ATTR_RO(warn_smpro);
  394. static ssize_t warn_pmpro_show(struct device *dev, struct device_attribute *da, char *buf)
  395. {
  396. return smpro_internal_warn_read(dev, da, buf, RAS_PMPRO_ERR);
  397. }
  398. static DEVICE_ATTR_RO(warn_pmpro);
  399. #define EVENT_RO(_event, _index) \
  400. static ssize_t event_##_event##_show(struct device *dev, \
  401. struct device_attribute *da, \
  402. char *buf) \
  403. { \
  404. return smpro_event_data_read(dev, da, buf, _index); \
  405. } \
  406. static DEVICE_ATTR_RO(event_##_event)
  407. EVENT_RO(vrd_warn_fault, VRD_WARN_FAULT_EVENT);
  408. EVENT_RO(vrd_hot, VRD_HOT_EVENT);
  409. EVENT_RO(dimm_hot, DIMM_HOT_EVENT);
  410. EVENT_RO(dimm_2x_refresh, DIMM_2X_REFRESH_EVENT);
  411. static ssize_t smpro_dimm_syndrome_read(struct device *dev, struct device_attribute *da,
  412. char *buf, unsigned int slot)
  413. {
  414. struct smpro_errmon *errmon = dev_get_drvdata(dev);
  415. unsigned int data;
  416. int ret;
  417. ret = regmap_read(errmon->regmap, BOOTSTAGE, &data);
  418. if (ret)
  419. return ret;
  420. /* check for valid stage */
  421. data = (data >> 8) & 0xff;
  422. if (data != DIMM_SYNDROME_STAGE)
  423. return ret;
  424. /* Write the slot ID to retrieve Error Syndrome */
  425. ret = regmap_write(errmon->regmap, DIMM_SYNDROME_SEL, slot);
  426. if (ret)
  427. return ret;
  428. /* Read the Syndrome error */
  429. ret = regmap_read(errmon->regmap, DIMM_SYNDROME_ERR, &data);
  430. if (ret || !data)
  431. return ret;
  432. return sysfs_emit(buf, "%04x\n", data);
  433. }
  434. #define EVENT_DIMM_SYNDROME(_slot) \
  435. static ssize_t event_dimm##_slot##_syndrome_show(struct device *dev, \
  436. struct device_attribute *da, \
  437. char *buf) \
  438. { \
  439. return smpro_dimm_syndrome_read(dev, da, buf, _slot); \
  440. } \
  441. static DEVICE_ATTR_RO(event_dimm##_slot##_syndrome)
  442. EVENT_DIMM_SYNDROME(0);
  443. EVENT_DIMM_SYNDROME(1);
  444. EVENT_DIMM_SYNDROME(2);
  445. EVENT_DIMM_SYNDROME(3);
  446. EVENT_DIMM_SYNDROME(4);
  447. EVENT_DIMM_SYNDROME(5);
  448. EVENT_DIMM_SYNDROME(6);
  449. EVENT_DIMM_SYNDROME(7);
  450. EVENT_DIMM_SYNDROME(8);
  451. EVENT_DIMM_SYNDROME(9);
  452. EVENT_DIMM_SYNDROME(10);
  453. EVENT_DIMM_SYNDROME(11);
  454. EVENT_DIMM_SYNDROME(12);
  455. EVENT_DIMM_SYNDROME(13);
  456. EVENT_DIMM_SYNDROME(14);
  457. EVENT_DIMM_SYNDROME(15);
  458. static struct attribute *smpro_errmon_attrs[] = {
  459. &dev_attr_overflow_core_ce.attr,
  460. &dev_attr_overflow_core_ue.attr,
  461. &dev_attr_overflow_mem_ce.attr,
  462. &dev_attr_overflow_mem_ue.attr,
  463. &dev_attr_overflow_pcie_ce.attr,
  464. &dev_attr_overflow_pcie_ue.attr,
  465. &dev_attr_overflow_other_ce.attr,
  466. &dev_attr_overflow_other_ue.attr,
  467. &dev_attr_error_core_ce.attr,
  468. &dev_attr_error_core_ue.attr,
  469. &dev_attr_error_mem_ce.attr,
  470. &dev_attr_error_mem_ue.attr,
  471. &dev_attr_error_pcie_ce.attr,
  472. &dev_attr_error_pcie_ue.attr,
  473. &dev_attr_error_other_ce.attr,
  474. &dev_attr_error_other_ue.attr,
  475. &dev_attr_error_smpro.attr,
  476. &dev_attr_error_pmpro.attr,
  477. &dev_attr_warn_smpro.attr,
  478. &dev_attr_warn_pmpro.attr,
  479. &dev_attr_event_vrd_warn_fault.attr,
  480. &dev_attr_event_vrd_hot.attr,
  481. &dev_attr_event_dimm_hot.attr,
  482. &dev_attr_event_dimm_2x_refresh.attr,
  483. &dev_attr_event_dimm0_syndrome.attr,
  484. &dev_attr_event_dimm1_syndrome.attr,
  485. &dev_attr_event_dimm2_syndrome.attr,
  486. &dev_attr_event_dimm3_syndrome.attr,
  487. &dev_attr_event_dimm4_syndrome.attr,
  488. &dev_attr_event_dimm5_syndrome.attr,
  489. &dev_attr_event_dimm6_syndrome.attr,
  490. &dev_attr_event_dimm7_syndrome.attr,
  491. &dev_attr_event_dimm8_syndrome.attr,
  492. &dev_attr_event_dimm9_syndrome.attr,
  493. &dev_attr_event_dimm10_syndrome.attr,
  494. &dev_attr_event_dimm11_syndrome.attr,
  495. &dev_attr_event_dimm12_syndrome.attr,
  496. &dev_attr_event_dimm13_syndrome.attr,
  497. &dev_attr_event_dimm14_syndrome.attr,
  498. &dev_attr_event_dimm15_syndrome.attr,
  499. NULL
  500. };
  501. ATTRIBUTE_GROUPS(smpro_errmon);
  502. static int smpro_errmon_probe(struct platform_device *pdev)
  503. {
  504. struct smpro_errmon *errmon;
  505. errmon = devm_kzalloc(&pdev->dev, sizeof(struct smpro_errmon), GFP_KERNEL);
  506. if (!errmon)
  507. return -ENOMEM;
  508. platform_set_drvdata(pdev, errmon);
  509. errmon->regmap = dev_get_regmap(pdev->dev.parent, NULL);
  510. if (!errmon->regmap)
  511. return -ENODEV;
  512. return 0;
  513. }
  514. static struct platform_driver smpro_errmon_driver = {
  515. .probe = smpro_errmon_probe,
  516. .driver = {
  517. .name = "smpro-errmon",
  518. .dev_groups = smpro_errmon_groups,
  519. },
  520. };
  521. module_platform_driver(smpro_errmon_driver);
  522. MODULE_AUTHOR("Tung Nguyen <tung.nguyen@amperecomputing.com>");
  523. MODULE_AUTHOR("Thinh Pham <thinh.pham@amperecomputing.com>");
  524. MODULE_AUTHOR("Hoang Nguyen <hnguyen@amperecomputing.com>");
  525. MODULE_AUTHOR("Thu Nguyen <thu@os.amperecomputing.com>");
  526. MODULE_AUTHOR("Quan Nguyen <quan@os.amperecomputing.com>");
  527. MODULE_DESCRIPTION("Ampere Altra SMpro driver");
  528. MODULE_LICENSE("GPL");