0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <linux/types.h>
0023 #include <linux/interrupt.h>
0024 #include <linux/pm_runtime.h>
0025
0026 #include "ipa.h"
0027 #include "ipa_reg.h"
0028 #include "ipa_endpoint.h"
0029 #include "ipa_interrupt.h"
0030
0031
0032
0033
0034
0035
0036
0037
0038 struct ipa_interrupt {
0039 struct ipa *ipa;
0040 u32 irq;
0041 u32 enabled;
0042 ipa_irq_handler_t handler[IPA_IRQ_COUNT];
0043 };
0044
0045
0046 static bool ipa_interrupt_uc(struct ipa_interrupt *interrupt, u32 irq_id)
0047 {
0048 return irq_id == IPA_IRQ_UC_0 || irq_id == IPA_IRQ_UC_1;
0049 }
0050
0051
0052 static void ipa_interrupt_process(struct ipa_interrupt *interrupt, u32 irq_id)
0053 {
0054 bool uc_irq = ipa_interrupt_uc(interrupt, irq_id);
0055 struct ipa *ipa = interrupt->ipa;
0056 u32 mask = BIT(irq_id);
0057 u32 offset;
0058
0059
0060
0061
0062 offset = ipa_reg_irq_clr_offset(ipa->version);
0063 if (uc_irq)
0064 iowrite32(mask, ipa->reg_virt + offset);
0065
0066 if (irq_id < IPA_IRQ_COUNT && interrupt->handler[irq_id])
0067 interrupt->handler[irq_id](interrupt->ipa, irq_id);
0068
0069
0070
0071
0072
0073 if (!uc_irq)
0074 iowrite32(mask, ipa->reg_virt + offset);
0075 }
0076
0077
0078 static irqreturn_t ipa_isr_thread(int irq, void *dev_id)
0079 {
0080 struct ipa_interrupt *interrupt = dev_id;
0081 struct ipa *ipa = interrupt->ipa;
0082 u32 enabled = interrupt->enabled;
0083 struct device *dev;
0084 u32 pending;
0085 u32 offset;
0086 u32 mask;
0087 int ret;
0088
0089 dev = &ipa->pdev->dev;
0090 ret = pm_runtime_get_sync(dev);
0091 if (WARN_ON(ret < 0))
0092 goto out_power_put;
0093
0094
0095
0096
0097
0098 offset = ipa_reg_irq_stts_offset(ipa->version);
0099 pending = ioread32(ipa->reg_virt + offset);
0100 while ((mask = pending & enabled)) {
0101 do {
0102 u32 irq_id = __ffs(mask);
0103
0104 mask ^= BIT(irq_id);
0105
0106 ipa_interrupt_process(interrupt, irq_id);
0107 } while (mask);
0108 pending = ioread32(ipa->reg_virt + offset);
0109 }
0110
0111
0112 if (pending) {
0113 dev_dbg(dev, "clearing disabled IPA interrupts 0x%08x\n",
0114 pending);
0115 offset = ipa_reg_irq_clr_offset(ipa->version);
0116 iowrite32(pending, ipa->reg_virt + offset);
0117 }
0118 out_power_put:
0119 pm_runtime_mark_last_busy(dev);
0120 (void)pm_runtime_put_autosuspend(dev);
0121
0122 return IRQ_HANDLED;
0123 }
0124
0125
0126 static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt,
0127 u32 endpoint_id, bool enable)
0128 {
0129 struct ipa *ipa = interrupt->ipa;
0130 u32 mask = BIT(endpoint_id);
0131 u32 offset;
0132 u32 val;
0133
0134 WARN_ON(!(mask & ipa->available));
0135
0136
0137 if (ipa->version == IPA_VERSION_3_0)
0138 return;
0139
0140 offset = ipa_reg_irq_suspend_en_offset(ipa->version);
0141 val = ioread32(ipa->reg_virt + offset);
0142 if (enable)
0143 val |= mask;
0144 else
0145 val &= ~mask;
0146 iowrite32(val, ipa->reg_virt + offset);
0147 }
0148
0149
0150 void
0151 ipa_interrupt_suspend_enable(struct ipa_interrupt *interrupt, u32 endpoint_id)
0152 {
0153 ipa_interrupt_suspend_control(interrupt, endpoint_id, true);
0154 }
0155
0156
0157 void
0158 ipa_interrupt_suspend_disable(struct ipa_interrupt *interrupt, u32 endpoint_id)
0159 {
0160 ipa_interrupt_suspend_control(interrupt, endpoint_id, false);
0161 }
0162
0163
0164 void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt)
0165 {
0166 struct ipa *ipa = interrupt->ipa;
0167 u32 offset;
0168 u32 val;
0169
0170 offset = ipa_reg_irq_suspend_info_offset(ipa->version);
0171 val = ioread32(ipa->reg_virt + offset);
0172
0173
0174 if (ipa->version == IPA_VERSION_3_0)
0175 return;
0176
0177 offset = ipa_reg_irq_suspend_clr_offset(ipa->version);
0178 iowrite32(val, ipa->reg_virt + offset);
0179 }
0180
0181
0182 void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt)
0183 {
0184 ipa_interrupt_process(interrupt, IPA_IRQ_TX_SUSPEND);
0185 }
0186
0187
0188 void ipa_interrupt_add(struct ipa_interrupt *interrupt,
0189 enum ipa_irq_id ipa_irq, ipa_irq_handler_t handler)
0190 {
0191 struct ipa *ipa = interrupt->ipa;
0192 u32 offset;
0193
0194 if (WARN_ON(ipa_irq >= IPA_IRQ_COUNT))
0195 return;
0196
0197 interrupt->handler[ipa_irq] = handler;
0198
0199
0200 interrupt->enabled |= BIT(ipa_irq);
0201 offset = ipa_reg_irq_en_offset(ipa->version);
0202 iowrite32(interrupt->enabled, ipa->reg_virt + offset);
0203 }
0204
0205
0206 void
0207 ipa_interrupt_remove(struct ipa_interrupt *interrupt, enum ipa_irq_id ipa_irq)
0208 {
0209 struct ipa *ipa = interrupt->ipa;
0210 u32 offset;
0211
0212 if (WARN_ON(ipa_irq >= IPA_IRQ_COUNT))
0213 return;
0214
0215
0216 interrupt->enabled &= ~BIT(ipa_irq);
0217 offset = ipa_reg_irq_en_offset(ipa->version);
0218 iowrite32(interrupt->enabled, ipa->reg_virt + offset);
0219
0220 interrupt->handler[ipa_irq] = NULL;
0221 }
0222
0223
0224 struct ipa_interrupt *ipa_interrupt_config(struct ipa *ipa)
0225 {
0226 struct device *dev = &ipa->pdev->dev;
0227 struct ipa_interrupt *interrupt;
0228 unsigned int irq;
0229 u32 offset;
0230 int ret;
0231
0232 ret = platform_get_irq_byname(ipa->pdev, "ipa");
0233 if (ret <= 0) {
0234 dev_err(dev, "DT error %d getting \"ipa\" IRQ property\n",
0235 ret);
0236 return ERR_PTR(ret ? : -EINVAL);
0237 }
0238 irq = ret;
0239
0240 interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL);
0241 if (!interrupt)
0242 return ERR_PTR(-ENOMEM);
0243 interrupt->ipa = ipa;
0244 interrupt->irq = irq;
0245
0246
0247 offset = ipa_reg_irq_en_offset(ipa->version);
0248 iowrite32(0, ipa->reg_virt + offset);
0249
0250 ret = request_threaded_irq(irq, NULL, ipa_isr_thread, IRQF_ONESHOT,
0251 "ipa", interrupt);
0252 if (ret) {
0253 dev_err(dev, "error %d requesting \"ipa\" IRQ\n", ret);
0254 goto err_kfree;
0255 }
0256
0257 ret = enable_irq_wake(irq);
0258 if (ret) {
0259 dev_err(dev, "error %d enabling wakeup for \"ipa\" IRQ\n", ret);
0260 goto err_free_irq;
0261 }
0262
0263 return interrupt;
0264
0265 err_free_irq:
0266 free_irq(interrupt->irq, interrupt);
0267 err_kfree:
0268 kfree(interrupt);
0269
0270 return ERR_PTR(ret);
0271 }
0272
0273
0274 void ipa_interrupt_deconfig(struct ipa_interrupt *interrupt)
0275 {
0276 struct device *dev = &interrupt->ipa->pdev->dev;
0277 int ret;
0278
0279 ret = disable_irq_wake(interrupt->irq);
0280 if (ret)
0281 dev_err(dev, "error %d disabling \"ipa\" IRQ wakeup\n", ret);
0282 free_irq(interrupt->irq, interrupt);
0283 kfree(interrupt);
0284 }