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