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