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()
59 /* For microcontroller interrupts, clear the interrupt right away, in ipa_interrupt_process()
66 if (irq_id < IPA_IRQ_COUNT && interrupt->handler[irq_id]) in ipa_interrupt_process()
67 interrupt->handler[irq_id](interrupt->ipa, irq_id); in ipa_interrupt_process()
69 /* Clearing the SUSPEND_TX interrupt also clears the register in ipa_interrupt_process()
70 * that tells us which suspended endpoint(s) caused the interrupt, in ipa_interrupt_process()
80 struct ipa_interrupt *interrupt = dev_id; in ipa_isr_thread() local
81 struct ipa *ipa = interrupt->ipa; in ipa_isr_thread()
82 u32 enabled = interrupt->enabled; in ipa_isr_thread()
95 * including conditions whose interrupt is not enabled. Handle in ipa_isr_thread()
106 ipa_interrupt_process(interrupt, irq_id); in ipa_isr_thread()
126 static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt, in ipa_interrupt_suspend_control() argument
129 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_suspend_control()
136 /* IPA version 3.0 does not support TX_SUSPEND interrupt control */ in ipa_interrupt_suspend_control()
151 ipa_interrupt_suspend_enable(struct ipa_interrupt *interrupt, u32 endpoint_id) in ipa_interrupt_suspend_enable() argument
153 ipa_interrupt_suspend_control(interrupt, endpoint_id, true); in ipa_interrupt_suspend_enable()
158 ipa_interrupt_suspend_disable(struct ipa_interrupt *interrupt, u32 endpoint_id) in ipa_interrupt_suspend_disable() argument
160 ipa_interrupt_suspend_control(interrupt, endpoint_id, false); in ipa_interrupt_suspend_disable()
163 /* Clear the suspend interrupt for all endpoints that signaled it */
164 void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt) in ipa_interrupt_suspend_clear_all() argument
166 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_suspend_clear_all()
173 /* SUSPEND interrupt status isn't cleared on IPA version 3.0 */ in ipa_interrupt_suspend_clear_all()
181 /* Simulate arrival of an IPA TX_SUSPEND interrupt */
182 void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt) in ipa_interrupt_simulate_suspend() argument
184 ipa_interrupt_process(interrupt, IPA_IRQ_TX_SUSPEND); in ipa_interrupt_simulate_suspend()
187 /* Add a handler for an IPA interrupt */
188 void ipa_interrupt_add(struct ipa_interrupt *interrupt, in ipa_interrupt_add() argument
191 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_add()
196 interrupt->handler[ipa_irq] = handler; in ipa_interrupt_add()
198 /* Update the IPA interrupt mask to enable it */ in ipa_interrupt_add()
199 interrupt->enabled |= BIT(ipa_irq); in ipa_interrupt_add()
201 iowrite32(interrupt->enabled, ipa->reg_virt + offset); in ipa_interrupt_add()
204 /* Remove the handler for an IPA interrupt type */
206 ipa_interrupt_remove(struct ipa_interrupt *interrupt, enum ipa_irq_id ipa_irq) in ipa_interrupt_remove() argument
208 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_remove()
213 /* Update the IPA interrupt mask to disable it */ in ipa_interrupt_remove()
214 interrupt->enabled &= ~BIT(ipa_irq); in ipa_interrupt_remove()
216 iowrite32(interrupt->enabled, ipa->reg_virt + offset); in ipa_interrupt_remove()
218 interrupt->handler[ipa_irq] = NULL; in ipa_interrupt_remove()
221 /* Configure the IPA interrupt framework */
225 struct ipa_interrupt *interrupt; in ipa_interrupt_config() local
238 interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL); in ipa_interrupt_config()
239 if (!interrupt) in ipa_interrupt_config()
241 interrupt->ipa = ipa; in ipa_interrupt_config()
242 interrupt->irq = irq; in ipa_interrupt_config()
249 "ipa", interrupt); in ipa_interrupt_config()
261 return interrupt; in ipa_interrupt_config()
264 free_irq(interrupt->irq, interrupt); in ipa_interrupt_config()
266 kfree(interrupt); in ipa_interrupt_config()
272 void ipa_interrupt_deconfig(struct ipa_interrupt *interrupt) in ipa_interrupt_deconfig() argument
274 struct device *dev = &interrupt->ipa->pdev->dev; in ipa_interrupt_deconfig()
277 ret = disable_irq_wake(interrupt->irq); in ipa_interrupt_deconfig()
280 free_irq(interrupt->irq, interrupt); in ipa_interrupt_deconfig()
281 kfree(interrupt); in ipa_interrupt_deconfig()