aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorSvatopluk Kraus <skra@FreeBSD.org>2016-03-24 09:55:11 +0000
committerSvatopluk Kraus <skra@FreeBSD.org>2016-03-24 09:55:11 +0000
commit61c8fde5d63adf4b0c05702c4ba060e3cc0f3c69 (patch)
tree4893de0375aab00843476e8638ec2bd3177250ab /sys/kern
parent6227e5963580e94874fc94d57c956494ff965785 (diff)
downloadsrc-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.m13
-rw-r--r--sys/kern/subr_intr.c20
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 */
}