Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/intr_machdep.c
Show First 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | static SLIST_HEAD(, arm64_intr_entry) irq_slist_head = | ||||
SLIST_HEAD_INITIALIZER(irq_slist_head); | SLIST_HEAD_INITIALIZER(irq_slist_head); | ||||
struct arm64_intr_entry { | struct arm64_intr_entry { | ||||
SLIST_ENTRY(arm64_intr_entry) entries; | SLIST_ENTRY(arm64_intr_entry) entries; | ||||
struct intr_event *i_event; | struct intr_event *i_event; | ||||
enum intr_trigger i_trig; | enum intr_trigger i_trig; | ||||
enum intr_polarity i_pol; | enum intr_polarity i_pol; | ||||
int fwcode; /* Code from HW description */ | |||||
u_int i_hw_irq; /* Physical interrupt number */ | u_int i_hw_irq; /* Physical interrupt number */ | ||||
u_int i_cntidx; /* Index in intrcnt table */ | u_int i_cntidx; /* Index in intrcnt table */ | ||||
u_int i_handlers; /* Allocated handlers */ | u_int i_handlers; /* Allocated handlers */ | ||||
u_int i_cpu; /* Assigned CPU */ | u_int i_cpu; /* Assigned CPU */ | ||||
u_long *i_cntp; /* Interrupt hit counter */ | u_long *i_cntp; /* Interrupt hit counter */ | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | if (intr == NULL) | ||||
return (NULL); | return (NULL); | ||||
/* The default CPU is 0 but can be changed later by bind or shuffle */ | /* The default CPU is 0 but can be changed later by bind or shuffle */ | ||||
intr->i_cpu = 0; | intr->i_cpu = 0; | ||||
intr->i_event = NULL; | intr->i_event = NULL; | ||||
intr->i_handlers = 0; | intr->i_handlers = 0; | ||||
intr->i_trig = INTR_TRIGGER_CONFORM; | intr->i_trig = INTR_TRIGGER_CONFORM; | ||||
intr->i_pol = INTR_POLARITY_CONFORM; | intr->i_pol = INTR_POLARITY_CONFORM; | ||||
intr->fwcode = -1; | |||||
intr->i_cntidx = atomic_fetchadd_int(&intrcntidx, 1); | intr->i_cntidx = atomic_fetchadd_int(&intrcntidx, 1); | ||||
intr->i_cntp = &intrcnt[intr->i_cntidx]; | intr->i_cntp = &intrcnt[intr->i_cntidx]; | ||||
intr->i_hw_irq = hw_irq; | intr->i_hw_irq = hw_irq; | ||||
mtx_lock_spin(&intr_list_lock); | mtx_lock_spin(&intr_list_lock); | ||||
SLIST_INSERT_HEAD(&irq_slist_head, intr, entries); | SLIST_INSERT_HEAD(&irq_slist_head, intr, entries); | ||||
mtx_unlock_spin(&intr_list_lock); | mtx_unlock_spin(&intr_list_lock); | ||||
return intr; | return intr; | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | |||||
* Finalize interrupts bring-up (should be called from configure_final()). | * Finalize interrupts bring-up (should be called from configure_final()). | ||||
* Enables all interrupts registered by bus_setup_intr() during boot | * Enables all interrupts registered by bus_setup_intr() during boot | ||||
* as well as unlocks interrups reception on primary CPU. | * as well as unlocks interrups reception on primary CPU. | ||||
*/ | */ | ||||
int | int | ||||
arm_enable_intr(void) | arm_enable_intr(void) | ||||
{ | { | ||||
struct arm64_intr_entry *intr; | struct arm64_intr_entry *intr; | ||||
int error; | |||||
if (root_pic == NULL) | if (root_pic == NULL) | ||||
panic("Cannot enable interrupts. No PIC configured"); | panic("Cannot enable interrupts. No PIC configured"); | ||||
/* | /* | ||||
* Iterate through all possible interrupts and perform | * Iterate through all possible interrupts and perform | ||||
* configuration if the interrupt is registered. | * configuration if the interrupt is registered. | ||||
*/ | */ | ||||
Show All 12 Lines | if (intr->i_cntidx >= arm64_nintrs) { | ||||
"registered PIC. Max interrupt number: %u", __func__, | "registered PIC. Max interrupt number: %u", __func__, | ||||
intr->i_cntidx, arm64_nintrs - 1)); | intr->i_cntidx, arm64_nintrs - 1)); | ||||
/* Print message and disable otherwise */ | /* Print message and disable otherwise */ | ||||
printf("ERROR: Cannot enable irq %u. Disabling.\n", | printf("ERROR: Cannot enable irq %u. Disabling.\n", | ||||
intr->i_cntidx); | intr->i_cntidx); | ||||
PIC_MASK(root_pic, intr->i_hw_irq); | PIC_MASK(root_pic, intr->i_hw_irq); | ||||
} | } | ||||
if (intr->i_trig == INTR_TRIGGER_CONFORM && | |||||
intr->i_pol == INTR_POLARITY_CONFORM) { | |||||
PIC_TRANSLATE_CODE(root_pic, intr->i_hw_irq, | |||||
intr->fwcode, &intr->i_trig, &intr->i_pol); | |||||
} | |||||
if (intr->i_trig != INTR_TRIGGER_CONFORM || | if (intr->i_trig != INTR_TRIGGER_CONFORM || | ||||
intr->i_pol != INTR_POLARITY_CONFORM) { | intr->i_pol != INTR_POLARITY_CONFORM) { | ||||
PIC_CONFIG(root_pic, intr->i_hw_irq, | error = PIC_CONFIG(root_pic, intr->i_hw_irq, | ||||
intr->i_trig, intr->i_pol); | intr->i_trig, intr->i_pol); | ||||
if (error != 0) | |||||
printf("Error: Cannot configure irq %u.\n", | |||||
intr->i_hw_irq); | |||||
} | } | ||||
if (intr->i_handlers > 0) | if (intr->i_handlers > 0) | ||||
PIC_UNMASK(root_pic, intr->i_hw_irq); | PIC_UNMASK(root_pic, intr->i_hw_irq); | ||||
} | } | ||||
/* Enable interrupt reception on this CPU */ | /* Enable interrupt reception on this CPU */ | ||||
intr_enable(); | intr_enable(); | ||||
Show All 31 Lines | arm_setup_intr(const char *name, driver_filter_t *filt, driver_intr_t handler, | ||||
error = intr_event_add_handler(intr->i_event, name, filt, handler, arg, | error = intr_event_add_handler(intr->i_event, name, filt, handler, arg, | ||||
intr_priority(flags), flags, cookiep); | intr_priority(flags), flags, cookiep); | ||||
if (!error) { | if (!error) { | ||||
intrcnt_setname(intr->i_event->ie_fullname, intr->i_cntidx); | intrcnt_setname(intr->i_event->ie_fullname, intr->i_cntidx); | ||||
intr->i_handlers++; | intr->i_handlers++; | ||||
if (!cold && (root_pic != NULL) && (intr->i_handlers == 1)) { | if (!cold && (root_pic != NULL) && (intr->i_handlers == 1)) { | ||||
if (intr->i_trig == INTR_TRIGGER_CONFORM && | |||||
intr->i_pol == INTR_POLARITY_CONFORM) { | |||||
PIC_TRANSLATE_CODE(root_pic, hw_irq, | |||||
intr->fwcode, &intr->i_trig, &intr->i_pol); | |||||
} | |||||
if (intr->i_trig != INTR_TRIGGER_CONFORM || | if (intr->i_trig != INTR_TRIGGER_CONFORM || | ||||
intr->i_pol != INTR_POLARITY_CONFORM) { | intr->i_pol != INTR_POLARITY_CONFORM) { | ||||
PIC_CONFIG(root_pic, intr->i_hw_irq, intr->i_trig, | error = PIC_CONFIG(root_pic, intr->i_hw_irq, | ||||
intr->i_pol); | intr->i_trig, intr->i_pol); | ||||
} | } | ||||
if (!error) | |||||
PIC_UNMASK(root_pic, intr->i_hw_irq); | PIC_UNMASK(root_pic, intr->i_hw_irq); | ||||
} | } | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
intr_irq_remove_handler(device_t dev, u_int irq, void *cookie) | intr_irq_remove_handler(device_t dev, u_int irq, void *cookie) | ||||
Show All 28 Lines | intr_irq_config(u_int hw_irq, enum intr_trigger trig, enum intr_polarity pol) | ||||
/* | /* | ||||
* Return success if PIC cannot be called yet. The interrupt will be | * Return success if PIC cannot be called yet. The interrupt will be | ||||
* configured at a later time based on i_trig and i_pol. | * configured at a later time based on i_trig and i_pol. | ||||
*/ | */ | ||||
rv = 0; | rv = 0; | ||||
if (!cold && root_pic != NULL) | if (!cold && root_pic != NULL) | ||||
rv = PIC_CONFIG(root_pic, hw_irq, trig, pol); | rv = PIC_CONFIG(root_pic, hw_irq, trig, pol); | ||||
return (rv); | |||||
} | |||||
int | |||||
arm_fw_config_intr(u_int hw_irq, int sense_code) | |||||
{ | |||||
struct arm64_intr_entry *intr; | |||||
int rv; | |||||
intr = intr_allocate(hw_irq); | |||||
if (intr == NULL) | |||||
return (ENOMEM); | |||||
/* | |||||
* Store FW code to be able to translate it later if root_pic is not | |||||
* currently available | |||||
*/ | |||||
intr->fwcode = sense_code; | |||||
rv = 0; | |||||
if (!cold && root_pic != NULL) { | |||||
if (intr->i_trig == INTR_TRIGGER_CONFORM && | |||||
intr->i_pol == INTR_POLARITY_CONFORM) { | |||||
PIC_TRANSLATE_CODE(root_pic, hw_irq, intr->fwcode, | |||||
&intr->i_trig, &intr->i_pol); | |||||
rv = PIC_CONFIG(root_pic, hw_irq, intr->i_trig, | |||||
intr->i_pol); | |||||
} | |||||
} | |||||
return (rv); | return (rv); | ||||
} | } | ||||
void | void | ||||
arm_dispatch_intr(u_int hw_irq, struct trapframe *tf) | arm_dispatch_intr(u_int hw_irq, struct trapframe *tf) | ||||
{ | { | ||||
struct arm64_intr_entry *intr; | struct arm64_intr_entry *intr; | ||||
▲ Show 20 Lines • Show All 133 Lines • Show Last 20 Lines |