Interrupt Handler
Kernel-space interrupt handler declarations.
Interrupt handlers may be either stand-alone or associated with an event
source. Stand-alone interrupt handlers must be installed / removed by
calling cuddlk_interrupt_register() /
cuddlk_interrupt_unregister(), whereas interrupt handlers associated
with and event source are automatically installed and removed as part the
parent device’s registration process.
This part of the API is only applicable to kernel-space code.
Note that the comments in this file regarding Linux UIO and Xenomai UDD implementations are based on linux-cip-4.19.94-cip18 and xenomai-3.1, but other versions are probably very similar.
-
enum cuddlk_interrupt_handler_return_value
Interrupt handler return values.
Constants
CUDDLK_RET_INTR_NOT_HANDLEDIndicates that the interrupt was not handled. Usually this means that the interrupt was generated by another device.
CUDDLK_RET_INTR_HANDLEDIndicates that the interrupt was handled.
Description
Possible return values for interrupt handlers.
Similar to:
IRQ_* (type irqreturn_t) in linux/irqreturn.h for Linux UIO
RTDM_IRQ_* (#define) in rtdm/driver.h for Xenomai UDD
XN_IRQ_* (#define) in cobalt/kernel/intr.h for Xenomai UDD
Note that the equivalent Xenomai UDD and Linux UIO constants have different values, but this should not matter for our purposes because a single interrupt system will be selected at compile time.
-
enum cuddlk_special_irq_value
Special-purpose irq values.
Constants
CUDDLK_IRQ_NONENo hardware interrupts or user-space interrupt events are associated with this device
CUDDLK_IRQ_CUSTOMNo hardware interrupts are associated with this device, but user-space interrupt events may be generated by calling
cuddlk_eventsrc_notify(). This value is only applicable tocuddlk_interruptinstances associated with an event source, not stand-alone interrupt handlers.
Description
Special-purpose values for the irq member of the cuddlk_interrupt
struct.
Similar to:
UIO_IRQ_* (#define) in linux/uio_driver.h for Linux UIO
UDD_IRQ_* (#define) in rtdm/udd.h for Xenomai UDD
Note that the equivalent Xenomai UDD and Linux UIO constants have similar values, but this is not strictly necessary for our purposes because a single interrupt system will be selected at compile time.
Our implementation does rely on the condition that CUDDLK_IRQ_NONE is
0 for proper default initialization, so we confirm this via a
compile-time assertion in cuddlk_linux.c.
-
enum cuddlk_interrupt_flags
Interrupt flags for kernel space.
Constants
CUDDLK_IRQF_SHAREDTell the kernel to enable interrupt sharing with other drivers.
Description
Flags that describe the properties of an interrupt. These may be used in
the flags member of the cuddlk_interrupt struct.
Similar to:
IRQF_SHARED (#define) in linux/interrupt.h for Linux UIO
RTDM_IRQTYPE_SHARED (#define) in rtdm/driver.h for Xenomai UDD
XN_IRQTYPE_SHARED (#define) in kernel/intr.h for Xenomai UDD
Note that the equivalent Xenomai UDD and Linux UIO constants have different values, but that is taken into account in the implementation.
-
struct cuddlk_interrupt_kernel
Kernel-managed interrupt data members.
Definition
struct cuddlk_interrupt_kernel {
};
Members
Description
Kernel-managed cuddlk_interrupt data that is available for use by
Cuddl drivers.
-
struct cuddlk_interrupt
Interrupt handler/masking data structure.
Definition
struct cuddlk_interrupt {
int (*handler)(struct cuddlk_interrupt *intr);
int (*disable) (struct cuddlk_interrupt *intr);
int (*enable) (struct cuddlk_interrupt *intr);
int (*is_enabled) (struct cuddlk_interrupt *intr);
cuddlk_iomem_t *iomem_ptr;
void *extra_ptr;
int irq;
int flags;
struct cuddlk_interrupt_kernel kernel;
struct cuddlki_interrupt_priv priv;
};
Members
handlerPointer to the interrupt handler routine to be called when a hardware interrupt occurs. This routine should check for and mask any pending interrupts and then return the applicable value from the
cuddlk_interrupt_handler_return_valueenumeration. If this field is set toNULL, then no interrupt handler will be installed. Typically a value ofNULLonly makes sense when settingirqtoCUDDLK_IRQ_NONEorCUDDLK_IRQ_CUSTOM.Linux UIO equivalent in linux/uio_driver.h:
irqreturn_t (*handler)(int irq, struct uio_info *dev_info);
Xenomai UDD equivalent in rtdm/udd.h:
int (*interrupt)(struct udd_device *udd);
disablePointer to a routine that will disable the interrupt source. A return value of
0indicates success and a negative value indicates failure. This field may be set toNULLif external interrupt disabling control is not required.enablePointer to a routine that will enable the interrupt source. A return value of
0indicates success and a negative value indicates failure. This field may be set toNULLif external interrupt enabling control is not required.is_enabledPointer to a routine that will return a boolean value indicating whether or not the interrupt source is currently enabled. A return value of
0indicates that the interrupt is disabled, a value of1indicates that the interrupt is enabled, and a negative value indicates an error condition. This field may be set toNULLif external interrupt status querying is not required.iomem_ptrThis field is available for use by Cuddl drivers to store a pointer to mapped I/O memory. This field is not managed (or used) by the Cuddl implementation, so this field must set up (if desired) manually during driver initialization.
extra_ptrThis field is available for use by Cuddl drivers to store a pointer to a custom data structure for use by the driver. This field is not manged or used by the Cuddl implementation.
irqIRQ number for which the associated handler will be installed, or one of the
cuddlk_special_irq_valueenumerations.Under Linux UIO, the device IRQ number can be read from a file such as:
/sys/class/uio/uio0/device/irq
The associated UIO/UDD field declarations look like this:
UIO: long irq; UDD: int irq;
flagsFlags that describe the properties of the interrupt. This field may be a set of
cuddlk_interrupt_flagsORed together.kernelKernel-managed memory region data that is available for use by Cuddl drivers.
privPrivate memory region data reserved for internal use by the Cuddl implementation.
Description
Data structure for setting up an interrupt handler in kernel space.
Unused members of this data structure must be set to zero. This is
typically done by allocating this structure via kzalloc() or using
memset() to zeroize the structure after allocation.
-
int cuddlk_interrupt_register(struct cuddlk_interrupt *intr, const char *name)
Register a Cuddl interrupt handler.
Parameters
struct cuddlk_interrupt *intrCuddl interrupt structure describing the interrupt to register.
const char *nameUnique name for this interrupt.
Description
This routine is used to register a stand-alone interrupt handler. Interrupt handlers associated with an event source are automatically installed as part the parent device’s registration process.
In other words, hardware interrupts may be handled by populating the
events member of a cuddlk_device and registering it, or by
installing a separate handler that is not associated with one particular
device. This function accomplishes the latter.
Linux UIO equivalent in linux/interrupt.h:
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long
flags, const char *name, void *dev);
Xenomai UDD equivalent in rtdm/driver.h:
int rtdm_irq_request(rtdm_irq_t *irq_handle, unsigned int irq_no,
rtdm_irq_handler_t handler, unsigned long flags,
const char *device_name, void *arg);
Return
0 on success, or a negative error code.
- Error codes:
Error code returned by
request_irq()(Linux UIO).Error code returned by
rtdm_irq_request()(Xenomai UDD).
-
int cuddlk_interrupt_unregister(struct cuddlk_interrupt *intr)
Unregister a Cuddl interrupt handler.
Parameters
struct cuddlk_interrupt *intrCuddl interrupt structure describing the interrupt to unregister.
Description
This routine is used to unregister a stand-alone interrupt handler. Interrupt handlers associated with an event source are automatically removed as part the parent device’s registratio clean-up process.
Linux UIO equivalent in linux/interrupt.h:
void *free_irq(unsigned int, void *);
Xenomai UDD equivalent in rtdm/driver.h:
int rtdm_irq_free(rtdm_irq_t *irq_handle);
Return
0 on success, or a negative error code.
- Error codes:
None (Linux UIO).
Error code returned by
rtdm_irq_free()(Xenomai UDD).