Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/include/linux/interrupt.h
- This file was copied to sys/compat/linuxkpi/common/src/linux_interrupt.c.
Show All 32 Lines | |||||
#include <linux/cpu.h> | #include <linux/cpu.h> | ||||
#include <linux/device.h> | #include <linux/device.h> | ||||
#include <linux/pci.h> | #include <linux/pci.h> | ||||
#include <linux/irqreturn.h> | #include <linux/irqreturn.h> | ||||
#include <linux/hardirq.h> | #include <linux/hardirq.h> | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/bus.h> | |||||
#include <sys/rman.h> | |||||
#include <sys/interrupt.h> | #include <sys/interrupt.h> | ||||
typedef irqreturn_t (*irq_handler_t)(int, void *); | typedef irqreturn_t (*irq_handler_t)(int, void *); | ||||
#define IRQF_SHARED RF_SHAREABLE | #define IRQF_SHARED RF_SHAREABLE | ||||
struct irq_ent { | struct irq_ent; | ||||
struct list_head links; | |||||
struct device *dev; | |||||
struct resource *res; | |||||
void *arg; | |||||
irqreturn_t (*handler)(int, void *); | |||||
irqreturn_t (*thread_handler)(int, void *); | |||||
void *tag; | |||||
unsigned int irq; | |||||
}; | |||||
void linux_irq_handler(void *); | void linux_irq_handler(void *); | ||||
void lkpi_devm_irq_release(struct device *, void *); | void lkpi_devm_irq_release(struct device *, void *); | ||||
void lkpi_irq_release(struct device *, struct irq_ent *); | void lkpi_irq_release(struct device *, struct irq_ent *); | ||||
int lkpi_request_irq(struct device *, unsigned int, irq_handler_t, | |||||
irq_handler_t, unsigned long, const char *, void *); | |||||
int lkpi_enable_irq(unsigned int); | |||||
void lkpi_disable_irq(unsigned int); | |||||
int lkpi_bind_irq_to_cpu(unsigned int, int); | |||||
void lkpi_free_irq(unsigned int, void *); | |||||
void lkpi_devm_free_irq(struct device *, unsigned int, void *); | |||||
static inline int | static inline int | ||||
linux_irq_rid(struct device *dev, unsigned int irq) | |||||
{ | |||||
/* check for MSI- or MSIX- interrupt */ | |||||
if (irq >= dev->irq_start && irq < dev->irq_end) | |||||
return (irq - dev->irq_start + 1); | |||||
else | |||||
return (0); | |||||
} | |||||
static inline struct irq_ent * | |||||
linux_irq_ent(struct device *dev, unsigned int irq) | |||||
{ | |||||
struct irq_ent *irqe; | |||||
list_for_each_entry(irqe, &dev->irqents, links) | |||||
if (irqe->irq == irq) | |||||
return (irqe); | |||||
return (NULL); | |||||
} | |||||
static inline int | |||||
_request_irq(struct device *xdev, unsigned int irq, | |||||
irq_handler_t handler, irq_handler_t thread_handler, | |||||
unsigned long flags, const char *name, void *arg) | |||||
{ | |||||
struct resource *res; | |||||
struct irq_ent *irqe; | |||||
struct device *dev; | |||||
int error; | |||||
int rid; | |||||
dev = linux_pci_find_irq_dev(irq); | |||||
if (dev == NULL) | |||||
return -ENXIO; | |||||
if (xdev != NULL && xdev != dev) | |||||
return -ENXIO; | |||||
rid = linux_irq_rid(dev, irq); | |||||
res = bus_alloc_resource_any(dev->bsddev, SYS_RES_IRQ, &rid, | |||||
flags | RF_ACTIVE); | |||||
if (res == NULL) | |||||
return (-ENXIO); | |||||
if (xdev != NULL) | |||||
irqe = lkpi_devres_alloc(lkpi_devm_irq_release, sizeof(*irqe), | |||||
GFP_KERNEL | __GFP_ZERO); | |||||
else | |||||
irqe = kzalloc(sizeof(*irqe), GFP_KERNEL); | |||||
irqe->dev = dev; | |||||
irqe->res = res; | |||||
irqe->arg = arg; | |||||
irqe->handler = handler; | |||||
irqe->thread_handler = thread_handler; | |||||
irqe->irq = irq; | |||||
error = bus_setup_intr(dev->bsddev, res, INTR_TYPE_NET | INTR_MPSAFE, | |||||
NULL, linux_irq_handler, irqe, &irqe->tag); | |||||
if (error) | |||||
goto errout; | |||||
list_add(&irqe->links, &dev->irqents); | |||||
if (xdev != NULL) | |||||
devres_add(xdev, irqe); | |||||
return 0; | |||||
errout: | |||||
bus_release_resource(dev->bsddev, SYS_RES_IRQ, rid, irqe->res); | |||||
if (xdev != NULL) | |||||
devres_free(irqe); | |||||
else | |||||
kfree(irqe); | |||||
return (-error); | |||||
} | |||||
static inline int | |||||
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, | request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, | ||||
const char *name, void *arg) | const char *name, void *arg) | ||||
{ | { | ||||
return (_request_irq(NULL, irq, handler, NULL, flags, name, arg)); | return (lkpi_request_irq(NULL, irq, handler, NULL, flags, name, arg)); | ||||
} | } | ||||
static inline int | static inline int | ||||
request_threaded_irq(int irq, irq_handler_t handler, | request_threaded_irq(int irq, irq_handler_t handler, | ||||
irq_handler_t thread_handler, unsigned long flags, | irq_handler_t thread_handler, unsigned long flags, | ||||
const char *name, void *arg) | const char *name, void *arg) | ||||
{ | { | ||||
return (_request_irq(NULL, irq, handler, thread_handler, | return (lkpi_request_irq(NULL, irq, handler, thread_handler, | ||||
flags, name, arg)); | flags, name, arg)); | ||||
} | } | ||||
static inline int | static inline int | ||||
devm_request_threaded_irq(struct device *dev, int irq, | devm_request_threaded_irq(struct device *dev, int irq, | ||||
irq_handler_t handler, irq_handler_t thread_handler, | irq_handler_t handler, irq_handler_t thread_handler, | ||||
unsigned long flags, const char *name, void *arg) | unsigned long flags, const char *name, void *arg) | ||||
{ | { | ||||
return (_request_irq(dev, irq, handler, thread_handler, | return (lkpi_request_irq(dev, irq, handler, thread_handler, | ||||
flags, name, arg)); | flags, name, arg)); | ||||
} | } | ||||
static inline int | static inline int | ||||
enable_irq(unsigned int irq) | enable_irq(unsigned int irq) | ||||
{ | { | ||||
struct irq_ent *irqe; | return (lkpi_enable_irq(irq)); | ||||
struct device *dev; | |||||
dev = linux_pci_find_irq_dev(irq); | |||||
if (dev == NULL) | |||||
return -EINVAL; | |||||
irqe = linux_irq_ent(dev, irq); | |||||
if (irqe == NULL || irqe->tag != NULL) | |||||
return -EINVAL; | |||||
return -bus_setup_intr(dev->bsddev, irqe->res, INTR_TYPE_NET | INTR_MPSAFE, | |||||
NULL, linux_irq_handler, irqe, &irqe->tag); | |||||
} | } | ||||
static inline void | static inline void | ||||
disable_irq(unsigned int irq) | disable_irq(unsigned int irq) | ||||
{ | { | ||||
struct irq_ent *irqe; | lkpi_disable_irq(irq); | ||||
struct device *dev; | |||||
dev = linux_pci_find_irq_dev(irq); | |||||
if (dev == NULL) | |||||
return; | |||||
irqe = linux_irq_ent(dev, irq); | |||||
if (irqe == NULL) | |||||
return; | |||||
if (irqe->tag != NULL) | |||||
bus_teardown_intr(dev->bsddev, irqe->res, irqe->tag); | |||||
irqe->tag = NULL; | |||||
} | } | ||||
static inline int | static inline int | ||||
bind_irq_to_cpu(unsigned int irq, int cpu_id) | bind_irq_to_cpu(unsigned int irq, int cpu_id) | ||||
{ | { | ||||
struct irq_ent *irqe; | return (lkpi_bind_irq_to_cpu(irq, cpu_id)); | ||||
struct device *dev; | |||||
dev = linux_pci_find_irq_dev(irq); | |||||
if (dev == NULL) | |||||
return (-ENOENT); | |||||
irqe = linux_irq_ent(dev, irq); | |||||
if (irqe == NULL) | |||||
return (-ENOENT); | |||||
return (-bus_bind_intr(dev->bsddev, irqe->res, cpu_id)); | |||||
} | } | ||||
static inline void | static inline void | ||||
free_irq(unsigned int irq, void *device __unused) | free_irq(unsigned int irq, void *device __unused) | ||||
hselasky: "device" is no longer __unused here. | |||||
{ | { | ||||
struct irq_ent *irqe; | lkpi_free_irq(irq, device); | ||||
struct device *dev; | |||||
dev = linux_pci_find_irq_dev(irq); | |||||
if (dev == NULL) | |||||
return; | |||||
irqe = linux_irq_ent(dev, irq); | |||||
if (irqe == NULL) | |||||
return; | |||||
lkpi_irq_release(dev, irqe); | |||||
kfree(irqe); | |||||
} | } | ||||
static inline void | static inline void | ||||
devm_free_irq(struct device *xdev, unsigned int irq, void *p) | devm_free_irq(struct device *xdev, unsigned int irq, void *p) | ||||
{ | { | ||||
struct device *dev; | lkpi_devm_free_irq(xdev, irq, p); | ||||
struct irq_ent *irqe; | |||||
dev = linux_pci_find_irq_dev(irq); | |||||
if (dev == NULL) | |||||
return; | |||||
if (xdev != dev) | |||||
return; | |||||
irqe = linux_irq_ent(dev, irq); | |||||
if (irqe == NULL) | |||||
return; | |||||
lkpi_irq_release(dev, irqe); | |||||
lkpi_devres_unlink(dev, irqe); | |||||
lkpi_devres_free(irqe); | |||||
return; | |||||
} | } | ||||
static inline int | static inline int | ||||
irq_set_affinity_hint(int vector, cpumask_t *mask) | irq_set_affinity_hint(int vector, cpumask_t *mask) | ||||
{ | { | ||||
int error; | int error; | ||||
if (mask != NULL) | if (mask != NULL) | ||||
Show All 38 Lines |
"device" is no longer __unused here.