1139804Simp#-
2256861Sbrooks# Copyright (c) 2013 SRI International
3133588Simp# Copyright (c) 1998-2004 Doug Rabson
436973Sdfr# All rights reserved.
536973Sdfr#
636973Sdfr# Redistribution and use in source and binary forms, with or without
736973Sdfr# modification, are permitted provided that the following conditions
836973Sdfr# are met:
936973Sdfr# 1. Redistributions of source code must retain the above copyright
1036973Sdfr#    notice, this list of conditions and the following disclaimer.
1136973Sdfr# 2. Redistributions in binary form must reproduce the above copyright
1236973Sdfr#    notice, this list of conditions and the following disclaimer in the
1336973Sdfr#    documentation and/or other materials provided with the distribution.
1436973Sdfr#
1536973Sdfr# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1636973Sdfr# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1736973Sdfr# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1836973Sdfr# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1936973Sdfr# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2036973Sdfr# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2136973Sdfr# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2236973Sdfr# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2336973Sdfr# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2436973Sdfr# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2536973Sdfr# SUCH DAMAGE.
2636973Sdfr#
2750477Speter# $FreeBSD$
2836973Sdfr#
2936973Sdfr
30212544Savg#include <sys/types.h>
31212544Savg#include <sys/systm.h>
3259093Sdfr#include <sys/bus.h>
3359093Sdfr
34132354Sdfr/**
35256861Sbrooks * @defgroup FST_IC fdt_ic - KObj methods for interrupt controllers
36256861Sbrooks * @brief A set of methods required device drivers that are interrupt
37256861Sbrooks * controllers.  Derived from sys/kern/bus_if.m.
38132354Sdfr * @{
39132354Sdfr */
40256861SbrooksINTERFACE fdt_ic;
4136973Sdfr
42132354Sdfr/**
43256861Sbrooks * @brief Allocate an interrupt resource
44132354Sdfr *
45256861Sbrooks * This method is called by child devices of an interrupt controller to
46256861Sbrooks * allocate an interrup. The meaning of the resource-ID field varies
47256861Sbrooks * from bus to bus and is opaque to the interrupt controller. If a
48256861Sbrooks * resource was allocated and the caller did not use the RF_ACTIVE
49256861Sbrooks * to specify that it should be activated immediately, the caller is
50256861Sbrooks * responsible for calling FDT_IC_ACTIVATE_INTR() when it actually uses
51256861Sbrooks * the interupt.
52132354Sdfr *
53256861Sbrooks * @param _dev		the interrupt-parent device of @p _child
54132354Sdfr * @param _child	the device which is requesting an allocation
55132354Sdfr * @param _rid		a pointer to the resource identifier
56256861Sbrooks * @param _irq		interrupt source to allocate
57132354Sdfr * @param _flags	any extra flags to control the resource
58132354Sdfr *			allocation - see @c RF_XXX flags in
59132354Sdfr *			<sys/rman.h> for details
60132354Sdfr * 
61256861Sbrooks * @returns		the interrupt which was allocated or @c NULL if no
62132354Sdfr *			resource could be allocated
63132354Sdfr */
64256861SbrooksMETHOD struct resource * alloc_intr {
6595201Smarkm	device_t	_dev;
6695201Smarkm	device_t	_child;
6795201Smarkm	int	       *_rid;
68256861Sbrooks	u_long		_irq;
6995201Smarkm	u_int		_flags;
70256861Sbrooks};
7137592Sdfr
72132354Sdfr/**
73256861Sbrooks * @brief Activate an interrupt
74132354Sdfr *
75256861Sbrooks * Activate an interrupt previously allocated with FDT_IC_ALLOC_INTR().
76132354Sdfr *
77132354Sdfr * @param _dev		the parent device of @p _child
78256861Sbrooks * @param _r		interrupt to activate
79132354Sdfr */
80256861SbrooksMETHOD int activate_intr {
8195201Smarkm	device_t	_dev;
8295201Smarkm	struct resource *_r;
8341153Swollman};
8441153Swollman
85132354Sdfr/**
86256861Sbrooks * @brief Deactivate an interrupt
87132354Sdfr *
88256861Sbrooks * Deactivate a resource previously allocated with FDT_IC_ALLOC_INTR().
89132354Sdfr *
90132354Sdfr * @param _dev		the parent device of @p _child
91256861Sbrooks * @param _r		the interrupt to deactivate
92132354Sdfr */
93256861SbrooksMETHOD int deactivate_intr {
9495201Smarkm	device_t	_dev;
9595201Smarkm	struct resource *_r;
9641153Swollman};
9741153Swollman
98132354Sdfr/**
99256861Sbrooks * @brief Release an interrupt
100221231Sjhb *
101256861Sbrooks * Free an interupt allocated by the FDT_IC_ALLOC_INTR.
102221231Sjhb *
103221231Sjhb * @param _dev		the parent device of @p _child
104132354Sdfr * @param _r		the resource to release
105132354Sdfr */
106256861SbrooksMETHOD int release_intr {
10795201Smarkm	device_t	_dev;
10895201Smarkm	struct resource *_res;
10937592Sdfr};
11041153Swollman
111132354Sdfr/**
112132354Sdfr * @brief Install an interrupt handler
113132354Sdfr *
114132354Sdfr * This method is used to associate an interrupt handler function with
115132354Sdfr * an irq resource. When the interrupt triggers, the function @p _intr
116132354Sdfr * will be called with the value of @p _arg as its single
117132354Sdfr * argument. The value returned in @p *_cookiep is used to cancel the
118132354Sdfr * interrupt handler - the caller should save this value to use in a
119256861Sbrooks * future call to FDT_IC_TEARDOWN_INTR().
120132354Sdfr * 
121256861Sbrooks * @param _dev		the interrupt-parent device of @p _child
122132354Sdfr * @param _child	the device which allocated the resource
123132354Sdfr * @param _irq		the resource representing the interrupt
124132354Sdfr * @param _flags	a set of bits from enum intr_type specifying
125132354Sdfr *			the class of interrupt
126132354Sdfr * @param _intr		the function to call when the interrupt
127132354Sdfr *			triggers
128132354Sdfr * @param _arg		a value to use as the single argument in calls
129132354Sdfr *			to @p _intr
130132354Sdfr * @param _cookiep	a pointer to a location to recieve a cookie
131132354Sdfr *			value that may be used to remove the interrupt
132132354Sdfr *			handler
133132354Sdfr */
13441153SwollmanMETHOD int setup_intr {
13595201Smarkm	device_t	_dev;
13695201Smarkm	device_t	_child;
13795201Smarkm	struct resource *_irq;
13895201Smarkm	int		_flags;
139166901Spiso	driver_filter_t	*_filter;
14095201Smarkm	driver_intr_t	*_intr;
14195201Smarkm	void		*_arg;
14295201Smarkm	void		**_cookiep;
14341153Swollman};
14441153Swollman
145132354Sdfr/**
146132354Sdfr * @brief Uninstall an interrupt handler
147132354Sdfr *
148132354Sdfr * This method is used to disassociate an interrupt handler function
149132354Sdfr * with an irq resource. The value of @p _cookie must be the value
150256861Sbrooks * returned from a previous call to FDT_IC_SETUP_INTR().
151132354Sdfr * 
152256861Sbrooks * @param _dev		the interrupt-parent device of @p _child
153132354Sdfr * @param _child	the device which allocated the resource
154132354Sdfr * @param _irq		the resource representing the interrupt
155132354Sdfr * @param _cookie	the cookie value returned when the interrupt
156132354Sdfr *			was originally registered
157132354Sdfr */
15841153SwollmanMETHOD int teardown_intr {
15995201Smarkm	device_t	_dev;
16095201Smarkm	device_t	_child;
16195201Smarkm	struct resource	*_irq;
16295201Smarkm	void		*_cookie;
16341153Swollman};
16452174Sdfr
165132354Sdfr/**
166177467Sjhb * @brief Allow drivers to request that an interrupt be bound to a specific
167177467Sjhb * CPU.
168177467Sjhb * 
169256861Sbrooks * @param _dev		the interrupt-parent device of @p _child
170177467Sjhb * @param _child	the device which allocated the resource
171177467Sjhb * @param _irq		the resource representing the interrupt
172177467Sjhb * @param _cpu		the CPU to bind the interrupt to
173177467Sjhb */
174177467SjhbMETHOD int bind_intr {
175177467Sjhb	device_t	_dev;
176177467Sjhb	device_t	_child;
177177467Sjhb	struct resource *_irq;
178177467Sjhb	int		_cpu;
179256861Sbrooks};
180177467Sjhb
181177467Sjhb/**
182256861Sbrooks * @brief Allow drivers to specify the trigger mode and polarity
183132354Sdfr * of the specified interrupt.
184132354Sdfr * 
185256861Sbrooks * @param _dev		the interrupt-parent device
186132354Sdfr * @param _irq		the interrupt number to modify
187132354Sdfr * @param _trig		the trigger mode required
188132354Sdfr * @param _pol		the interrupt polarity required
189132354Sdfr */
190119967SmarcelMETHOD int config_intr {
191119967Smarcel	device_t	_dev;
192119967Smarcel	int		_irq;
193119967Smarcel	enum intr_trigger _trig;
194119967Smarcel	enum intr_polarity _pol;
195256861Sbrooks};
196160186Simp
197160186Simp/**
198198134Sjhb * @brief Allow drivers to associate a description with an active
199198134Sjhb * interrupt handler.
200198134Sjhb *
201256861Sbrooks * @param _dev		the interrupt-parent device of @p _child
202198134Sjhb * @param _child	the device which allocated the resource
203198134Sjhb * @param _irq		the resource representing the interrupt
204198134Sjhb * @param _cookie	the cookie value returned when the interrupt
205198134Sjhb *			was originally registered
206198134Sjhb * @param _descr	the description to associate with the interrupt
207198134Sjhb */
208198134SjhbMETHOD int describe_intr {
209198134Sjhb	device_t	_dev;
210198134Sjhb	device_t	_child;
211198134Sjhb	struct resource *_irq;
212198134Sjhb	void		*_cookie;
213198134Sjhb	const char	*_descr;
214160186Simp};
215161928Sjmg
216161928Sjmg/**
217256861Sbrooks * @brief Notify an ic that specified child's IRQ should be remapped.
218161928Sjmg *
219256861Sbrooks * @param _dev		the interrupt-parent device
220256861Sbrooks * @param _child	the child device
221256861Sbrooks * @param _irq		the irq number
222161928Sjmg */
223256861SbrooksMETHOD int remap_intr {
224161928Sjmg	device_t	_dev;
225161928Sjmg	device_t	_child;
226256861Sbrooks	u_int		_irq;
227256861Sbrooks};
228185059Sjhb
229185059Sjhb/**
230256861Sbrooks * @brief Enable an IPI source.
231185059Sjhb *
232256861Sbrooks * @param _dev		the interrupt controller
233256861Sbrooks * @param _tid		the thread ID (relative to the interrupt controller)
234256861Sbrooks *			to enable IPIs for
235256861Sbrooks * @param _ipi_irq	hardware IRQ to send IPIs to
236185059Sjhb */
237256861SbrooksMETHOD void setup_ipi {
238185059Sjhb	device_t	_dev;
239256861Sbrooks	u_int		_tid;
240256861Sbrooks	u_int		_irq;
241185059Sjhb};
242185059Sjhb
243193833Sjhb/**
244256861Sbrooks * @brief Send an IPI to the specified thread.
245193833Sjhb *
246256861Sbrooks * @param _dev		the interrupt controller
247256861Sbrooks * @param _tid		the thread ID (relative to the interrupt controller)
248256861Sbrooks *			to send IPIs to
249193833Sjhb */
250256861SbrooksMETHOD void send_ipi {
251193833Sjhb	device_t	_dev;
252256861Sbrooks	u_int		_tid;
253256861Sbrooks};
254209154Smav
255209154Smav/**
256256861Sbrooks * @brief Clear the IPI on the specfied thread.  Only call with the
257256861Sbrooks * local hardware thread or interrupts may be lost!
258209154Smav *
259256861Sbrooks * @param _dev		the interrupt controller
260256861Sbrooks * @param _tid		the thread ID (relative to the interrupt controller)
261256861Sbrooks *			to clear the IPI on
262209154Smav */
263256861SbrooksMETHOD void clear_ipi {
264209154Smav	device_t	_dev;
265256861Sbrooks	u_int		_tid;
266256861Sbrooks};
267