diff options
author | Svatopluk Kraus <skra@FreeBSD.org> | 2016-03-24 09:55:11 +0000 |
---|---|---|
committer | Svatopluk Kraus <skra@FreeBSD.org> | 2016-03-24 09:55:11 +0000 |
commit | 61c8fde5d63adf4b0c05702c4ba060e3cc0f3c69 (patch) | |
tree | 4893de0375aab00843476e8638ec2bd3177250ab /sys/kern | |
parent | 6227e5963580e94874fc94d57c956494ff965785 (diff) | |
download | src-61c8fde5d63adf4b0c05702c4ba060e3cc0f3c69.tar.gz src-61c8fde5d63adf4b0c05702c4ba060e3cc0f3c69.zip |
Generalize IPI support for ARM intrng and use it for interrupt
controller IPI provider.
New struct intr_ipi is defined which keeps all info about an IPI:
its name, counter, send and dispatch methods. Generic intr_ipi_setup(),
intr_ipi_send() and intr_ipi_dispatch() functions are implemented.
An IPI provider must implement two functions:
(1) an intr_ipi_send_t function which is able to send an IPI,
(2) a setup function which initializes itself for an IPI and
calls intr_ipi_setup() with appropriate arguments.
Differential Revision: https://reviews.freebsd.org/D5700
Notes
Notes:
svn path=/head/; revision=297230
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/pic_if.m | 13 | ||||
-rw-r--r-- | sys/kern/subr_intr.c | 20 |
2 files changed, 23 insertions, 10 deletions
diff --git a/sys/kern/pic_if.m b/sys/kern/pic_if.m index 2309f0c9fd9f..04d5f5f1afad 100644 --- a/sys/kern/pic_if.m +++ b/sys/kern/pic_if.m @@ -60,6 +60,13 @@ CODE { { return; } + + static int + dflt_pic_ipi_setup(device_t dev, u_int ipi, struct intr_irqsrc *isrc) + { + + return (EOPNOTSUPP); + } }; METHOD int register { @@ -122,3 +129,9 @@ METHOD void ipi_send { struct intr_irqsrc *isrc; cpuset_t cpus; } DEFAULT null_pic_ipi_send; + +METHOD int ipi_setup { + device_t dev; + u_int ipi; + struct intr_irqsrc *isrc; +} DEFAULT dflt_pic_ipi_setup; diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c index 1c97fd48af21..a92c642afe4d 100644 --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -311,8 +311,8 @@ intr_irq_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf) /* * Allocate interrupt source. */ -static struct intr_irqsrc * -isrc_alloc(u_int type, u_int extsize) +struct intr_irqsrc * +intr_isrc_alloc(u_int type, u_int extsize) { struct intr_irqsrc *isrc; @@ -329,8 +329,8 @@ isrc_alloc(u_int type, u_int extsize) /* * Free interrupt source. */ -static void -isrc_free(struct intr_irqsrc *isrc) +void +intr_isrc_free(struct intr_irqsrc *isrc) { free(isrc, M_INTRNG); @@ -462,20 +462,20 @@ intr_namespace_map_irq(device_t dev, uint16_t type, uint16_t num) struct intr_irqsrc *isrc, *new_isrc; int error; - new_isrc = isrc_alloc(INTR_ISRCT_NAMESPACE, 0); + new_isrc = intr_isrc_alloc(INTR_ISRCT_NAMESPACE, 0); mtx_lock(&isrc_table_lock); isrc = isrc_namespace_lookup(dev, type, num); if (isrc != NULL) { mtx_unlock(&isrc_table_lock); - isrc_free(new_isrc); + intr_isrc_free(new_isrc); return (isrc->isrc_irq); /* already mapped */ } error = isrc_alloc_irq_locked(new_isrc); if (error != 0) { mtx_unlock(&isrc_table_lock); - isrc_free(new_isrc); + intr_isrc_free(new_isrc); return (IRQ_INVALID); /* no space left */ } @@ -526,20 +526,20 @@ intr_fdt_map_irq(phandle_t node, pcell_t *cells, u_int ncells) xref = (intptr_t)node; /* It's so simple for now. */ cellsize = ncells * sizeof(*cells); - new_isrc = isrc_alloc(INTR_ISRCT_FDT, cellsize); + new_isrc = intr_isrc_alloc(INTR_ISRCT_FDT, cellsize); mtx_lock(&isrc_table_lock); isrc = isrc_fdt_lookup(xref, cells, ncells); if (isrc != NULL) { mtx_unlock(&isrc_table_lock); - isrc_free(new_isrc); + intr_isrc_free(new_isrc); return (isrc->isrc_irq); /* already mapped */ } error = isrc_alloc_irq_locked(new_isrc); if (error != 0) { mtx_unlock(&isrc_table_lock); - isrc_free(new_isrc); + intr_isrc_free(new_isrc); return (IRQ_INVALID); /* no space left */ } |