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