Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5)  * Copyright (C) IBM Corporation, 2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7)  * Author: Max Asböck <amax@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "ibmasm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "dot_command.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)  * Reverse Heartbeat, i.e. heartbeats sent from the driver to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)  * service processor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)  * These heartbeats are initiated by user level programs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* the reverse heartbeat dot command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #pragma pack(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 	struct dot_command_header	header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 	unsigned char			command[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) } rhb_dot_cmd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 	.header = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 		.type =		sp_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 		.command_size = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 		.data_size =	0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 		.status =	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 	.command = { 4, 3, 6 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #pragma pack()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 	init_waitqueue_head(&rhb->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 	rhb->stopped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)  * start_reverse_heartbeat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)  * Loop forever, sending a reverse heartbeat dot command to the service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)  * processor, then sleeping. The loop comes to an end if the service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)  * processor fails to respond 3 times or we were interrupted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 	struct command *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 	int times_failed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 	int result = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 	cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 	if (!cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 	while (times_failed < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 		memcpy(cmd->buffer, (void *)&rhb_dot_cmd, sizeof rhb_dot_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 		cmd->status = IBMASM_CMD_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 		ibmasm_exec_command(sp, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 		ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 		if (cmd->status != IBMASM_CMD_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 			times_failed++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 		wait_event_interruptible_timeout(rhb->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 			rhb->stopped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 			REVERSE_HEARTBEAT_TIMEOUT * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 		if (signal_pending(current) || rhb->stopped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 			result = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 	command_put(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 	rhb->stopped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 	rhb->stopped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 	wake_up_interruptible(&rhb->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }