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