1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2018-2019, Intel Corporation 4 * Copyright (C) 2025, Altera Corporation 5 */ 6 7 #include <linux/arm-smccc.h> 8 #include <linux/bitfield.h> 9 #include <linux/completion.h> 10 #include <linux/kobject.h> 11 #include <linux/module.h> 12 #include <linux/mutex.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/firmware/intel/stratix10-svc-client.h> 16 #include <linux/string.h> 17 #include <linux/sysfs.h> 18 #include <linux/delay.h> 19 20 #define RSU_ERASE_SIZE_MASK GENMASK_ULL(63, 32) 21 #define RSU_DCMF0_MASK GENMASK_ULL(31, 0) 22 #define RSU_DCMF1_MASK GENMASK_ULL(63, 32) 23 #define RSU_DCMF2_MASK GENMASK_ULL(31, 0) 24 #define RSU_DCMF3_MASK GENMASK_ULL(63, 32) 25 #define RSU_DCMF0_STATUS_MASK GENMASK_ULL(15, 0) 26 #define RSU_DCMF1_STATUS_MASK GENMASK_ULL(31, 16) 27 #define RSU_DCMF2_STATUS_MASK GENMASK_ULL(47, 32) 28 #define RSU_DCMF3_STATUS_MASK GENMASK_ULL(63, 48) 29 30 #define RSU_TIMEOUT (msecs_to_jiffies(SVC_RSU_REQUEST_TIMEOUT_MS)) 31 32 #define INVALID_RETRY_COUNTER 0xFF 33 #define INVALID_DCMF_VERSION 0xFF 34 #define INVALID_DCMF_STATUS 0xFFFFFFFF 35 #define INVALID_SPT_ADDRESS 0x0 36 37 #define RSU_RETRY_SLEEP_MS (1U) 38 #define RSU_ASYNC_MSG_RETRY (3U) 39 #define RSU_GET_SPT_RESP_LEN (4 * sizeof(unsigned int)) 40 41 typedef void (*rsu_callback)(struct stratix10_svc_client *client, 42 struct stratix10_svc_cb_data *data); 43 /** 44 * struct stratix10_rsu_priv - rsu data structure 45 * @chan: pointer to the allocated service channel 46 * @client: active service client 47 * @completion: state for callback completion 48 * @lock: a mutex to protect callback completion state 49 * @status.current_image: address of image currently running in flash 50 * @status.fail_image: address of failed image in flash 51 * @status.version: the interface version number of RSU firmware 52 * @status.state: the state of RSU system 53 * @status.error_details: error code 54 * @status.error_location: the error offset inside the image that failed 55 * @dcmf_version.dcmf0: Quartus dcmf0 version 56 * @dcmf_version.dcmf1: Quartus dcmf1 version 57 * @dcmf_version.dcmf2: Quartus dcmf2 version 58 * @dcmf_version.dcmf3: Quartus dcmf3 version 59 * @dcmf_status.dcmf0: dcmf0 status 60 * @dcmf_status.dcmf1: dcmf1 status 61 * @dcmf_status.dcmf2: dcmf2 status 62 * @dcmf_status.dcmf3: dcmf3 status 63 * @retry_counter: the current image's retry counter 64 * @max_retry: the preset max retry value 65 * @spt0_address: address of spt0 66 * @spt1_address: address of spt1 67 */ 68 struct stratix10_rsu_priv { 69 struct stratix10_svc_chan *chan; 70 struct stratix10_svc_client client; 71 struct completion completion; 72 struct mutex lock; 73 struct { 74 unsigned long current_image; 75 unsigned long fail_image; 76 unsigned int version; 77 unsigned int state; 78 unsigned int error_details; 79 unsigned int error_location; 80 } status; 81 82 struct { 83 unsigned int dcmf0; 84 unsigned int dcmf1; 85 unsigned int dcmf2; 86 unsigned int dcmf3; 87 } dcmf_version; 88 89 struct { 90 unsigned int dcmf0; 91 unsigned int dcmf1; 92 unsigned int dcmf2; 93 unsigned int dcmf3; 94 } dcmf_status; 95 96 unsigned int retry_counter; 97 unsigned int max_retry; 98 99 unsigned long spt0_address; 100 unsigned long spt1_address; 101 }; 102 103 typedef void (*rsu_async_callback)(struct device *dev, 104 struct stratix10_rsu_priv *priv, struct stratix10_svc_cb_data *data); 105 106 /** 107 * rsu_async_status_callback() - Status callback from rsu_async_send() 108 * @dev: pointer to device object 109 * @priv: pointer to priv object 110 * @data: pointer to callback data structure 111 * 112 * Callback from rsu_async_send() to get the system rsu error status. 113 */ 114 static void rsu_async_status_callback(struct device *dev, 115 struct stratix10_rsu_priv *priv, 116 struct stratix10_svc_cb_data *data) 117 { 118 struct arm_smccc_1_2_regs *res = (struct arm_smccc_1_2_regs *)data->kaddr1; 119 120 priv->status.current_image = res->a2; 121 priv->status.fail_image = res->a3; 122 priv->status.state = res->a4; 123 priv->status.version = res->a5; 124 priv->status.error_location = res->a7; 125 priv->status.error_details = res->a8; 126 priv->retry_counter = res->a9; 127 } 128 129 /** 130 * rsu_command_callback() - Update callback from Intel Service Layer 131 * @client: pointer to client 132 * @data: pointer to callback data structure 133 * 134 * Callback from Intel service layer for RSU commands. 135 */ 136 static void rsu_command_callback(struct stratix10_svc_client *client, 137 struct stratix10_svc_cb_data *data) 138 { 139 struct stratix10_rsu_priv *priv = client->priv; 140 141 if (data->status == BIT(SVC_STATUS_NO_SUPPORT)) 142 dev_warn(client->dev, "Secure FW doesn't support notify\n"); 143 else if (data->status == BIT(SVC_STATUS_ERROR)) 144 dev_err(client->dev, "Failure, returned status is %lu\n", 145 BIT(data->status)); 146 147 complete(&priv->completion); 148 } 149 150 151 /** 152 * rsu_max_retry_callback() - Callback from Intel service layer for getting 153 * the max retry value from the firmware 154 * @client: pointer to client 155 * @data: pointer to callback data structure 156 * 157 * Callback from Intel service layer for max retry. 158 */ 159 static void rsu_max_retry_callback(struct stratix10_svc_client *client, 160 struct stratix10_svc_cb_data *data) 161 { 162 struct stratix10_rsu_priv *priv = client->priv; 163 unsigned int *max_retry = (unsigned int *)data->kaddr1; 164 165 if (data->status == BIT(SVC_STATUS_OK)) 166 priv->max_retry = *max_retry; 167 else if (data->status == BIT(SVC_STATUS_NO_SUPPORT)) 168 dev_warn(client->dev, "Secure FW doesn't support max retry\n"); 169 else 170 dev_err(client->dev, "Failed to get max retry %lu\n", 171 BIT(data->status)); 172 173 complete(&priv->completion); 174 } 175 176 /** 177 * rsu_dcmf_version_callback() - Callback from Intel service layer for getting 178 * the DCMF version 179 * @client: pointer to client 180 * @data: pointer to callback data structure 181 * 182 * Callback from Intel service layer for DCMF version number 183 */ 184 static void rsu_dcmf_version_callback(struct stratix10_svc_client *client, 185 struct stratix10_svc_cb_data *data) 186 { 187 struct stratix10_rsu_priv *priv = client->priv; 188 unsigned long long *value1 = (unsigned long long *)data->kaddr1; 189 unsigned long long *value2 = (unsigned long long *)data->kaddr2; 190 191 if (data->status == BIT(SVC_STATUS_OK)) { 192 priv->dcmf_version.dcmf0 = FIELD_GET(RSU_DCMF0_MASK, *value1); 193 priv->dcmf_version.dcmf1 = FIELD_GET(RSU_DCMF1_MASK, *value1); 194 priv->dcmf_version.dcmf2 = FIELD_GET(RSU_DCMF2_MASK, *value2); 195 priv->dcmf_version.dcmf3 = FIELD_GET(RSU_DCMF3_MASK, *value2); 196 } else 197 dev_err(client->dev, "failed to get DCMF version\n"); 198 199 complete(&priv->completion); 200 } 201 202 /** 203 * rsu_dcmf_status_callback() - Callback from Intel service layer for getting 204 * the DCMF status 205 * @client: pointer to client 206 * @data: pointer to callback data structure 207 * 208 * Callback from Intel service layer for DCMF status 209 */ 210 static void rsu_dcmf_status_callback(struct stratix10_svc_client *client, 211 struct stratix10_svc_cb_data *data) 212 { 213 struct stratix10_rsu_priv *priv = client->priv; 214 unsigned long long *value = (unsigned long long *)data->kaddr1; 215 216 if (data->status == BIT(SVC_STATUS_OK)) { 217 priv->dcmf_status.dcmf0 = FIELD_GET(RSU_DCMF0_STATUS_MASK, 218 *value); 219 priv->dcmf_status.dcmf1 = FIELD_GET(RSU_DCMF1_STATUS_MASK, 220 *value); 221 priv->dcmf_status.dcmf2 = FIELD_GET(RSU_DCMF2_STATUS_MASK, 222 *value); 223 priv->dcmf_status.dcmf3 = FIELD_GET(RSU_DCMF3_STATUS_MASK, 224 *value); 225 } else 226 dev_err(client->dev, "failed to get DCMF status\n"); 227 228 complete(&priv->completion); 229 } 230 231 /** 232 * rsu_async_get_spt_table_callback() - Callback to be used by the rsu_async_send() 233 * to retrieve the SPT table information. 234 * @dev: pointer to device object 235 * @priv: pointer to priv object 236 * @data: pointer to callback data structure 237 */ 238 static void rsu_async_get_spt_table_callback(struct device *dev, 239 struct stratix10_rsu_priv *priv, 240 struct stratix10_svc_cb_data *data) 241 { 242 priv->spt0_address = *((unsigned long *)data->kaddr1); 243 priv->spt1_address = *((unsigned long *)data->kaddr2); 244 } 245 246 /** 247 * __rsu_send_msg_locked() - send a message to Intel service layer 248 * @priv: pointer to rsu private data 249 * @command: RSU status or update command 250 * @arg: the request argument, the bitstream address or notify status 251 * @callback: function pointer for the callback (status or update) 252 * 253 * Perform the actual SMC transaction. The caller must hold @priv->lock. 254 * 255 * Returns 0 on success or a negative errno on failure. 256 */ 257 static int __rsu_send_msg_locked(struct stratix10_rsu_priv *priv, 258 enum stratix10_svc_command_code command, 259 unsigned long arg, 260 rsu_callback callback) 261 { 262 struct stratix10_svc_client_msg msg; 263 int ret; 264 265 lockdep_assert_held(&priv->lock); 266 267 reinit_completion(&priv->completion); 268 priv->client.receive_cb = callback; 269 270 msg.command = command; 271 if (arg) 272 msg.arg[0] = arg; 273 274 ret = stratix10_svc_send(priv->chan, &msg); 275 if (ret < 0) 276 goto status_done; 277 278 ret = wait_for_completion_interruptible_timeout(&priv->completion, 279 RSU_TIMEOUT); 280 if (!ret) { 281 dev_err(priv->client.dev, 282 "timeout waiting for SMC call\n"); 283 ret = -ETIMEDOUT; 284 goto status_done; 285 } else if (ret < 0) { 286 dev_err(priv->client.dev, 287 "error %d waiting for SMC call\n", ret); 288 goto status_done; 289 } else { 290 ret = 0; 291 } 292 293 status_done: 294 stratix10_svc_done(priv->chan); 295 return ret; 296 } 297 298 /** 299 * rsu_send_msg() - send a message to Intel service layer 300 * @priv: pointer to rsu private data 301 * @command: RSU status or update command 302 * @arg: the request argument, the bitstream address or notify status 303 * @callback: function pointer for the callback (status or update) 304 * 305 * Start an Intel service layer transaction to perform the SMC call that 306 * is necessary to get RSU boot log or set the address of bitstream to 307 * boot after reboot. This call will block until the RSU lock can be 308 * acquired. 309 * 310 * Returns 0 on success or a negative errno on failure. 311 */ 312 static int rsu_send_msg(struct stratix10_rsu_priv *priv, 313 enum stratix10_svc_command_code command, 314 unsigned long arg, 315 rsu_callback callback) 316 { 317 int ret; 318 319 mutex_lock(&priv->lock); 320 ret = __rsu_send_msg_locked(priv, command, arg, callback); 321 mutex_unlock(&priv->lock); 322 return ret; 323 } 324 325 /** 326 * rsu_try_send_msg() - non-blocking variant of rsu_send_msg() 327 * @priv: pointer to rsu private data 328 * @command: RSU status or update command 329 * @arg: the request argument, the bitstream address or notify status 330 * @callback: function pointer for the callback (status or update) 331 * 332 * Same as rsu_send_msg() but returns -EBUSY immediately when another 333 * RSU operation is already in flight, instead of waiting for the lock. 334 * 335 * Returns 0 on success, -EBUSY if the RSU is busy, or another negative 336 * errno on failure. 337 */ 338 static int rsu_try_send_msg(struct stratix10_rsu_priv *priv, 339 enum stratix10_svc_command_code command, 340 unsigned long arg, 341 rsu_callback callback) 342 { 343 int ret; 344 345 if (!mutex_trylock(&priv->lock)) 346 return -EBUSY; 347 ret = __rsu_send_msg_locked(priv, command, arg, callback); 348 mutex_unlock(&priv->lock); 349 return ret; 350 } 351 352 /** 353 * soc64_async_callback() - Callback from Intel service layer for async requests 354 * @ptr: pointer to the completion object 355 */ 356 static void soc64_async_callback(void *ptr) 357 { 358 if (ptr) 359 complete(ptr); 360 } 361 362 /** 363 * rsu_send_async_msg() - send an async message to Intel service layer 364 * @dev: pointer to device object 365 * @priv: pointer to rsu private data 366 * @command: RSU status or update command 367 * @arg: the request argument, notify status 368 * @callback: function pointer for the callback (status or update) 369 */ 370 static int rsu_send_async_msg(struct device *dev, struct stratix10_rsu_priv *priv, 371 enum stratix10_svc_command_code command, 372 unsigned long arg, 373 rsu_async_callback callback) 374 { 375 struct stratix10_svc_client_msg msg = {0}; 376 struct stratix10_svc_cb_data data = {0}; 377 struct completion completion; 378 int status, index, ret; 379 void *handle = NULL; 380 381 msg.command = command; 382 msg.arg[0] = arg; 383 384 init_completion(&completion); 385 386 for (index = 0; index < RSU_ASYNC_MSG_RETRY; index++) { 387 status = stratix10_svc_async_send(priv->chan, &msg, 388 &handle, soc64_async_callback, 389 &completion); 390 if (status == 0) 391 break; 392 dev_warn(dev, "Failed to send async message\n"); 393 msleep(RSU_RETRY_SLEEP_MS); 394 } 395 396 if (status && !handle) { 397 dev_err(dev, "Failed to send async message\n"); 398 return -ETIMEDOUT; 399 } 400 401 ret = wait_for_completion_io_timeout(&completion, RSU_TIMEOUT); 402 if (ret > 0) 403 dev_dbg(dev, "Received async interrupt\n"); 404 else if (ret == 0) 405 dev_dbg(dev, "Timeout occurred. Trying to poll the response\n"); 406 407 for (index = 0; index < RSU_ASYNC_MSG_RETRY; index++) { 408 status = stratix10_svc_async_poll(priv->chan, handle, &data); 409 if (status == -EAGAIN) { 410 dev_dbg(dev, "Async message is still in progress\n"); 411 } else if (status < 0) { 412 dev_alert(dev, "Failed to poll async message\n"); 413 ret = -ETIMEDOUT; 414 } else if (status == 0) { 415 ret = 0; 416 break; 417 } 418 msleep(RSU_RETRY_SLEEP_MS); 419 } 420 421 if (ret) { 422 dev_err(dev, "Failed to get async response\n"); 423 goto status_done; 424 } 425 426 if (data.status == 0) { 427 ret = 0; 428 if (callback) 429 callback(dev, priv, &data); 430 } else { 431 dev_err(dev, "%s returned 0x%x from SDM\n", __func__, 432 data.status); 433 ret = -EFAULT; 434 } 435 436 status_done: 437 stratix10_svc_async_done(priv->chan, handle); 438 return ret; 439 } 440 441 /* 442 * This driver exposes some optional features of the Intel Stratix 10 SoC FPGA. 443 * The sysfs interfaces exposed here are FPGA Remote System Update (RSU) 444 * related. They allow user space software to query the configuration system 445 * status and to request optional reboot behavior specific to Intel FPGAs. 446 */ 447 448 static ssize_t current_image_show(struct device *dev, 449 struct device_attribute *attr, char *buf) 450 { 451 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 452 453 if (!priv) 454 return -ENODEV; 455 456 return sprintf(buf, "0x%08lx\n", priv->status.current_image); 457 } 458 459 static ssize_t fail_image_show(struct device *dev, 460 struct device_attribute *attr, char *buf) 461 { 462 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 463 464 if (!priv) 465 return -ENODEV; 466 467 return sprintf(buf, "0x%08lx\n", priv->status.fail_image); 468 } 469 470 static ssize_t version_show(struct device *dev, struct device_attribute *attr, 471 char *buf) 472 { 473 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 474 475 if (!priv) 476 return -ENODEV; 477 478 return sprintf(buf, "0x%08x\n", priv->status.version); 479 } 480 481 static ssize_t state_show(struct device *dev, struct device_attribute *attr, 482 char *buf) 483 { 484 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 485 486 if (!priv) 487 return -ENODEV; 488 489 return sprintf(buf, "0x%08x\n", priv->status.state); 490 } 491 492 static ssize_t error_location_show(struct device *dev, 493 struct device_attribute *attr, char *buf) 494 { 495 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 496 497 if (!priv) 498 return -ENODEV; 499 500 return sprintf(buf, "0x%08x\n", priv->status.error_location); 501 } 502 503 static ssize_t error_details_show(struct device *dev, 504 struct device_attribute *attr, char *buf) 505 { 506 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 507 508 if (!priv) 509 return -ENODEV; 510 511 return sprintf(buf, "0x%08x\n", priv->status.error_details); 512 } 513 514 static ssize_t retry_counter_show(struct device *dev, 515 struct device_attribute *attr, char *buf) 516 { 517 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 518 519 if (!priv) 520 return -ENODEV; 521 522 return sprintf(buf, "0x%08x\n", priv->retry_counter); 523 } 524 525 static ssize_t max_retry_show(struct device *dev, 526 struct device_attribute *attr, char *buf) 527 { 528 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 529 530 if (!priv) 531 return -ENODEV; 532 533 return sysfs_emit(buf, "0x%08x\n", priv->max_retry); 534 } 535 536 static ssize_t dcmf0_show(struct device *dev, 537 struct device_attribute *attr, char *buf) 538 { 539 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 540 541 if (!priv) 542 return -ENODEV; 543 544 return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf0); 545 } 546 547 static ssize_t dcmf1_show(struct device *dev, 548 struct device_attribute *attr, char *buf) 549 { 550 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 551 552 if (!priv) 553 return -ENODEV; 554 555 return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf1); 556 } 557 558 static ssize_t dcmf2_show(struct device *dev, 559 struct device_attribute *attr, char *buf) 560 { 561 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 562 563 if (!priv) 564 return -ENODEV; 565 566 return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf2); 567 } 568 569 static ssize_t dcmf3_show(struct device *dev, 570 struct device_attribute *attr, char *buf) 571 { 572 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 573 574 if (!priv) 575 return -ENODEV; 576 577 return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf3); 578 } 579 580 static ssize_t dcmf0_status_show(struct device *dev, 581 struct device_attribute *attr, char *buf) 582 { 583 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 584 585 if (!priv) 586 return -ENODEV; 587 588 if (priv->dcmf_status.dcmf0 == INVALID_DCMF_STATUS) 589 return -EIO; 590 591 return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf0); 592 } 593 594 static ssize_t dcmf1_status_show(struct device *dev, 595 struct device_attribute *attr, char *buf) 596 { 597 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 598 599 if (!priv) 600 return -ENODEV; 601 602 if (priv->dcmf_status.dcmf1 == INVALID_DCMF_STATUS) 603 return -EIO; 604 605 return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf1); 606 } 607 608 static ssize_t dcmf2_status_show(struct device *dev, 609 struct device_attribute *attr, char *buf) 610 { 611 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 612 613 if (!priv) 614 return -ENODEV; 615 616 if (priv->dcmf_status.dcmf2 == INVALID_DCMF_STATUS) 617 return -EIO; 618 619 return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf2); 620 } 621 622 static ssize_t dcmf3_status_show(struct device *dev, 623 struct device_attribute *attr, char *buf) 624 { 625 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 626 627 if (!priv) 628 return -ENODEV; 629 630 if (priv->dcmf_status.dcmf3 == INVALID_DCMF_STATUS) 631 return -EIO; 632 633 return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf3); 634 } 635 static ssize_t reboot_image_store(struct device *dev, 636 struct device_attribute *attr, 637 const char *buf, size_t count) 638 { 639 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 640 unsigned long address; 641 int ret; 642 643 if (!priv) 644 return -ENODEV; 645 646 ret = kstrtoul(buf, 0, &address); 647 if (ret) 648 return ret; 649 650 /* 651 * Use the non-blocking variant so a write to this sysfs attribute 652 * does not stall the caller while another RSU operation is in 653 * flight. Userspace can retry on -EBUSY. 654 */ 655 ret = rsu_try_send_msg(priv, COMMAND_RSU_UPDATE, 656 address, rsu_command_callback); 657 if (ret == -EBUSY) { 658 dev_dbg(dev, "RSU busy, reboot_image write rejected\n"); 659 return ret; 660 } 661 if (ret) { 662 dev_err(dev, "Error, RSU update returned %i\n", ret); 663 return ret; 664 } 665 666 return count; 667 } 668 669 static ssize_t notify_store(struct device *dev, 670 struct device_attribute *attr, 671 const char *buf, size_t count) 672 { 673 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 674 unsigned long status; 675 int ret; 676 677 if (!priv) 678 return -ENODEV; 679 680 ret = kstrtoul(buf, 0, &status); 681 if (ret) 682 return ret; 683 684 ret = rsu_send_async_msg(dev, priv, COMMAND_RSU_NOTIFY, status, NULL); 685 if (ret) { 686 dev_err(dev, "Error, RSU notify returned %i\n", ret); 687 return ret; 688 } 689 690 /* to get the updated state */ 691 ret = rsu_send_async_msg(dev, priv, COMMAND_RSU_STATUS, 0, 692 rsu_async_status_callback); 693 if (ret) { 694 dev_err(dev, "Error, getting RSU status %i\n", ret); 695 return ret; 696 } 697 698 return count; 699 } 700 701 static ssize_t spt0_address_show(struct device *dev, 702 struct device_attribute *attr, char *buf) 703 { 704 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 705 706 if (!priv) 707 return -ENODEV; 708 709 if (priv->spt0_address == INVALID_SPT_ADDRESS) 710 return -EIO; 711 712 return sysfs_emit(buf, "0x%08lx\n", priv->spt0_address); 713 } 714 715 static ssize_t spt1_address_show(struct device *dev, 716 struct device_attribute *attr, char *buf) 717 { 718 struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 719 720 if (!priv) 721 return -ENODEV; 722 723 if (priv->spt1_address == INVALID_SPT_ADDRESS) 724 return -EIO; 725 726 return sysfs_emit(buf, "0x%08lx\n", priv->spt1_address); 727 } 728 729 static DEVICE_ATTR_RO(current_image); 730 static DEVICE_ATTR_RO(fail_image); 731 static DEVICE_ATTR_RO(state); 732 static DEVICE_ATTR_RO(version); 733 static DEVICE_ATTR_RO(error_location); 734 static DEVICE_ATTR_RO(error_details); 735 static DEVICE_ATTR_RO(retry_counter); 736 static DEVICE_ATTR_RO(max_retry); 737 static DEVICE_ATTR_RO(dcmf0); 738 static DEVICE_ATTR_RO(dcmf1); 739 static DEVICE_ATTR_RO(dcmf2); 740 static DEVICE_ATTR_RO(dcmf3); 741 static DEVICE_ATTR_RO(dcmf0_status); 742 static DEVICE_ATTR_RO(dcmf1_status); 743 static DEVICE_ATTR_RO(dcmf2_status); 744 static DEVICE_ATTR_RO(dcmf3_status); 745 static DEVICE_ATTR_WO(reboot_image); 746 static DEVICE_ATTR_WO(notify); 747 static DEVICE_ATTR_RO(spt0_address); 748 static DEVICE_ATTR_RO(spt1_address); 749 750 static struct attribute *rsu_attrs[] = { 751 &dev_attr_current_image.attr, 752 &dev_attr_fail_image.attr, 753 &dev_attr_state.attr, 754 &dev_attr_version.attr, 755 &dev_attr_error_location.attr, 756 &dev_attr_error_details.attr, 757 &dev_attr_retry_counter.attr, 758 &dev_attr_max_retry.attr, 759 &dev_attr_dcmf0.attr, 760 &dev_attr_dcmf1.attr, 761 &dev_attr_dcmf2.attr, 762 &dev_attr_dcmf3.attr, 763 &dev_attr_dcmf0_status.attr, 764 &dev_attr_dcmf1_status.attr, 765 &dev_attr_dcmf2_status.attr, 766 &dev_attr_dcmf3_status.attr, 767 &dev_attr_reboot_image.attr, 768 &dev_attr_notify.attr, 769 &dev_attr_spt0_address.attr, 770 &dev_attr_spt1_address.attr, 771 NULL 772 }; 773 774 ATTRIBUTE_GROUPS(rsu); 775 776 static int stratix10_rsu_probe(struct platform_device *pdev) 777 { 778 struct device *dev = &pdev->dev; 779 struct stratix10_rsu_priv *priv; 780 int ret; 781 782 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 783 if (!priv) 784 return -ENOMEM; 785 786 priv->client.dev = dev; 787 priv->client.priv = priv; 788 priv->retry_counter = INVALID_RETRY_COUNTER; 789 priv->max_retry = INVALID_RETRY_COUNTER; 790 priv->dcmf_version.dcmf0 = INVALID_DCMF_VERSION; 791 priv->dcmf_version.dcmf1 = INVALID_DCMF_VERSION; 792 priv->dcmf_version.dcmf2 = INVALID_DCMF_VERSION; 793 priv->dcmf_version.dcmf3 = INVALID_DCMF_VERSION; 794 priv->dcmf_status.dcmf0 = INVALID_DCMF_STATUS; 795 priv->dcmf_status.dcmf1 = INVALID_DCMF_STATUS; 796 priv->dcmf_status.dcmf2 = INVALID_DCMF_STATUS; 797 priv->dcmf_status.dcmf3 = INVALID_DCMF_STATUS; 798 /* spt0/1_address and status fields default to 0 from kzalloc */ 799 800 mutex_init(&priv->lock); 801 init_completion(&priv->completion); 802 803 priv->chan = stratix10_svc_request_channel_byname(&priv->client, 804 SVC_CLIENT_RSU); 805 if (IS_ERR(priv->chan)) { 806 dev_err(dev, "couldn't get service channel %s\n", 807 SVC_CLIENT_RSU); 808 return PTR_ERR(priv->chan); 809 } 810 811 ret = stratix10_svc_add_async_client(priv->chan, false); 812 if (ret) { 813 dev_err(dev, "failed to add async client\n"); 814 goto free_channel; 815 } 816 817 platform_set_drvdata(pdev, priv); 818 819 /* get the initial state from firmware */ 820 ret = rsu_send_async_msg(dev, priv, COMMAND_RSU_STATUS, 0, 821 rsu_async_status_callback); 822 if (ret) { 823 dev_err(dev, "Error, getting RSU status %i\n", ret); 824 goto remove_async_client; 825 } 826 827 /* get DCMF version from firmware */ 828 ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_VERSION, 0, 829 rsu_dcmf_version_callback); 830 if (ret) { 831 dev_err(dev, "Error, getting DCMF version %i\n", ret); 832 goto remove_async_client; 833 } 834 835 ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_STATUS, 0, 836 rsu_dcmf_status_callback); 837 if (ret) { 838 dev_err(dev, "Error, getting DCMF status %i\n", ret); 839 goto remove_async_client; 840 } 841 842 ret = rsu_send_msg(priv, COMMAND_RSU_MAX_RETRY, 0, 843 rsu_max_retry_callback); 844 if (ret) { 845 dev_err(dev, "Error, getting RSU max retry %i\n", ret); 846 goto remove_async_client; 847 } 848 849 ret = rsu_send_async_msg(dev, priv, COMMAND_RSU_GET_SPT_TABLE, 0, 850 rsu_async_get_spt_table_callback); 851 if (ret) { 852 dev_err(dev, "Error, getting SPT table %i\n", ret); 853 goto remove_async_client; 854 } 855 856 return 0; 857 858 remove_async_client: 859 stratix10_svc_remove_async_client(priv->chan); 860 free_channel: 861 stratix10_svc_free_channel(priv->chan); 862 return ret; 863 } 864 865 static void stratix10_rsu_remove(struct platform_device *pdev) 866 { 867 struct stratix10_rsu_priv *priv = platform_get_drvdata(pdev); 868 869 stratix10_svc_free_channel(priv->chan); 870 } 871 872 static struct platform_driver stratix10_rsu_driver = { 873 .probe = stratix10_rsu_probe, 874 .remove = stratix10_rsu_remove, 875 .driver = { 876 .name = "stratix10-rsu", 877 .dev_groups = rsu_groups, 878 }, 879 }; 880 881 module_platform_driver(stratix10_rsu_driver); 882 883 MODULE_LICENSE("GPL v2"); 884 MODULE_DESCRIPTION("Intel Remote System Update Driver"); 885 MODULE_AUTHOR("Richard Gong <richard.gong@intel.com>"); 886