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