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)  * IBM ASM Service Processor Device Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) IBM Corporation, 2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Author: Max Asböck <amax@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "ibmasm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "lowlevel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * ASM service processor event handling routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * Events are signalled to the device drivers through interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * They have the format of dot commands, with the type field set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * sp_event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * The driver does not interpret the events, it simply stores them in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * circular buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static void wake_up_event_readers(struct service_processor *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	struct event_reader *reader;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	list_for_each_entry(reader, &sp->event_buffer->readers, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)                 wake_up_interruptible(&reader->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * receive_event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * Called by the interrupt handler when a dot command of type sp_event is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * Store the event in the circular event buffer, wake up any sleeping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * event readers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * There is no reader marker in the buffer, therefore readers are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * responsible for keeping up with the writer, or they will lose events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) void ibmasm_receive_event(struct service_processor *sp, void *data, unsigned int data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct event_buffer *buffer = sp->event_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct ibmasm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	data_size = min(data_size, IBMASM_EVENT_MAX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	spin_lock_irqsave(&sp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	/* copy the event into the next slot in the circular buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	event = &buffer->events[buffer->next_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	memcpy_fromio(event->data, data, data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	event->data_size = data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	event->serial_number = buffer->next_serial_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	/* advance indices in the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	buffer->next_index = (buffer->next_index + 1) % IBMASM_NUM_EVENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	buffer->next_serial_number++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	spin_unlock_irqrestore(&sp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	wake_up_event_readers(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static inline int event_available(struct event_buffer *b, struct event_reader *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return (r->next_serial_number < b->next_serial_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * get_next_event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * Called by event readers (initiated from user space through the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * system).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * Sleeps until a new event is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct event_buffer *buffer = sp->event_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct ibmasm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	reader->cancelled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (wait_event_interruptible(reader->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			event_available(buffer, reader) || reader->cancelled))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (!event_available(buffer, reader))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	spin_lock_irqsave(&sp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	index = buffer->next_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	event = &buffer->events[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	while (event->serial_number < reader->next_serial_number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		index = (index + 1) % IBMASM_NUM_EVENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		event = &buffer->events[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	memcpy(reader->data, event->data, event->data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	reader->data_size = event->data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	reader->next_serial_number = event->serial_number + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	spin_unlock_irqrestore(&sp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	return event->data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) void ibmasm_cancel_next_event(struct event_reader *reader)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)         reader->cancelled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)         wake_up_interruptible(&reader->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	reader->next_serial_number = sp->event_buffer->next_serial_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	init_waitqueue_head(&reader->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	spin_lock_irqsave(&sp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	list_add(&reader->node, &sp->event_buffer->readers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	spin_unlock_irqrestore(&sp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	spin_lock_irqsave(&sp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	list_del(&reader->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	spin_unlock_irqrestore(&sp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int ibmasm_event_buffer_init(struct service_processor *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	struct event_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct ibmasm_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	buffer = kmalloc(sizeof(struct event_buffer), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	buffer->next_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	buffer->next_serial_number = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	event = buffer->events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	for (i=0; i<IBMASM_NUM_EVENTS; i++, event++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		event->serial_number = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	INIT_LIST_HEAD(&buffer->readers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	sp->event_buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) void ibmasm_event_buffer_exit(struct service_processor *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	kfree(sp->event_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }