1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. 4*4882a593Smuzhiyun * Copyright (C) 2018-2020 Linaro Ltd. 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun #ifndef _IPA_INTERRUPT_H_ 7*4882a593Smuzhiyun #define _IPA_INTERRUPT_H_ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <linux/types.h> 10*4882a593Smuzhiyun #include <linux/bits.h> 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun struct ipa; 13*4882a593Smuzhiyun struct ipa_interrupt; 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun /** 16*4882a593Smuzhiyun * enum ipa_irq_id - IPA interrupt type 17*4882a593Smuzhiyun * @IPA_IRQ_UC_0: Microcontroller event interrupt 18*4882a593Smuzhiyun * @IPA_IRQ_UC_1: Microcontroller response interrupt 19*4882a593Smuzhiyun * @IPA_IRQ_TX_SUSPEND: Data ready interrupt 20*4882a593Smuzhiyun * 21*4882a593Smuzhiyun * The data ready interrupt is signaled if data has arrived that is destined 22*4882a593Smuzhiyun * for an AP RX endpoint whose underlying GSI channel is suspended/stopped. 23*4882a593Smuzhiyun */ 24*4882a593Smuzhiyun enum ipa_irq_id { 25*4882a593Smuzhiyun IPA_IRQ_UC_0 = 2, 26*4882a593Smuzhiyun IPA_IRQ_UC_1 = 3, 27*4882a593Smuzhiyun IPA_IRQ_TX_SUSPEND = 14, 28*4882a593Smuzhiyun IPA_IRQ_COUNT, /* Number of interrupt types (not an index) */ 29*4882a593Smuzhiyun }; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun /** 32*4882a593Smuzhiyun * typedef ipa_irq_handler_t - IPA interrupt handler function type 33*4882a593Smuzhiyun * @ipa: IPA pointer 34*4882a593Smuzhiyun * @irq_id: interrupt type 35*4882a593Smuzhiyun * 36*4882a593Smuzhiyun * Callback function registered by ipa_interrupt_add() to handle a specific 37*4882a593Smuzhiyun * IPA interrupt type 38*4882a593Smuzhiyun */ 39*4882a593Smuzhiyun typedef void (*ipa_irq_handler_t)(struct ipa *ipa, enum ipa_irq_id irq_id); 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /** 42*4882a593Smuzhiyun * ipa_interrupt_add() - Register a handler for an IPA interrupt type 43*4882a593Smuzhiyun * @irq_id: IPA interrupt type 44*4882a593Smuzhiyun * @handler: Handler function for the interrupt 45*4882a593Smuzhiyun * 46*4882a593Smuzhiyun * Add a handler for an IPA interrupt and enable it. IPA interrupt 47*4882a593Smuzhiyun * handlers are run in threaded interrupt context, so are allowed to 48*4882a593Smuzhiyun * block. 49*4882a593Smuzhiyun */ 50*4882a593Smuzhiyun void ipa_interrupt_add(struct ipa_interrupt *interrupt, enum ipa_irq_id irq_id, 51*4882a593Smuzhiyun ipa_irq_handler_t handler); 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun /** 54*4882a593Smuzhiyun * ipa_interrupt_remove() - Remove the handler for an IPA interrupt type 55*4882a593Smuzhiyun * @interrupt: IPA interrupt structure 56*4882a593Smuzhiyun * @irq_id: IPA interrupt type 57*4882a593Smuzhiyun * 58*4882a593Smuzhiyun * Remove an IPA interrupt handler and disable it. 59*4882a593Smuzhiyun */ 60*4882a593Smuzhiyun void ipa_interrupt_remove(struct ipa_interrupt *interrupt, 61*4882a593Smuzhiyun enum ipa_irq_id irq_id); 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun /** 64*4882a593Smuzhiyun * ipa_interrupt_suspend_enable - Enable TX_SUSPEND for an endpoint 65*4882a593Smuzhiyun * @interrupt: IPA interrupt structure 66*4882a593Smuzhiyun * @endpoint_id: Endpoint whose interrupt should be enabled 67*4882a593Smuzhiyun * 68*4882a593Smuzhiyun * Note: The "TX" in the name is from the perspective of the IPA hardware. 69*4882a593Smuzhiyun * A TX_SUSPEND interrupt arrives on an AP RX enpoint when packet data can't 70*4882a593Smuzhiyun * be delivered to the endpoint because it is suspended (or its underlying 71*4882a593Smuzhiyun * channel is stopped). 72*4882a593Smuzhiyun */ 73*4882a593Smuzhiyun void ipa_interrupt_suspend_enable(struct ipa_interrupt *interrupt, 74*4882a593Smuzhiyun u32 endpoint_id); 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun /** 77*4882a593Smuzhiyun * ipa_interrupt_suspend_disable - Disable TX_SUSPEND for an endpoint 78*4882a593Smuzhiyun * @interrupt: IPA interrupt structure 79*4882a593Smuzhiyun * @endpoint_id: Endpoint whose interrupt should be disabled 80*4882a593Smuzhiyun */ 81*4882a593Smuzhiyun void ipa_interrupt_suspend_disable(struct ipa_interrupt *interrupt, 82*4882a593Smuzhiyun u32 endpoint_id); 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun /** 85*4882a593Smuzhiyun * ipa_interrupt_suspend_clear_all - clear all suspend interrupts 86*4882a593Smuzhiyun * @interrupt: IPA interrupt structure 87*4882a593Smuzhiyun * 88*4882a593Smuzhiyun * Clear the TX_SUSPEND interrupt for all endpoints that signaled it. 89*4882a593Smuzhiyun */ 90*4882a593Smuzhiyun void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt); 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun /** 93*4882a593Smuzhiyun * ipa_interrupt_simulate_suspend() - Simulate TX_SUSPEND IPA interrupt 94*4882a593Smuzhiyun * @interrupt: IPA interrupt structure 95*4882a593Smuzhiyun * 96*4882a593Smuzhiyun * This calls the TX_SUSPEND interrupt handler, as if such an interrupt 97*4882a593Smuzhiyun * had been signaled. This is needed to work around a hardware quirk 98*4882a593Smuzhiyun * that occurs if aggregation is active on an endpoint when its underlying 99*4882a593Smuzhiyun * channel is suspended. 100*4882a593Smuzhiyun */ 101*4882a593Smuzhiyun void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt); 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun /** 104*4882a593Smuzhiyun * ipa_interrupt_setup() - Set up the IPA interrupt framework 105*4882a593Smuzhiyun * @ipa: IPA pointer 106*4882a593Smuzhiyun * 107*4882a593Smuzhiyun * Return: Pointer to IPA SMP2P info, or a pointer-coded error 108*4882a593Smuzhiyun */ 109*4882a593Smuzhiyun struct ipa_interrupt *ipa_interrupt_setup(struct ipa *ipa); 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun /** 112*4882a593Smuzhiyun * ipa_interrupt_teardown() - Tear down the IPA interrupt framework 113*4882a593Smuzhiyun * @interrupt: IPA interrupt structure 114*4882a593Smuzhiyun */ 115*4882a593Smuzhiyun void ipa_interrupt_teardown(struct ipa_interrupt *interrupt); 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun #endif /* _IPA_INTERRUPT_H_ */ 118