Lines Matching full:interrupt
9 * The IPA has an interrupt line distinct from the interrupt used by the GSI
13 * embedded in the IPA. Each IPA interrupt type can be both masked and
23 #include <linux/interrupt.h>
32 * struct ipa_interrupt - IPA interrupt information
36 * @handler: Array of handlers indexed by IPA interrupt ID
45 /* Returns true if the interrupt type is associated with the microcontroller */
46 static bool ipa_interrupt_uc(struct ipa_interrupt *interrupt, u32 irq_id) in ipa_interrupt_uc() argument
51 /* Process a particular interrupt type that has been received */
52 static void ipa_interrupt_process(struct ipa_interrupt *interrupt, u32 irq_id) in ipa_interrupt_process() argument
54 bool uc_irq = ipa_interrupt_uc(interrupt, irq_id); in ipa_interrupt_process()
55 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_process()
60 /* For microcontroller interrupts, clear the interrupt right away, in ipa_interrupt_process()
68 if (irq_id < IPA_IRQ_COUNT && interrupt->handler[irq_id]) in ipa_interrupt_process()
69 interrupt->handler[irq_id](interrupt->ipa, irq_id); in ipa_interrupt_process()
71 /* Clearing the SUSPEND_TX interrupt also clears the register in ipa_interrupt_process()
72 * that tells us which suspended endpoint(s) caused the interrupt, in ipa_interrupt_process()
82 struct ipa_interrupt *interrupt = dev_id; in ipa_isr_thread() local
83 struct ipa *ipa = interrupt->ipa; in ipa_isr_thread()
84 u32 enabled = interrupt->enabled; in ipa_isr_thread()
98 * including conditions whose interrupt is not enabled. Handle in ipa_isr_thread()
110 ipa_interrupt_process(interrupt, irq_id); in ipa_isr_thread()
131 static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt, in ipa_interrupt_suspend_control() argument
134 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_suspend_control()
142 /* IPA version 3.0 does not support TX_SUSPEND interrupt control */ in ipa_interrupt_suspend_control()
158 ipa_interrupt_suspend_enable(struct ipa_interrupt *interrupt, u32 endpoint_id) in ipa_interrupt_suspend_enable() argument
160 ipa_interrupt_suspend_control(interrupt, endpoint_id, true); in ipa_interrupt_suspend_enable()
165 ipa_interrupt_suspend_disable(struct ipa_interrupt *interrupt, u32 endpoint_id) in ipa_interrupt_suspend_disable() argument
167 ipa_interrupt_suspend_control(interrupt, endpoint_id, false); in ipa_interrupt_suspend_disable()
170 /* Clear the suspend interrupt for all endpoints that signaled it */
171 void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt) in ipa_interrupt_suspend_clear_all() argument
173 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_suspend_clear_all()
180 /* SUSPEND interrupt status isn't cleared on IPA version 3.0 */ in ipa_interrupt_suspend_clear_all()
188 /* Simulate arrival of an IPA TX_SUSPEND interrupt */
189 void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt) in ipa_interrupt_simulate_suspend() argument
191 ipa_interrupt_process(interrupt, IPA_IRQ_TX_SUSPEND); in ipa_interrupt_simulate_suspend()
194 /* Add a handler for an IPA interrupt */
195 void ipa_interrupt_add(struct ipa_interrupt *interrupt, in ipa_interrupt_add() argument
198 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_add()
204 interrupt->handler[ipa_irq] = handler; in ipa_interrupt_add()
206 /* Update the IPA interrupt mask to enable it */ in ipa_interrupt_add()
207 interrupt->enabled |= BIT(ipa_irq); in ipa_interrupt_add()
210 iowrite32(interrupt->enabled, ipa->reg_virt + ipa_reg_offset(reg)); in ipa_interrupt_add()
213 /* Remove the handler for an IPA interrupt type */
215 ipa_interrupt_remove(struct ipa_interrupt *interrupt, enum ipa_irq_id ipa_irq) in ipa_interrupt_remove() argument
217 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_remove()
223 /* Update the IPA interrupt mask to disable it */ in ipa_interrupt_remove()
224 interrupt->enabled &= ~BIT(ipa_irq); in ipa_interrupt_remove()
227 iowrite32(interrupt->enabled, ipa->reg_virt + ipa_reg_offset(reg)); in ipa_interrupt_remove()
229 interrupt->handler[ipa_irq] = NULL; in ipa_interrupt_remove()
232 /* Configure the IPA interrupt framework */
236 struct ipa_interrupt *interrupt; in ipa_interrupt_config() local
249 interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL); in ipa_interrupt_config()
250 if (!interrupt) in ipa_interrupt_config()
252 interrupt->ipa = ipa; in ipa_interrupt_config()
253 interrupt->irq = irq; in ipa_interrupt_config()
260 "ipa", interrupt); in ipa_interrupt_config()
272 return interrupt; in ipa_interrupt_config()
275 free_irq(interrupt->irq, interrupt); in ipa_interrupt_config()
277 kfree(interrupt); in ipa_interrupt_config()
283 void ipa_interrupt_deconfig(struct ipa_interrupt *interrupt) in ipa_interrupt_deconfig() argument
285 struct device *dev = &interrupt->ipa->pdev->dev; in ipa_interrupt_deconfig()
288 ret = disable_irq_wake(interrupt->irq); in ipa_interrupt_deconfig()
291 free_irq(interrupt->irq, interrupt); in ipa_interrupt_deconfig()
292 kfree(interrupt); in ipa_interrupt_deconfig()