xref: /openbmc/linux/drivers/s390/cio/airq.c (revision 64c70b1c)
1 /*
2  *  drivers/s390/cio/airq.c
3  *   S/390 common I/O routines -- support for adapter interruptions
4  *
5  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
6  *			      IBM Corporation
7  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
8  *		 Cornelia Huck (cornelia.huck@de.ibm.com)
9  *		 Arnd Bergmann (arndb@de.ibm.com)
10  */
11 
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/rcupdate.h>
16 
17 #include "cio_debug.h"
18 #include "airq.h"
19 
20 static adapter_int_handler_t adapter_handler;
21 
22 /*
23  * register for adapter interrupts
24  *
25  * With HiperSockets the zSeries architecture provides for
26  *  means of adapter interrups, pseudo I/O interrupts that are
27  *  not tied to an I/O subchannel, but to an adapter. However,
28  *  it doesn't disclose the info how to enable/disable them, but
29  *  to recognize them only. Perhaps we should consider them
30  *  being shared interrupts, and thus build a linked list
31  *  of adapter handlers ... to be evaluated ...
32  */
33 int
34 s390_register_adapter_interrupt (adapter_int_handler_t handler)
35 {
36 	int ret;
37 	char dbf_txt[15];
38 
39 	CIO_TRACE_EVENT (4, "rgaint");
40 
41 	if (handler == NULL)
42 		ret = -EINVAL;
43 	else
44 		ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0);
45 	if (!ret)
46 		synchronize_sched();  /* Allow interrupts to complete. */
47 
48 	sprintf (dbf_txt, "ret:%d", ret);
49 	CIO_TRACE_EVENT (4, dbf_txt);
50 
51 	return ret;
52 }
53 
54 int
55 s390_unregister_adapter_interrupt (adapter_int_handler_t handler)
56 {
57 	int ret;
58 	char dbf_txt[15];
59 
60 	CIO_TRACE_EVENT (4, "urgaint");
61 
62 	if (handler == NULL)
63 		ret = -EINVAL;
64 	else {
65 		adapter_handler = NULL;
66 		synchronize_sched();  /* Allow interrupts to complete. */
67 		ret = 0;
68 	}
69 	sprintf (dbf_txt, "ret:%d", ret);
70 	CIO_TRACE_EVENT (4, dbf_txt);
71 
72 	return ret;
73 }
74 
75 void
76 do_adapter_IO (void)
77 {
78 	CIO_TRACE_EVENT (6, "doaio");
79 
80 	if (adapter_handler)
81 		(*adapter_handler) ();
82 }
83 
84 EXPORT_SYMBOL (s390_register_adapter_interrupt);
85 EXPORT_SYMBOL (s390_unregister_adapter_interrupt);
86