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