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