1 // SPDX-License-Identifier: GPL-2.0 2 3 /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. 4 * Copyright (C) 2018-2022 Linaro Ltd. 5 */ 6 7 /* DOC: IPA Interrupts 8 * 9 * The IPA has an interrupt line distinct from the interrupt used by the GSI 10 * code. Whereas GSI interrupts are generally related to channel events (like 11 * transfer completions), IPA interrupts are related to other events related 12 * to the IPA. Some of the IPA interrupts come from a microcontroller 13 * embedded in the IPA. Each IPA interrupt type can be both masked and 14 * acknowledged independent of the others. 15 * 16 * Two of the IPA interrupts are initiated by the microcontroller. A third 17 * can be generated to signal the need for a wakeup/resume when an IPA 18 * endpoint has been suspended. There are other IPA events, but at this 19 * time only these three are supported. 20 */ 21 22 #include <linux/types.h> 23 #include <linux/interrupt.h> 24 #include <linux/pm_runtime.h> 25 #include <linux/pm_wakeirq.h> 26 27 #include "ipa.h" 28 #include "ipa_reg.h" 29 #include "ipa_endpoint.h" 30 #include "ipa_power.h" 31 #include "ipa_uc.h" 32 #include "ipa_interrupt.h" 33 34 /** 35 * struct ipa_interrupt - IPA interrupt information 36 * @ipa: IPA pointer 37 * @irq: Linux IRQ number used for IPA interrupts 38 * @enabled: Mask indicating which interrupts are enabled 39 */ 40 struct ipa_interrupt { 41 struct ipa *ipa; 42 u32 irq; 43 u32 enabled; 44 }; 45 46 /* Process a particular interrupt type that has been received */ 47 static void ipa_interrupt_process(struct ipa_interrupt *interrupt, u32 irq_id) 48 { 49 struct ipa *ipa = interrupt->ipa; 50 const struct ipa_reg *reg; 51 u32 mask = BIT(irq_id); 52 u32 offset; 53 54 reg = ipa_reg(ipa, IPA_IRQ_CLR); 55 offset = ipa_reg_offset(reg); 56 57 switch (irq_id) { 58 case IPA_IRQ_UC_0: 59 case IPA_IRQ_UC_1: 60 /* For microcontroller interrupts, clear the interrupt right 61 * away, "to avoid clearing unhandled interrupts." 62 */ 63 iowrite32(mask, ipa->reg_virt + offset); 64 ipa_uc_interrupt_handler(ipa, irq_id); 65 break; 66 67 case IPA_IRQ_TX_SUSPEND: 68 /* Clearing the SUSPEND_TX interrupt also clears the 69 * register that tells us which suspended endpoint(s) 70 * caused the interrupt, so defer clearing until after 71 * the handler has been called. 72 */ 73 ipa_power_suspend_handler(ipa, irq_id); 74 fallthrough; 75 76 default: /* Silently ignore (and clear) any other condition */ 77 iowrite32(mask, ipa->reg_virt + offset); 78 break; 79 } 80 } 81 82 /* IPA IRQ handler is threaded */ 83 static irqreturn_t ipa_isr_thread(int irq, void *dev_id) 84 { 85 struct ipa_interrupt *interrupt = dev_id; 86 struct ipa *ipa = interrupt->ipa; 87 u32 enabled = interrupt->enabled; 88 const struct ipa_reg *reg; 89 struct device *dev; 90 u32 pending; 91 u32 offset; 92 u32 mask; 93 int ret; 94 95 dev = &ipa->pdev->dev; 96 ret = pm_runtime_get_sync(dev); 97 if (WARN_ON(ret < 0)) 98 goto out_power_put; 99 100 /* The status register indicates which conditions are present, 101 * including conditions whose interrupt is not enabled. Handle 102 * only the enabled ones. 103 */ 104 reg = ipa_reg(ipa, IPA_IRQ_STTS); 105 offset = ipa_reg_offset(reg); 106 pending = ioread32(ipa->reg_virt + offset); 107 while ((mask = pending & enabled)) { 108 do { 109 u32 irq_id = __ffs(mask); 110 111 mask ^= BIT(irq_id); 112 113 ipa_interrupt_process(interrupt, irq_id); 114 } while (mask); 115 pending = ioread32(ipa->reg_virt + offset); 116 } 117 118 /* If any disabled interrupts are pending, clear them */ 119 if (pending) { 120 dev_dbg(dev, "clearing disabled IPA interrupts 0x%08x\n", 121 pending); 122 reg = ipa_reg(ipa, IPA_IRQ_CLR); 123 offset = ipa_reg_offset(reg); 124 iowrite32(pending, ipa->reg_virt + offset); 125 } 126 out_power_put: 127 pm_runtime_mark_last_busy(dev); 128 (void)pm_runtime_put_autosuspend(dev); 129 130 return IRQ_HANDLED; 131 } 132 133 static void ipa_interrupt_enabled_update(struct ipa *ipa) 134 { 135 const struct ipa_reg *reg = ipa_reg(ipa, IPA_IRQ_EN); 136 137 iowrite32(ipa->interrupt->enabled, ipa->reg_virt + ipa_reg_offset(reg)); 138 } 139 140 /* Enable an IPA interrupt type */ 141 void ipa_interrupt_enable(struct ipa *ipa, enum ipa_irq_id ipa_irq) 142 { 143 /* Update the IPA interrupt mask to enable it */ 144 ipa->interrupt->enabled |= BIT(ipa_irq); 145 ipa_interrupt_enabled_update(ipa); 146 } 147 148 /* Disable an IPA interrupt type */ 149 void ipa_interrupt_disable(struct ipa *ipa, enum ipa_irq_id ipa_irq) 150 { 151 /* Update the IPA interrupt mask to disable it */ 152 ipa->interrupt->enabled &= ~BIT(ipa_irq); 153 ipa_interrupt_enabled_update(ipa); 154 } 155 156 void ipa_interrupt_irq_disable(struct ipa *ipa) 157 { 158 disable_irq(ipa->interrupt->irq); 159 } 160 161 void ipa_interrupt_irq_enable(struct ipa *ipa) 162 { 163 enable_irq(ipa->interrupt->irq); 164 } 165 166 /* Common function used to enable/disable TX_SUSPEND for an endpoint */ 167 static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt, 168 u32 endpoint_id, bool enable) 169 { 170 struct ipa *ipa = interrupt->ipa; 171 u32 mask = BIT(endpoint_id % 32); 172 u32 unit = endpoint_id / 32; 173 const struct ipa_reg *reg; 174 u32 offset; 175 u32 val; 176 177 WARN_ON(!test_bit(endpoint_id, ipa->available)); 178 179 /* IPA version 3.0 does not support TX_SUSPEND interrupt control */ 180 if (ipa->version == IPA_VERSION_3_0) 181 return; 182 183 reg = ipa_reg(ipa, IRQ_SUSPEND_EN); 184 offset = ipa_reg_n_offset(reg, unit); 185 val = ioread32(ipa->reg_virt + offset); 186 187 if (enable) 188 val |= mask; 189 else 190 val &= ~mask; 191 192 iowrite32(val, ipa->reg_virt + offset); 193 } 194 195 /* Enable TX_SUSPEND for an endpoint */ 196 void 197 ipa_interrupt_suspend_enable(struct ipa_interrupt *interrupt, u32 endpoint_id) 198 { 199 ipa_interrupt_suspend_control(interrupt, endpoint_id, true); 200 } 201 202 /* Disable TX_SUSPEND for an endpoint */ 203 void 204 ipa_interrupt_suspend_disable(struct ipa_interrupt *interrupt, u32 endpoint_id) 205 { 206 ipa_interrupt_suspend_control(interrupt, endpoint_id, false); 207 } 208 209 /* Clear the suspend interrupt for all endpoints that signaled it */ 210 void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt) 211 { 212 struct ipa *ipa = interrupt->ipa; 213 u32 unit_count; 214 u32 unit; 215 216 unit_count = roundup(ipa->endpoint_count, 32); 217 for (unit = 0; unit < unit_count; unit++) { 218 const struct ipa_reg *reg; 219 u32 val; 220 221 reg = ipa_reg(ipa, IRQ_SUSPEND_INFO); 222 val = ioread32(ipa->reg_virt + ipa_reg_n_offset(reg, unit)); 223 224 /* SUSPEND interrupt status isn't cleared on IPA version 3.0 */ 225 if (ipa->version == IPA_VERSION_3_0) 226 continue; 227 228 reg = ipa_reg(ipa, IRQ_SUSPEND_CLR); 229 iowrite32(val, ipa->reg_virt + ipa_reg_n_offset(reg, unit)); 230 } 231 } 232 233 /* Simulate arrival of an IPA TX_SUSPEND interrupt */ 234 void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt) 235 { 236 ipa_interrupt_process(interrupt, IPA_IRQ_TX_SUSPEND); 237 } 238 239 /* Configure the IPA interrupt framework */ 240 struct ipa_interrupt *ipa_interrupt_config(struct ipa *ipa) 241 { 242 struct device *dev = &ipa->pdev->dev; 243 struct ipa_interrupt *interrupt; 244 const struct ipa_reg *reg; 245 unsigned int irq; 246 int ret; 247 248 ret = platform_get_irq_byname(ipa->pdev, "ipa"); 249 if (ret <= 0) { 250 dev_err(dev, "DT error %d getting \"ipa\" IRQ property\n", 251 ret); 252 return ERR_PTR(ret ? : -EINVAL); 253 } 254 irq = ret; 255 256 interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL); 257 if (!interrupt) 258 return ERR_PTR(-ENOMEM); 259 interrupt->ipa = ipa; 260 interrupt->irq = irq; 261 262 /* Start with all IPA interrupts disabled */ 263 reg = ipa_reg(ipa, IPA_IRQ_EN); 264 iowrite32(0, ipa->reg_virt + ipa_reg_offset(reg)); 265 266 ret = request_threaded_irq(irq, NULL, ipa_isr_thread, IRQF_ONESHOT, 267 "ipa", interrupt); 268 if (ret) { 269 dev_err(dev, "error %d requesting \"ipa\" IRQ\n", ret); 270 goto err_kfree; 271 } 272 273 ret = dev_pm_set_wake_irq(dev, irq); 274 if (ret) { 275 dev_err(dev, "error %d registering \"ipa\" IRQ as wakeirq\n", ret); 276 goto err_free_irq; 277 } 278 279 return interrupt; 280 281 err_free_irq: 282 free_irq(interrupt->irq, interrupt); 283 err_kfree: 284 kfree(interrupt); 285 286 return ERR_PTR(ret); 287 } 288 289 /* Inverse of ipa_interrupt_config() */ 290 void ipa_interrupt_deconfig(struct ipa_interrupt *interrupt) 291 { 292 struct device *dev = &interrupt->ipa->pdev->dev; 293 294 dev_pm_clear_wake_irq(dev); 295 free_irq(interrupt->irq, interrupt); 296 kfree(interrupt); 297 } 298