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