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()
58 /* For microcontroller interrupts, clear the interrupt right away, in ipa_interrupt_process()
64 if (irq_id < IPA_IRQ_COUNT && interrupt->handler[irq_id]) in ipa_interrupt_process()
65 interrupt->handler[irq_id](interrupt->ipa, irq_id); in ipa_interrupt_process()
67 /* Clearing the SUSPEND_TX interrupt also clears the register in ipa_interrupt_process()
68 * that tells us which suspended endpoint(s) caused the interrupt, in ipa_interrupt_process()
75 /* Process all IPA interrupt types that have been signaled */
76 static void ipa_interrupt_process_all(struct ipa_interrupt *interrupt) in ipa_interrupt_process_all() argument
78 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_process_all()
79 u32 enabled = interrupt->enabled; in ipa_interrupt_process_all()
83 * including conditions whose interrupt is not enabled. Handle in ipa_interrupt_process_all()
93 ipa_interrupt_process(interrupt, irq_id); in ipa_interrupt_process_all()
102 struct ipa_interrupt *interrupt = dev_id; in ipa_isr_thread() local
104 ipa_clock_get(interrupt->ipa); in ipa_isr_thread()
106 ipa_interrupt_process_all(interrupt); in ipa_isr_thread()
108 ipa_clock_put(interrupt->ipa); in ipa_isr_thread()
116 struct ipa_interrupt *interrupt = dev_id; in ipa_isr() local
117 struct ipa *ipa = interrupt->ipa; in ipa_isr()
121 if (mask & interrupt->enabled) in ipa_isr()
124 /* Nothing in the mask was supposed to cause an interrupt */ in ipa_isr()
127 dev_err(&ipa->pdev->dev, "%s: unexpected interrupt, mask 0x%08x\n", in ipa_isr()
134 static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt, in ipa_interrupt_suspend_control() argument
137 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_suspend_control()
152 ipa_interrupt_suspend_enable(struct ipa_interrupt *interrupt, u32 endpoint_id) in ipa_interrupt_suspend_enable() argument
154 ipa_interrupt_suspend_control(interrupt, endpoint_id, true); in ipa_interrupt_suspend_enable()
159 ipa_interrupt_suspend_disable(struct ipa_interrupt *interrupt, u32 endpoint_id) in ipa_interrupt_suspend_disable() argument
161 ipa_interrupt_suspend_control(interrupt, endpoint_id, false); in ipa_interrupt_suspend_disable()
164 /* Clear the suspend interrupt for all endpoints that signaled it */
165 void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt) in ipa_interrupt_suspend_clear_all() argument
167 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_suspend_clear_all()
174 /* Simulate arrival of an IPA TX_SUSPEND interrupt */
175 void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt) in ipa_interrupt_simulate_suspend() argument
177 ipa_interrupt_process(interrupt, IPA_IRQ_TX_SUSPEND); in ipa_interrupt_simulate_suspend()
180 /* Add a handler for an IPA interrupt */
181 void ipa_interrupt_add(struct ipa_interrupt *interrupt, in ipa_interrupt_add() argument
184 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_add()
187 interrupt->handler[ipa_irq] = handler; in ipa_interrupt_add()
189 /* Update the IPA interrupt mask to enable it */ in ipa_interrupt_add()
190 interrupt->enabled |= BIT(ipa_irq); in ipa_interrupt_add()
191 iowrite32(interrupt->enabled, ipa->reg_virt + IPA_REG_IRQ_EN_OFFSET); in ipa_interrupt_add()
194 /* Remove the handler for an IPA interrupt type */
196 ipa_interrupt_remove(struct ipa_interrupt *interrupt, enum ipa_irq_id ipa_irq) in ipa_interrupt_remove() argument
198 struct ipa *ipa = interrupt->ipa; in ipa_interrupt_remove()
201 /* Update the IPA interrupt mask to disable it */ in ipa_interrupt_remove()
202 interrupt->enabled &= ~BIT(ipa_irq); in ipa_interrupt_remove()
203 iowrite32(interrupt->enabled, ipa->reg_virt + IPA_REG_IRQ_EN_OFFSET); in ipa_interrupt_remove()
205 interrupt->handler[ipa_irq] = NULL; in ipa_interrupt_remove()
208 /* Set up the IPA interrupt framework */
212 struct ipa_interrupt *interrupt; in ipa_interrupt_setup() local
224 interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL); in ipa_interrupt_setup()
225 if (!interrupt) in ipa_interrupt_setup()
227 interrupt->ipa = ipa; in ipa_interrupt_setup()
228 interrupt->irq = irq; in ipa_interrupt_setup()
234 "ipa", interrupt); in ipa_interrupt_setup()
246 return interrupt; in ipa_interrupt_setup()
249 free_irq(interrupt->irq, interrupt); in ipa_interrupt_setup()
251 kfree(interrupt); in ipa_interrupt_setup()
256 /* Tear down the IPA interrupt framework */
257 void ipa_interrupt_teardown(struct ipa_interrupt *interrupt) in ipa_interrupt_teardown() argument
259 struct device *dev = &interrupt->ipa->pdev->dev; in ipa_interrupt_teardown()
262 ret = disable_irq_wake(interrupt->irq); in ipa_interrupt_teardown()
265 free_irq(interrupt->irq, interrupt); in ipa_interrupt_teardown()
266 kfree(interrupt); in ipa_interrupt_teardown()