1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2017, Linaro Ltd.
4  */
5 #include <linux/firmware.h>
6 #include <linux/module.h>
7 #include <linux/notifier.h>
8 #include <linux/slab.h>
9 #include <linux/io.h>
10 #include <linux/notifier.h>
11 #include <linux/of_platform.h>
12 #include <linux/platform_device.h>
13 #include <linux/remoteproc/qcom_rproc.h>
14 #include <linux/rpmsg.h>
15 
16 #include "qcom_common.h"
17 
18 static BLOCKING_NOTIFIER_HEAD(sysmon_notifiers);
19 
20 struct qcom_sysmon {
21 	struct rproc_subdev subdev;
22 	struct rproc *rproc;
23 
24 	struct list_head node;
25 
26 	const char *name;
27 
28 	int ssctl_version;
29 	int ssctl_instance;
30 
31 	struct notifier_block nb;
32 
33 	struct device *dev;
34 
35 	struct rpmsg_endpoint *ept;
36 	struct completion comp;
37 	struct mutex lock;
38 
39 	bool ssr_ack;
40 
41 	struct qmi_handle qmi;
42 	struct sockaddr_qrtr ssctl;
43 };
44 
45 static DEFINE_MUTEX(sysmon_lock);
46 static LIST_HEAD(sysmon_list);
47 
48 /**
49  * sysmon_send_event() - send notification of other remote's SSR event
50  * @sysmon:	sysmon context
51  * @name:	other remote's name
52  */
53 static void sysmon_send_event(struct qcom_sysmon *sysmon, const char *name)
54 {
55 	char req[50];
56 	int len;
57 	int ret;
58 
59 	len = snprintf(req, sizeof(req), "ssr:%s:before_shutdown", name);
60 	if (len >= sizeof(req))
61 		return;
62 
63 	mutex_lock(&sysmon->lock);
64 	reinit_completion(&sysmon->comp);
65 	sysmon->ssr_ack = false;
66 
67 	ret = rpmsg_send(sysmon->ept, req, len);
68 	if (ret < 0) {
69 		dev_err(sysmon->dev, "failed to send sysmon event\n");
70 		goto out_unlock;
71 	}
72 
73 	ret = wait_for_completion_timeout(&sysmon->comp,
74 					  msecs_to_jiffies(5000));
75 	if (!ret) {
76 		dev_err(sysmon->dev, "timeout waiting for sysmon ack\n");
77 		goto out_unlock;
78 	}
79 
80 	if (!sysmon->ssr_ack)
81 		dev_err(sysmon->dev, "unexpected response to sysmon event\n");
82 
83 out_unlock:
84 	mutex_unlock(&sysmon->lock);
85 }
86 
87 /**
88  * sysmon_request_shutdown() - request graceful shutdown of remote
89  * @sysmon:	sysmon context
90  */
91 static void sysmon_request_shutdown(struct qcom_sysmon *sysmon)
92 {
93 	char *req = "ssr:shutdown";
94 	int ret;
95 
96 	mutex_lock(&sysmon->lock);
97 	reinit_completion(&sysmon->comp);
98 	sysmon->ssr_ack = false;
99 
100 	ret = rpmsg_send(sysmon->ept, req, strlen(req) + 1);
101 	if (ret < 0) {
102 		dev_err(sysmon->dev, "send sysmon shutdown request failed\n");
103 		goto out_unlock;
104 	}
105 
106 	ret = wait_for_completion_timeout(&sysmon->comp,
107 					  msecs_to_jiffies(5000));
108 	if (!ret) {
109 		dev_err(sysmon->dev, "timeout waiting for sysmon ack\n");
110 		goto out_unlock;
111 	}
112 
113 	if (!sysmon->ssr_ack)
114 		dev_err(sysmon->dev,
115 			"unexpected response to sysmon shutdown request\n");
116 
117 out_unlock:
118 	mutex_unlock(&sysmon->lock);
119 }
120 
121 static int sysmon_callback(struct rpmsg_device *rpdev, void *data, int count,
122 			   void *priv, u32 addr)
123 {
124 	struct qcom_sysmon *sysmon = priv;
125 	const char *ssr_ack = "ssr:ack";
126 	const int ssr_ack_len = strlen(ssr_ack) + 1;
127 
128 	if (!sysmon)
129 		return -EINVAL;
130 
131 	if (count >= ssr_ack_len && !memcmp(data, ssr_ack, ssr_ack_len))
132 		sysmon->ssr_ack = true;
133 
134 	complete(&sysmon->comp);
135 
136 	return 0;
137 }
138 
139 #define SSCTL_SHUTDOWN_REQ		0x21
140 #define SSCTL_SUBSYS_EVENT_REQ		0x23
141 
142 #define SSCTL_MAX_MSG_LEN		7
143 
144 #define SSCTL_SUBSYS_NAME_LENGTH	15
145 
146 enum {
147 	SSCTL_SSR_EVENT_BEFORE_POWERUP,
148 	SSCTL_SSR_EVENT_AFTER_POWERUP,
149 	SSCTL_SSR_EVENT_BEFORE_SHUTDOWN,
150 	SSCTL_SSR_EVENT_AFTER_SHUTDOWN,
151 };
152 
153 enum {
154 	SSCTL_SSR_EVENT_FORCED,
155 	SSCTL_SSR_EVENT_GRACEFUL,
156 };
157 
158 struct ssctl_shutdown_resp {
159 	struct qmi_response_type_v01 resp;
160 };
161 
162 static struct qmi_elem_info ssctl_shutdown_resp_ei[] = {
163 	{
164 		.data_type	= QMI_STRUCT,
165 		.elem_len	= 1,
166 		.elem_size	= sizeof(struct qmi_response_type_v01),
167 		.array_type	= NO_ARRAY,
168 		.tlv_type	= 0x02,
169 		.offset		= offsetof(struct ssctl_shutdown_resp, resp),
170 		.ei_array	= qmi_response_type_v01_ei,
171 	},
172 	{}
173 };
174 
175 struct ssctl_subsys_event_req {
176 	u8 subsys_name_len;
177 	char subsys_name[SSCTL_SUBSYS_NAME_LENGTH];
178 	u32 event;
179 	u8 evt_driven_valid;
180 	u32 evt_driven;
181 };
182 
183 static struct qmi_elem_info ssctl_subsys_event_req_ei[] = {
184 	{
185 		.data_type	= QMI_DATA_LEN,
186 		.elem_len	= 1,
187 		.elem_size	= sizeof(uint8_t),
188 		.array_type	= NO_ARRAY,
189 		.tlv_type	= 0x01,
190 		.offset		= offsetof(struct ssctl_subsys_event_req,
191 					   subsys_name_len),
192 		.ei_array	= NULL,
193 	},
194 	{
195 		.data_type	= QMI_UNSIGNED_1_BYTE,
196 		.elem_len	= SSCTL_SUBSYS_NAME_LENGTH,
197 		.elem_size	= sizeof(char),
198 		.array_type	= VAR_LEN_ARRAY,
199 		.tlv_type	= 0x01,
200 		.offset		= offsetof(struct ssctl_subsys_event_req,
201 					   subsys_name),
202 		.ei_array	= NULL,
203 	},
204 	{
205 		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
206 		.elem_len	= 1,
207 		.elem_size	= sizeof(uint32_t),
208 		.array_type	= NO_ARRAY,
209 		.tlv_type	= 0x02,
210 		.offset		= offsetof(struct ssctl_subsys_event_req,
211 					   event),
212 		.ei_array	= NULL,
213 	},
214 	{
215 		.data_type	= QMI_OPT_FLAG,
216 		.elem_len	= 1,
217 		.elem_size	= sizeof(uint8_t),
218 		.array_type	= NO_ARRAY,
219 		.tlv_type	= 0x10,
220 		.offset		= offsetof(struct ssctl_subsys_event_req,
221 					   evt_driven_valid),
222 		.ei_array	= NULL,
223 	},
224 	{
225 		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
226 		.elem_len	= 1,
227 		.elem_size	= sizeof(uint32_t),
228 		.array_type	= NO_ARRAY,
229 		.tlv_type	= 0x10,
230 		.offset		= offsetof(struct ssctl_subsys_event_req,
231 					   evt_driven),
232 		.ei_array	= NULL,
233 	},
234 	{}
235 };
236 
237 struct ssctl_subsys_event_resp {
238 	struct qmi_response_type_v01 resp;
239 };
240 
241 static struct qmi_elem_info ssctl_subsys_event_resp_ei[] = {
242 	{
243 		.data_type	= QMI_STRUCT,
244 		.elem_len	= 1,
245 		.elem_size	= sizeof(struct qmi_response_type_v01),
246 		.array_type	= NO_ARRAY,
247 		.tlv_type	= 0x02,
248 		.offset		= offsetof(struct ssctl_subsys_event_resp,
249 					   resp),
250 		.ei_array	= qmi_response_type_v01_ei,
251 	},
252 	{}
253 };
254 
255 /**
256  * ssctl_request_shutdown() - request shutdown via SSCTL QMI service
257  * @sysmon:	sysmon context
258  */
259 static void ssctl_request_shutdown(struct qcom_sysmon *sysmon)
260 {
261 	struct ssctl_shutdown_resp resp;
262 	struct qmi_txn txn;
263 	int ret;
264 
265 	ret = qmi_txn_init(&sysmon->qmi, &txn, ssctl_shutdown_resp_ei, &resp);
266 	if (ret < 0) {
267 		dev_err(sysmon->dev, "failed to allocate QMI txn\n");
268 		return;
269 	}
270 
271 	ret = qmi_send_request(&sysmon->qmi, &sysmon->ssctl, &txn,
272 			       SSCTL_SHUTDOWN_REQ, 0, NULL, NULL);
273 	if (ret < 0) {
274 		dev_err(sysmon->dev, "failed to send shutdown request\n");
275 		qmi_txn_cancel(&txn);
276 		return;
277 	}
278 
279 	ret = qmi_txn_wait(&txn, 5 * HZ);
280 	if (ret < 0)
281 		dev_err(sysmon->dev, "failed receiving QMI response\n");
282 	else if (resp.resp.result)
283 		dev_err(sysmon->dev, "shutdown request failed\n");
284 	else
285 		dev_dbg(sysmon->dev, "shutdown request completed\n");
286 }
287 
288 /**
289  * ssctl_send_event() - send notification of other remote's SSR event
290  * @sysmon:	sysmon context
291  * @name:	other remote's name
292  */
293 static void ssctl_send_event(struct qcom_sysmon *sysmon, const char *name)
294 {
295 	struct ssctl_subsys_event_resp resp;
296 	struct ssctl_subsys_event_req req;
297 	struct qmi_txn txn;
298 	int ret;
299 
300 	memset(&resp, 0, sizeof(resp));
301 	ret = qmi_txn_init(&sysmon->qmi, &txn, ssctl_subsys_event_resp_ei, &resp);
302 	if (ret < 0) {
303 		dev_err(sysmon->dev, "failed to allocate QMI txn\n");
304 		return;
305 	}
306 
307 	memset(&req, 0, sizeof(req));
308 	strlcpy(req.subsys_name, name, sizeof(req.subsys_name));
309 	req.subsys_name_len = strlen(req.subsys_name);
310 	req.event = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN;
311 	req.evt_driven_valid = true;
312 	req.evt_driven = SSCTL_SSR_EVENT_FORCED;
313 
314 	ret = qmi_send_request(&sysmon->qmi, &sysmon->ssctl, &txn,
315 			       SSCTL_SUBSYS_EVENT_REQ, 40,
316 			       ssctl_subsys_event_req_ei, &req);
317 	if (ret < 0) {
318 		dev_err(sysmon->dev, "failed to send shutdown request\n");
319 		qmi_txn_cancel(&txn);
320 		return;
321 	}
322 
323 	ret = qmi_txn_wait(&txn, 5 * HZ);
324 	if (ret < 0)
325 		dev_err(sysmon->dev, "failed receiving QMI response\n");
326 	else if (resp.resp.result)
327 		dev_err(sysmon->dev, "ssr event send failed\n");
328 	else
329 		dev_dbg(sysmon->dev, "ssr event send completed\n");
330 }
331 
332 /**
333  * ssctl_new_server() - QMI callback indicating a new service
334  * @qmi:	QMI handle
335  * @svc:	service information
336  *
337  * Return: 0 if we're interested in this service, -EINVAL otherwise.
338  */
339 static int ssctl_new_server(struct qmi_handle *qmi, struct qmi_service *svc)
340 {
341 	struct qcom_sysmon *sysmon = container_of(qmi, struct qcom_sysmon, qmi);
342 
343 	switch (svc->version) {
344 	case 1:
345 		if (svc->instance != 0)
346 			return -EINVAL;
347 		if (strcmp(sysmon->name, "modem"))
348 			return -EINVAL;
349 		break;
350 	case 2:
351 		if (svc->instance != sysmon->ssctl_instance)
352 			return -EINVAL;
353 		break;
354 	default:
355 		return -EINVAL;
356 	};
357 
358 	sysmon->ssctl_version = svc->version;
359 
360 	sysmon->ssctl.sq_family = AF_QIPCRTR;
361 	sysmon->ssctl.sq_node = svc->node;
362 	sysmon->ssctl.sq_port = svc->port;
363 
364 	svc->priv = sysmon;
365 
366 	return 0;
367 }
368 
369 /**
370  * ssctl_del_server() - QMI callback indicating that @svc is removed
371  * @qmi:	QMI handle
372  * @svc:	service information
373  */
374 static void ssctl_del_server(struct qmi_handle *qmi, struct qmi_service *svc)
375 {
376 	struct qcom_sysmon *sysmon = svc->priv;
377 
378 	sysmon->ssctl_version = 0;
379 }
380 
381 static const struct qmi_ops ssctl_ops = {
382 	.new_server = ssctl_new_server,
383 	.del_server = ssctl_del_server,
384 };
385 
386 static int sysmon_start(struct rproc_subdev *subdev)
387 {
388 	return 0;
389 }
390 
391 static void sysmon_stop(struct rproc_subdev *subdev, bool crashed)
392 {
393 	struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon, subdev);
394 
395 	blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)sysmon->name);
396 
397 	/* Don't request graceful shutdown if we've crashed */
398 	if (crashed)
399 		return;
400 
401 	if (sysmon->ssctl_version)
402 		ssctl_request_shutdown(sysmon);
403 	else if (sysmon->ept)
404 		sysmon_request_shutdown(sysmon);
405 }
406 
407 /**
408  * sysmon_notify() - notify sysmon target of another's SSR
409  * @nb:		notifier_block associated with sysmon instance
410  * @event:	unused
411  * @data:	SSR identifier of the remote that is going down
412  */
413 static int sysmon_notify(struct notifier_block *nb, unsigned long event,
414 			 void *data)
415 {
416 	struct qcom_sysmon *sysmon = container_of(nb, struct qcom_sysmon, nb);
417 	struct rproc *rproc = sysmon->rproc;
418 	const char *ssr_name = data;
419 
420 	/* Skip non-running rprocs and the originating instance */
421 	if (rproc->state != RPROC_RUNNING || !strcmp(data, sysmon->name)) {
422 		dev_dbg(sysmon->dev, "not notifying %s\n", sysmon->name);
423 		return NOTIFY_DONE;
424 	}
425 
426 	/* Only SSCTL version 2 supports SSR events */
427 	if (sysmon->ssctl_version == 2)
428 		ssctl_send_event(sysmon, ssr_name);
429 	else if (sysmon->ept)
430 		sysmon_send_event(sysmon, ssr_name);
431 
432 	return NOTIFY_DONE;
433 }
434 
435 /**
436  * qcom_add_sysmon_subdev() - create a sysmon subdev for the given remoteproc
437  * @rproc:	rproc context to associate the subdev with
438  * @name:	name of this subdev, to use in SSR
439  * @ssctl_instance: instance id of the ssctl QMI service
440  *
441  * Return: A new qcom_sysmon object, or NULL on failure
442  */
443 struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
444 					   const char *name,
445 					   int ssctl_instance)
446 {
447 	struct qcom_sysmon *sysmon;
448 	int ret;
449 
450 	sysmon = kzalloc(sizeof(*sysmon), GFP_KERNEL);
451 	if (!sysmon)
452 		return NULL;
453 
454 	sysmon->dev = rproc->dev.parent;
455 	sysmon->rproc = rproc;
456 
457 	sysmon->name = name;
458 	sysmon->ssctl_instance = ssctl_instance;
459 
460 	init_completion(&sysmon->comp);
461 	mutex_init(&sysmon->lock);
462 
463 	ret = qmi_handle_init(&sysmon->qmi, SSCTL_MAX_MSG_LEN, &ssctl_ops, NULL);
464 	if (ret < 0) {
465 		dev_err(sysmon->dev, "failed to initialize qmi handle\n");
466 		kfree(sysmon);
467 		return NULL;
468 	}
469 
470 	qmi_add_lookup(&sysmon->qmi, 43, 0, 0);
471 
472 	sysmon->subdev.start = sysmon_start;
473 	sysmon->subdev.stop = sysmon_stop;
474 
475 	rproc_add_subdev(rproc, &sysmon->subdev);
476 
477 	sysmon->nb.notifier_call = sysmon_notify;
478 	blocking_notifier_chain_register(&sysmon_notifiers, &sysmon->nb);
479 
480 	mutex_lock(&sysmon_lock);
481 	list_add(&sysmon->node, &sysmon_list);
482 	mutex_unlock(&sysmon_lock);
483 
484 	return sysmon;
485 }
486 EXPORT_SYMBOL_GPL(qcom_add_sysmon_subdev);
487 
488 /**
489  * qcom_remove_sysmon_subdev() - release a qcom_sysmon
490  * @sysmon:	sysmon context, as retrieved by qcom_add_sysmon_subdev()
491  */
492 void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon)
493 {
494 	if (!sysmon)
495 		return;
496 
497 	mutex_lock(&sysmon_lock);
498 	list_del(&sysmon->node);
499 	mutex_unlock(&sysmon_lock);
500 
501 	blocking_notifier_chain_unregister(&sysmon_notifiers, &sysmon->nb);
502 
503 	rproc_remove_subdev(sysmon->rproc, &sysmon->subdev);
504 
505 	qmi_handle_release(&sysmon->qmi);
506 
507 	kfree(sysmon);
508 }
509 EXPORT_SYMBOL_GPL(qcom_remove_sysmon_subdev);
510 
511 /**
512  * sysmon_probe() - probe sys_mon channel
513  * @rpdev:	rpmsg device handle
514  *
515  * Find the sysmon context associated with the ancestor remoteproc and assign
516  * this rpmsg device with said sysmon context.
517  *
518  * Return: 0 on success, negative errno on failure.
519  */
520 static int sysmon_probe(struct rpmsg_device *rpdev)
521 {
522 	struct qcom_sysmon *sysmon;
523 	struct rproc *rproc;
524 
525 	rproc = rproc_get_by_child(&rpdev->dev);
526 	if (!rproc) {
527 		dev_err(&rpdev->dev, "sysmon device not child of rproc\n");
528 		return -EINVAL;
529 	}
530 
531 	mutex_lock(&sysmon_lock);
532 	list_for_each_entry(sysmon, &sysmon_list, node) {
533 		if (sysmon->rproc == rproc)
534 			goto found;
535 	}
536 	mutex_unlock(&sysmon_lock);
537 
538 	dev_err(&rpdev->dev, "no sysmon associated with parent rproc\n");
539 
540 	return -EINVAL;
541 
542 found:
543 	mutex_unlock(&sysmon_lock);
544 
545 	rpdev->ept->priv = sysmon;
546 	sysmon->ept = rpdev->ept;
547 
548 	return 0;
549 }
550 
551 /**
552  * sysmon_remove() - sys_mon channel remove handler
553  * @rpdev:	rpmsg device handle
554  *
555  * Disassociate the rpmsg device with the sysmon instance.
556  */
557 static void sysmon_remove(struct rpmsg_device *rpdev)
558 {
559 	struct qcom_sysmon *sysmon = rpdev->ept->priv;
560 
561 	sysmon->ept = NULL;
562 }
563 
564 static const struct rpmsg_device_id sysmon_match[] = {
565 	{ "sys_mon" },
566 	{}
567 };
568 
569 static struct rpmsg_driver sysmon_driver = {
570 	.probe = sysmon_probe,
571 	.remove = sysmon_remove,
572 	.callback = sysmon_callback,
573 	.id_table = sysmon_match,
574 	.drv = {
575 		.name = "qcom_sysmon",
576 	},
577 };
578 
579 module_rpmsg_driver(sysmon_driver);
580 
581 MODULE_DESCRIPTION("Qualcomm sysmon driver");
582 MODULE_LICENSE("GPL v2");
583