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   */
rsu_status_callback(struct stratix10_svc_client * client,struct stratix10_svc_cb_data * data)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   */
rsu_command_callback(struct stratix10_svc_client * client,struct stratix10_svc_cb_data * data)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   */
rsu_retry_callback(struct stratix10_svc_client * client,struct stratix10_svc_cb_data * data)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   */
rsu_max_retry_callback(struct stratix10_svc_client * client,struct stratix10_svc_cb_data * data)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   */
rsu_dcmf_version_callback(struct stratix10_svc_client * client,struct stratix10_svc_cb_data * data)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   */
rsu_dcmf_status_callback(struct stratix10_svc_client * client,struct stratix10_svc_cb_data * data)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   */
rsu_send_msg(struct stratix10_rsu_priv * priv,enum stratix10_svc_command_code command,unsigned long arg,rsu_callback callback)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  
current_image_show(struct device * dev,struct device_attribute * attr,char * buf)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  
fail_image_show(struct device * dev,struct device_attribute * attr,char * buf)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  
version_show(struct device * dev,struct device_attribute * attr,char * buf)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  
state_show(struct device * dev,struct device_attribute * attr,char * buf)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  
error_location_show(struct device * dev,struct device_attribute * attr,char * buf)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  
error_details_show(struct device * dev,struct device_attribute * attr,char * buf)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  
retry_counter_show(struct device * dev,struct device_attribute * attr,char * buf)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  
max_retry_show(struct device * dev,struct device_attribute * attr,char * buf)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  
dcmf0_show(struct device * dev,struct device_attribute * attr,char * buf)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  
dcmf1_show(struct device * dev,struct device_attribute * attr,char * buf)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  
dcmf2_show(struct device * dev,struct device_attribute * attr,char * buf)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  
dcmf3_show(struct device * dev,struct device_attribute * attr,char * buf)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  
dcmf0_status_show(struct device * dev,struct device_attribute * attr,char * buf)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  
dcmf1_status_show(struct device * dev,struct device_attribute * attr,char * buf)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  
dcmf2_status_show(struct device * dev,struct device_attribute * attr,char * buf)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  
dcmf3_status_show(struct device * dev,struct device_attribute * attr,char * buf)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  }
reboot_image_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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  
notify_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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  
stratix10_rsu_probe(struct platform_device * pdev)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  
stratix10_rsu_remove(struct platform_device * pdev)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