xref: /linux/arch/um/include/shared/irq_kern.h (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
1f2f4bf5aSAlex Dewar /* SPDX-License-Identifier: GPL-2.0 */
28569c914SAl Viro /*
38569c914SAl Viro  * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
48569c914SAl Viro  */
58569c914SAl Viro 
68569c914SAl Viro #ifndef __IRQ_KERN_H__
78569c914SAl Viro #define __IRQ_KERN_H__
88569c914SAl Viro 
937185b33SAl Viro #include <linux/interrupt.h>
10c8177abaSJohannes Berg #include <linux/time-internal.h>
1137185b33SAl Viro #include <asm/ptrace.h>
122fccfcc0SJohannes Berg #include "irq_user.h"
138569c914SAl Viro 
1436d46a59SJohannes Berg #define UM_IRQ_ALLOC	-1
1536d46a59SJohannes Berg 
162fccfcc0SJohannes Berg int um_request_irq(int irq, int fd, enum um_irq_type type,
172fccfcc0SJohannes Berg 		   irq_handler_t handler, unsigned long irqflags,
182fccfcc0SJohannes Berg 		   const char *devname, void *dev_id);
19c8177abaSJohannes Berg 
20c8177abaSJohannes Berg #ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
21c8177abaSJohannes Berg /**
22c8177abaSJohannes Berg  * um_request_irq_tt - request an IRQ with timetravel handler
23c8177abaSJohannes Berg  *
24c8177abaSJohannes Berg  * @irq: the IRQ number, or %UM_IRQ_ALLOC
25c8177abaSJohannes Berg  * @fd: The file descriptor to request an IRQ for
26c8177abaSJohannes Berg  * @type: read or write
27c8177abaSJohannes Berg  * @handler: the (generic style) IRQ handler
28c8177abaSJohannes Berg  * @irqflags: Linux IRQ flags
29c8177abaSJohannes Berg  * @devname: name for this to show
30c8177abaSJohannes Berg  * @dev_id: data pointer to pass to the IRQ handler
31c8177abaSJohannes Berg  * @timetravel_handler: the timetravel interrupt handler, invoked with the IRQ
32c8177abaSJohannes Berg  *	number, fd, dev_id and time-travel event pointer.
33c8177abaSJohannes Berg  *
34c8177abaSJohannes Berg  * Returns: The interrupt number assigned or a negative error.
35c8177abaSJohannes Berg  *
36c8177abaSJohannes Berg  * Note that the timetravel handler is invoked only if the time_travel_mode is
37c8177abaSJohannes Berg  * %TT_MODE_EXTERNAL, and then it is invoked even while the system is suspended!
38c8177abaSJohannes Berg  * This function must call time_travel_add_irq_event() for the event passed with
39c8177abaSJohannes Berg  * an appropriate delay, before sending an ACK on the socket it was invoked for.
40c8177abaSJohannes Berg  *
41c8177abaSJohannes Berg  * If this was called while the system is suspended, then adding the event will
42c8177abaSJohannes Berg  * cause the system to resume.
43c8177abaSJohannes Berg  *
44c8177abaSJohannes Berg  * Since this function will almost certainly have to handle the FD's condition,
45c8177abaSJohannes Berg  * a read will consume the message, and after that it is up to the code using
46c8177abaSJohannes Berg  * it to pass such a message to the @handler in whichever way it can.
47c8177abaSJohannes Berg  *
48c8177abaSJohannes Berg  * If time_travel_mode is not %TT_MODE_EXTERNAL the @timetravel_handler will
49c8177abaSJohannes Berg  * not be invoked at all and the @handler must handle the FD becoming
50c8177abaSJohannes Berg  * readable (or writable) instead. Use um_irq_timetravel_handler_used() to
51c8177abaSJohannes Berg  * distinguish these cases.
52c8177abaSJohannes Berg  *
53c8177abaSJohannes Berg  * See virtio_uml.c for an example.
54c8177abaSJohannes Berg  */
55c8177abaSJohannes Berg int um_request_irq_tt(int irq, int fd, enum um_irq_type type,
56c8177abaSJohannes Berg 		      irq_handler_t handler, unsigned long irqflags,
57c8177abaSJohannes Berg 		      const char *devname, void *dev_id,
58c8177abaSJohannes Berg 		      void (*timetravel_handler)(int, int, void *,
59c8177abaSJohannes Berg 						 struct time_travel_event *));
60c8177abaSJohannes Berg #else
61c8177abaSJohannes Berg static inline
um_request_irq_tt(int irq,int fd,enum um_irq_type type,irq_handler_t handler,unsigned long irqflags,const char * devname,void * dev_id,void (* timetravel_handler)(int,int,void *,struct time_travel_event *))62c8177abaSJohannes Berg int um_request_irq_tt(int irq, int fd, enum um_irq_type type,
63c8177abaSJohannes Berg 		      irq_handler_t handler, unsigned long irqflags,
64c8177abaSJohannes Berg 		      const char *devname, void *dev_id,
65c8177abaSJohannes Berg 		      void (*timetravel_handler)(int, int, void *,
66c8177abaSJohannes Berg 						 struct time_travel_event *))
67c8177abaSJohannes Berg {
68c8177abaSJohannes Berg 	return um_request_irq(irq, fd, type, handler, irqflags,
69c8177abaSJohannes Berg 			      devname, dev_id);
70c8177abaSJohannes Berg }
71c8177abaSJohannes Berg #endif
72c8177abaSJohannes Berg 
um_irq_timetravel_handler_used(void)73c8177abaSJohannes Berg static inline bool um_irq_timetravel_handler_used(void)
74c8177abaSJohannes Berg {
75c8177abaSJohannes Berg 	return time_travel_mode == TT_MODE_EXTERNAL;
76c8177abaSJohannes Berg }
77c8177abaSJohannes Berg 
7836d46a59SJohannes Berg void um_free_irq(int irq, void *dev_id);
79*ab7ca2ebSNick Desaulniers void free_irqs(void);
808569c914SAl Viro #endif
81