Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2018-2019, Intel Corporation
0004  */
0005 
0006 #include <linux/arm-smccc.h>
0007 #include <linux/bitfield.h>
0008 #include <linux/completion.h>
0009 #include <linux/kobject.h>
0010 #include <linux/module.h>
0011 #include <linux/mutex.h>
0012 #include <linux/of.h>
0013 #include <linux/of_platform.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/firmware/intel/stratix10-svc-client.h>
0016 #include <linux/string.h>
0017 #include <linux/sysfs.h>
0018 
0019 #define RSU_STATE_MASK          GENMASK_ULL(31, 0)
0020 #define RSU_VERSION_MASK        GENMASK_ULL(63, 32)
0021 #define RSU_ERROR_LOCATION_MASK     GENMASK_ULL(31, 0)
0022 #define RSU_ERROR_DETAIL_MASK       GENMASK_ULL(63, 32)
0023 #define RSU_DCMF0_MASK          GENMASK_ULL(31, 0)
0024 #define RSU_DCMF1_MASK          GENMASK_ULL(63, 32)
0025 #define RSU_DCMF2_MASK          GENMASK_ULL(31, 0)
0026 #define RSU_DCMF3_MASK          GENMASK_ULL(63, 32)
0027 #define RSU_DCMF0_STATUS_MASK       GENMASK_ULL(15, 0)
0028 #define RSU_DCMF1_STATUS_MASK       GENMASK_ULL(31, 16)
0029 #define RSU_DCMF2_STATUS_MASK       GENMASK_ULL(47, 32)
0030 #define RSU_DCMF3_STATUS_MASK       GENMASK_ULL(63, 48)
0031 
0032 #define RSU_TIMEOUT (msecs_to_jiffies(SVC_RSU_REQUEST_TIMEOUT_MS))
0033 
0034 #define INVALID_RETRY_COUNTER       0xFF
0035 #define INVALID_DCMF_VERSION        0xFF
0036 #define INVALID_DCMF_STATUS     0xFFFFFFFF
0037 
0038 typedef void (*rsu_callback)(struct stratix10_svc_client *client,
0039                  struct stratix10_svc_cb_data *data);
0040 /**
0041  * struct stratix10_rsu_priv - rsu data structure
0042  * @chan: pointer to the allocated service channel
0043  * @client: active service client
0044  * @completion: state for callback completion
0045  * @lock: a mutex to protect callback completion state
0046  * @status.current_image: address of image currently running in flash
0047  * @status.fail_image: address of failed image in flash
0048  * @status.version: the interface version number of RSU firmware
0049  * @status.state: the state of RSU system
0050  * @status.error_details: error code
0051  * @status.error_location: the error offset inside the image that failed
0052  * @dcmf_version.dcmf0: Quartus dcmf0 version
0053  * @dcmf_version.dcmf1: Quartus dcmf1 version
0054  * @dcmf_version.dcmf2: Quartus dcmf2 version
0055  * @dcmf_version.dcmf3: Quartus dcmf3 version
0056  * @dcmf_status.dcmf0: dcmf0 status
0057  * @dcmf_status.dcmf1: dcmf1 status
0058  * @dcmf_status.dcmf2: dcmf2 status
0059  * @dcmf_status.dcmf3: dcmf3 status
0060  * @retry_counter: the current image's retry counter
0061  * @max_retry: the preset max retry value
0062  */
0063 struct stratix10_rsu_priv {
0064     struct stratix10_svc_chan *chan;
0065     struct stratix10_svc_client client;
0066     struct completion completion;
0067     struct mutex lock;
0068     struct {
0069         unsigned long current_image;
0070         unsigned long fail_image;
0071         unsigned int version;
0072         unsigned int state;
0073         unsigned int error_details;
0074         unsigned int error_location;
0075     } status;
0076 
0077     struct {
0078         unsigned int dcmf0;
0079         unsigned int dcmf1;
0080         unsigned int dcmf2;
0081         unsigned int dcmf3;
0082     } dcmf_version;
0083 
0084     struct {
0085         unsigned int dcmf0;
0086         unsigned int dcmf1;
0087         unsigned int dcmf2;
0088         unsigned int dcmf3;
0089     } dcmf_status;
0090 
0091     unsigned int retry_counter;
0092     unsigned int max_retry;
0093 };
0094 
0095 /**
0096  * rsu_status_callback() - Status callback from Intel Service Layer
0097  * @client: pointer to service client
0098  * @data: pointer to callback data structure
0099  *
0100  * Callback from Intel service layer for RSU status request. Status is
0101  * only updated after a system reboot, so a get updated status call is
0102  * made during driver probe.
0103  */
0104 static void rsu_status_callback(struct stratix10_svc_client *client,
0105                 struct stratix10_svc_cb_data *data)
0106 {
0107     struct stratix10_rsu_priv *priv = client->priv;
0108     struct arm_smccc_res *res = (struct arm_smccc_res *)data->kaddr1;
0109 
0110     if (data->status == BIT(SVC_STATUS_OK)) {
0111         priv->status.version = FIELD_GET(RSU_VERSION_MASK,
0112                          res->a2);
0113         priv->status.state = FIELD_GET(RSU_STATE_MASK, res->a2);
0114         priv->status.fail_image = res->a1;
0115         priv->status.current_image = res->a0;
0116         priv->status.error_location =
0117             FIELD_GET(RSU_ERROR_LOCATION_MASK, res->a3);
0118         priv->status.error_details =
0119             FIELD_GET(RSU_ERROR_DETAIL_MASK, res->a3);
0120     } else {
0121         dev_err(client->dev, "COMMAND_RSU_STATUS returned 0x%lX\n",
0122             res->a0);
0123         priv->status.version = 0;
0124         priv->status.state = 0;
0125         priv->status.fail_image = 0;
0126         priv->status.current_image = 0;
0127         priv->status.error_location = 0;
0128         priv->status.error_details = 0;
0129     }
0130 
0131     complete(&priv->completion);
0132 }
0133 
0134 /**
0135  * rsu_command_callback() - Update callback from Intel Service Layer
0136  * @client: pointer to client
0137  * @data: pointer to callback data structure
0138  *
0139  * Callback from Intel service layer for RSU commands.
0140  */
0141 static void rsu_command_callback(struct stratix10_svc_client *client,
0142                  struct stratix10_svc_cb_data *data)
0143 {
0144     struct stratix10_rsu_priv *priv = client->priv;
0145 
0146     if (data->status == BIT(SVC_STATUS_NO_SUPPORT))
0147         dev_warn(client->dev, "Secure FW doesn't support notify\n");
0148     else if (data->status == BIT(SVC_STATUS_ERROR))
0149         dev_err(client->dev, "Failure, returned status is %lu\n",
0150             BIT(data->status));
0151 
0152     complete(&priv->completion);
0153 }
0154 
0155 /**
0156  * rsu_retry_callback() - Callback from Intel service layer for getting
0157  * the current image's retry counter from the firmware
0158  * @client: pointer to client
0159  * @data: pointer to callback data structure
0160  *
0161  * Callback from Intel service layer for retry counter, which is used by
0162  * user to know how many times the images is still allowed to reload
0163  * itself before giving up and starting RSU fail-over flow.
0164  */
0165 static void rsu_retry_callback(struct stratix10_svc_client *client,
0166                    struct stratix10_svc_cb_data *data)
0167 {
0168     struct stratix10_rsu_priv *priv = client->priv;
0169     unsigned int *counter = (unsigned int *)data->kaddr1;
0170 
0171     if (data->status == BIT(SVC_STATUS_OK))
0172         priv->retry_counter = *counter;
0173     else if (data->status == BIT(SVC_STATUS_NO_SUPPORT))
0174         dev_warn(client->dev, "Secure FW doesn't support retry\n");
0175     else
0176         dev_err(client->dev, "Failed to get retry counter %lu\n",
0177             BIT(data->status));
0178 
0179     complete(&priv->completion);
0180 }
0181 
0182 /**
0183  * rsu_max_retry_callback() - Callback from Intel service layer for getting
0184  * the max retry value from the firmware
0185  * @client: pointer to client
0186  * @data: pointer to callback data structure
0187  *
0188  * Callback from Intel service layer for max retry.
0189  */
0190 static void rsu_max_retry_callback(struct stratix10_svc_client *client,
0191                    struct stratix10_svc_cb_data *data)
0192 {
0193     struct stratix10_rsu_priv *priv = client->priv;
0194     unsigned int *max_retry = (unsigned int *)data->kaddr1;
0195 
0196     if (data->status == BIT(SVC_STATUS_OK))
0197         priv->max_retry = *max_retry;
0198     else if (data->status == BIT(SVC_STATUS_NO_SUPPORT))
0199         dev_warn(client->dev, "Secure FW doesn't support max retry\n");
0200     else
0201         dev_err(client->dev, "Failed to get max retry %lu\n",
0202             BIT(data->status));
0203 
0204     complete(&priv->completion);
0205 }
0206 
0207 /**
0208  * rsu_dcmf_version_callback() - Callback from Intel service layer for getting
0209  * the DCMF version
0210  * @client: pointer to client
0211  * @data: pointer to callback data structure
0212  *
0213  * Callback from Intel service layer for DCMF version number
0214  */
0215 static void rsu_dcmf_version_callback(struct stratix10_svc_client *client,
0216                       struct stratix10_svc_cb_data *data)
0217 {
0218     struct stratix10_rsu_priv *priv = client->priv;
0219     unsigned long long *value1 = (unsigned long long *)data->kaddr1;
0220     unsigned long long *value2 = (unsigned long long *)data->kaddr2;
0221 
0222     if (data->status == BIT(SVC_STATUS_OK)) {
0223         priv->dcmf_version.dcmf0 = FIELD_GET(RSU_DCMF0_MASK, *value1);
0224         priv->dcmf_version.dcmf1 = FIELD_GET(RSU_DCMF1_MASK, *value1);
0225         priv->dcmf_version.dcmf2 = FIELD_GET(RSU_DCMF2_MASK, *value2);
0226         priv->dcmf_version.dcmf3 = FIELD_GET(RSU_DCMF3_MASK, *value2);
0227     } else
0228         dev_err(client->dev, "failed to get DCMF version\n");
0229 
0230     complete(&priv->completion);
0231 }
0232 
0233 /**
0234  * rsu_dcmf_status_callback() - Callback from Intel service layer for getting
0235  * the DCMF status
0236  * @client: pointer to client
0237  * @data: pointer to callback data structure
0238  *
0239  * Callback from Intel service layer for DCMF status
0240  */
0241 static void rsu_dcmf_status_callback(struct stratix10_svc_client *client,
0242                      struct stratix10_svc_cb_data *data)
0243 {
0244     struct stratix10_rsu_priv *priv = client->priv;
0245     unsigned long long *value = (unsigned long long *)data->kaddr1;
0246 
0247     if (data->status == BIT(SVC_STATUS_OK)) {
0248         priv->dcmf_status.dcmf0 = FIELD_GET(RSU_DCMF0_STATUS_MASK,
0249                             *value);
0250         priv->dcmf_status.dcmf1 = FIELD_GET(RSU_DCMF1_STATUS_MASK,
0251                             *value);
0252         priv->dcmf_status.dcmf2 = FIELD_GET(RSU_DCMF2_STATUS_MASK,
0253                             *value);
0254         priv->dcmf_status.dcmf3 = FIELD_GET(RSU_DCMF3_STATUS_MASK,
0255                             *value);
0256     } else
0257         dev_err(client->dev, "failed to get DCMF status\n");
0258 
0259     complete(&priv->completion);
0260 }
0261 
0262 /**
0263  * rsu_send_msg() - send a message to Intel service layer
0264  * @priv: pointer to rsu private data
0265  * @command: RSU status or update command
0266  * @arg: the request argument, the bitstream address or notify status
0267  * @callback: function pointer for the callback (status or update)
0268  *
0269  * Start an Intel service layer transaction to perform the SMC call that
0270  * is necessary to get RSU boot log or set the address of bitstream to
0271  * boot after reboot.
0272  *
0273  * Returns 0 on success or -ETIMEDOUT on error.
0274  */
0275 static int rsu_send_msg(struct stratix10_rsu_priv *priv,
0276             enum stratix10_svc_command_code command,
0277             unsigned long arg,
0278             rsu_callback callback)
0279 {
0280     struct stratix10_svc_client_msg msg;
0281     int ret;
0282 
0283     mutex_lock(&priv->lock);
0284     reinit_completion(&priv->completion);
0285     priv->client.receive_cb = callback;
0286 
0287     msg.command = command;
0288     if (arg)
0289         msg.arg[0] = arg;
0290 
0291     ret = stratix10_svc_send(priv->chan, &msg);
0292     if (ret < 0)
0293         goto status_done;
0294 
0295     ret = wait_for_completion_interruptible_timeout(&priv->completion,
0296                             RSU_TIMEOUT);
0297     if (!ret) {
0298         dev_err(priv->client.dev,
0299             "timeout waiting for SMC call\n");
0300         ret = -ETIMEDOUT;
0301         goto status_done;
0302     } else if (ret < 0) {
0303         dev_err(priv->client.dev,
0304             "error %d waiting for SMC call\n", ret);
0305         goto status_done;
0306     } else {
0307         ret = 0;
0308     }
0309 
0310 status_done:
0311     stratix10_svc_done(priv->chan);
0312     mutex_unlock(&priv->lock);
0313     return ret;
0314 }
0315 
0316 /*
0317  * This driver exposes some optional features of the Intel Stratix 10 SoC FPGA.
0318  * The sysfs interfaces exposed here are FPGA Remote System Update (RSU)
0319  * related. They allow user space software to query the configuration system
0320  * status and to request optional reboot behavior specific to Intel FPGAs.
0321  */
0322 
0323 static ssize_t current_image_show(struct device *dev,
0324                   struct device_attribute *attr, char *buf)
0325 {
0326     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0327 
0328     if (!priv)
0329         return -ENODEV;
0330 
0331     return sprintf(buf, "0x%08lx\n", priv->status.current_image);
0332 }
0333 
0334 static ssize_t fail_image_show(struct device *dev,
0335                    struct device_attribute *attr, char *buf)
0336 {
0337     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0338 
0339     if (!priv)
0340         return -ENODEV;
0341 
0342     return sprintf(buf, "0x%08lx\n", priv->status.fail_image);
0343 }
0344 
0345 static ssize_t version_show(struct device *dev, struct device_attribute *attr,
0346                 char *buf)
0347 {
0348     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0349 
0350     if (!priv)
0351         return -ENODEV;
0352 
0353     return sprintf(buf, "0x%08x\n", priv->status.version);
0354 }
0355 
0356 static ssize_t state_show(struct device *dev, struct device_attribute *attr,
0357               char *buf)
0358 {
0359     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0360 
0361     if (!priv)
0362         return -ENODEV;
0363 
0364     return sprintf(buf, "0x%08x\n", priv->status.state);
0365 }
0366 
0367 static ssize_t error_location_show(struct device *dev,
0368                    struct device_attribute *attr, char *buf)
0369 {
0370     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0371 
0372     if (!priv)
0373         return -ENODEV;
0374 
0375     return sprintf(buf, "0x%08x\n", priv->status.error_location);
0376 }
0377 
0378 static ssize_t error_details_show(struct device *dev,
0379                   struct device_attribute *attr, char *buf)
0380 {
0381     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0382 
0383     if (!priv)
0384         return -ENODEV;
0385 
0386     return sprintf(buf, "0x%08x\n", priv->status.error_details);
0387 }
0388 
0389 static ssize_t retry_counter_show(struct device *dev,
0390                   struct device_attribute *attr, char *buf)
0391 {
0392     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0393 
0394     if (!priv)
0395         return -ENODEV;
0396 
0397     return sprintf(buf, "0x%08x\n", priv->retry_counter);
0398 }
0399 
0400 static ssize_t max_retry_show(struct device *dev,
0401                   struct device_attribute *attr, char *buf)
0402 {
0403     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0404 
0405     if (!priv)
0406         return -ENODEV;
0407 
0408     return scnprintf(buf, sizeof(priv->max_retry),
0409              "0x%08x\n", priv->max_retry);
0410 }
0411 
0412 static ssize_t dcmf0_show(struct device *dev,
0413               struct device_attribute *attr, char *buf)
0414 {
0415     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0416 
0417     if (!priv)
0418         return -ENODEV;
0419 
0420     return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf0);
0421 }
0422 
0423 static ssize_t dcmf1_show(struct device *dev,
0424               struct device_attribute *attr, char *buf)
0425 {
0426     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0427 
0428     if (!priv)
0429         return -ENODEV;
0430 
0431     return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf1);
0432 }
0433 
0434 static ssize_t dcmf2_show(struct device *dev,
0435               struct device_attribute *attr, char *buf)
0436 {
0437     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0438 
0439     if (!priv)
0440         return -ENODEV;
0441 
0442     return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf2);
0443 }
0444 
0445 static ssize_t dcmf3_show(struct device *dev,
0446               struct device_attribute *attr, char *buf)
0447 {
0448     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0449 
0450     if (!priv)
0451         return -ENODEV;
0452 
0453     return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf3);
0454 }
0455 
0456 static ssize_t dcmf0_status_show(struct device *dev,
0457                  struct device_attribute *attr, char *buf)
0458 {
0459     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0460 
0461     if (!priv)
0462         return -ENODEV;
0463 
0464     if (priv->dcmf_status.dcmf0 == INVALID_DCMF_STATUS)
0465         return -EIO;
0466 
0467     return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf0);
0468 }
0469 
0470 static ssize_t dcmf1_status_show(struct device *dev,
0471                  struct device_attribute *attr, char *buf)
0472 {
0473     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0474 
0475     if (!priv)
0476         return -ENODEV;
0477 
0478     if (priv->dcmf_status.dcmf1 == INVALID_DCMF_STATUS)
0479         return -EIO;
0480 
0481     return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf1);
0482 }
0483 
0484 static ssize_t dcmf2_status_show(struct device *dev,
0485                 struct device_attribute *attr, char *buf)
0486 {
0487     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0488 
0489     if (!priv)
0490         return -ENODEV;
0491 
0492     if (priv->dcmf_status.dcmf2 == INVALID_DCMF_STATUS)
0493         return -EIO;
0494 
0495     return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf2);
0496 }
0497 
0498 static ssize_t dcmf3_status_show(struct device *dev,
0499                  struct device_attribute *attr, char *buf)
0500 {
0501     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0502 
0503     if (!priv)
0504         return -ENODEV;
0505 
0506     if (priv->dcmf_status.dcmf3 == INVALID_DCMF_STATUS)
0507         return -EIO;
0508 
0509     return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf3);
0510 }
0511 static ssize_t reboot_image_store(struct device *dev,
0512                   struct device_attribute *attr,
0513                   const char *buf, size_t count)
0514 {
0515     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0516     unsigned long address;
0517     int ret;
0518 
0519     if (!priv)
0520         return -ENODEV;
0521 
0522     ret = kstrtoul(buf, 0, &address);
0523     if (ret)
0524         return ret;
0525 
0526     ret = rsu_send_msg(priv, COMMAND_RSU_UPDATE,
0527                address, rsu_command_callback);
0528     if (ret) {
0529         dev_err(dev, "Error, RSU update returned %i\n", ret);
0530         return ret;
0531     }
0532 
0533     return count;
0534 }
0535 
0536 static ssize_t notify_store(struct device *dev,
0537                 struct device_attribute *attr,
0538                 const char *buf, size_t count)
0539 {
0540     struct stratix10_rsu_priv *priv = dev_get_drvdata(dev);
0541     unsigned long status;
0542     int ret;
0543 
0544     if (!priv)
0545         return -ENODEV;
0546 
0547     ret = kstrtoul(buf, 0, &status);
0548     if (ret)
0549         return ret;
0550 
0551     ret = rsu_send_msg(priv, COMMAND_RSU_NOTIFY,
0552                status, rsu_command_callback);
0553     if (ret) {
0554         dev_err(dev, "Error, RSU notify returned %i\n", ret);
0555         return ret;
0556     }
0557 
0558     /* to get the updated state */
0559     ret = rsu_send_msg(priv, COMMAND_RSU_STATUS,
0560                0, rsu_status_callback);
0561     if (ret) {
0562         dev_err(dev, "Error, getting RSU status %i\n", ret);
0563         return ret;
0564     }
0565 
0566     ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, rsu_retry_callback);
0567     if (ret) {
0568         dev_err(dev, "Error, getting RSU retry %i\n", ret);
0569         return ret;
0570     }
0571 
0572     return count;
0573 }
0574 
0575 static DEVICE_ATTR_RO(current_image);
0576 static DEVICE_ATTR_RO(fail_image);
0577 static DEVICE_ATTR_RO(state);
0578 static DEVICE_ATTR_RO(version);
0579 static DEVICE_ATTR_RO(error_location);
0580 static DEVICE_ATTR_RO(error_details);
0581 static DEVICE_ATTR_RO(retry_counter);
0582 static DEVICE_ATTR_RO(max_retry);
0583 static DEVICE_ATTR_RO(dcmf0);
0584 static DEVICE_ATTR_RO(dcmf1);
0585 static DEVICE_ATTR_RO(dcmf2);
0586 static DEVICE_ATTR_RO(dcmf3);
0587 static DEVICE_ATTR_RO(dcmf0_status);
0588 static DEVICE_ATTR_RO(dcmf1_status);
0589 static DEVICE_ATTR_RO(dcmf2_status);
0590 static DEVICE_ATTR_RO(dcmf3_status);
0591 static DEVICE_ATTR_WO(reboot_image);
0592 static DEVICE_ATTR_WO(notify);
0593 
0594 static struct attribute *rsu_attrs[] = {
0595     &dev_attr_current_image.attr,
0596     &dev_attr_fail_image.attr,
0597     &dev_attr_state.attr,
0598     &dev_attr_version.attr,
0599     &dev_attr_error_location.attr,
0600     &dev_attr_error_details.attr,
0601     &dev_attr_retry_counter.attr,
0602     &dev_attr_max_retry.attr,
0603     &dev_attr_dcmf0.attr,
0604     &dev_attr_dcmf1.attr,
0605     &dev_attr_dcmf2.attr,
0606     &dev_attr_dcmf3.attr,
0607     &dev_attr_dcmf0_status.attr,
0608     &dev_attr_dcmf1_status.attr,
0609     &dev_attr_dcmf2_status.attr,
0610     &dev_attr_dcmf3_status.attr,
0611     &dev_attr_reboot_image.attr,
0612     &dev_attr_notify.attr,
0613     NULL
0614 };
0615 
0616 ATTRIBUTE_GROUPS(rsu);
0617 
0618 static int stratix10_rsu_probe(struct platform_device *pdev)
0619 {
0620     struct device *dev = &pdev->dev;
0621     struct stratix10_rsu_priv *priv;
0622     int ret;
0623 
0624     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0625     if (!priv)
0626         return -ENOMEM;
0627 
0628     priv->client.dev = dev;
0629     priv->client.receive_cb = NULL;
0630     priv->client.priv = priv;
0631     priv->status.current_image = 0;
0632     priv->status.fail_image = 0;
0633     priv->status.error_location = 0;
0634     priv->status.error_details = 0;
0635     priv->status.version = 0;
0636     priv->status.state = 0;
0637     priv->retry_counter = INVALID_RETRY_COUNTER;
0638     priv->dcmf_version.dcmf0 = INVALID_DCMF_VERSION;
0639     priv->dcmf_version.dcmf1 = INVALID_DCMF_VERSION;
0640     priv->dcmf_version.dcmf2 = INVALID_DCMF_VERSION;
0641     priv->dcmf_version.dcmf3 = INVALID_DCMF_VERSION;
0642     priv->max_retry = INVALID_RETRY_COUNTER;
0643     priv->dcmf_status.dcmf0 = INVALID_DCMF_STATUS;
0644     priv->dcmf_status.dcmf1 = INVALID_DCMF_STATUS;
0645     priv->dcmf_status.dcmf2 = INVALID_DCMF_STATUS;
0646     priv->dcmf_status.dcmf3 = INVALID_DCMF_STATUS;
0647 
0648     mutex_init(&priv->lock);
0649     priv->chan = stratix10_svc_request_channel_byname(&priv->client,
0650                               SVC_CLIENT_RSU);
0651     if (IS_ERR(priv->chan)) {
0652         dev_err(dev, "couldn't get service channel %s\n",
0653             SVC_CLIENT_RSU);
0654         return PTR_ERR(priv->chan);
0655     }
0656 
0657     init_completion(&priv->completion);
0658     platform_set_drvdata(pdev, priv);
0659 
0660     /* get the initial state from firmware */
0661     ret = rsu_send_msg(priv, COMMAND_RSU_STATUS,
0662                0, rsu_status_callback);
0663     if (ret) {
0664         dev_err(dev, "Error, getting RSU status %i\n", ret);
0665         stratix10_svc_free_channel(priv->chan);
0666     }
0667 
0668     /* get DCMF version from firmware */
0669     ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_VERSION,
0670                0, rsu_dcmf_version_callback);
0671     if (ret) {
0672         dev_err(dev, "Error, getting DCMF version %i\n", ret);
0673         stratix10_svc_free_channel(priv->chan);
0674     }
0675 
0676     ret = rsu_send_msg(priv, COMMAND_RSU_DCMF_STATUS,
0677                0, rsu_dcmf_status_callback);
0678     if (ret) {
0679         dev_err(dev, "Error, getting DCMF status %i\n", ret);
0680         stratix10_svc_free_channel(priv->chan);
0681     }
0682 
0683     ret = rsu_send_msg(priv, COMMAND_RSU_RETRY, 0, rsu_retry_callback);
0684     if (ret) {
0685         dev_err(dev, "Error, getting RSU retry %i\n", ret);
0686         stratix10_svc_free_channel(priv->chan);
0687     }
0688 
0689     ret = rsu_send_msg(priv, COMMAND_RSU_MAX_RETRY, 0,
0690                rsu_max_retry_callback);
0691     if (ret) {
0692         dev_err(dev, "Error, getting RSU max retry %i\n", ret);
0693         stratix10_svc_free_channel(priv->chan);
0694     }
0695 
0696     return ret;
0697 }
0698 
0699 static int stratix10_rsu_remove(struct platform_device *pdev)
0700 {
0701     struct stratix10_rsu_priv *priv = platform_get_drvdata(pdev);
0702 
0703     stratix10_svc_free_channel(priv->chan);
0704     return 0;
0705 }
0706 
0707 static struct platform_driver stratix10_rsu_driver = {
0708     .probe = stratix10_rsu_probe,
0709     .remove = stratix10_rsu_remove,
0710     .driver = {
0711         .name = "stratix10-rsu",
0712         .dev_groups = rsu_groups,
0713     },
0714 };
0715 
0716 module_platform_driver(stratix10_rsu_driver);
0717 
0718 MODULE_LICENSE("GPL v2");
0719 MODULE_DESCRIPTION("Intel Remote System Update Driver");
0720 MODULE_AUTHOR("Richard Gong <richard.gong@intel.com>");