1 // SPDX-License-Identifier: GPL-2.0 2 3 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. 4 * Copyright (C) 2019-2020 Linaro Ltd. 5 */ 6 7 #include <linux/types.h> 8 #include <linux/device.h> 9 #include <linux/interrupt.h> 10 #include <linux/notifier.h> 11 #include <linux/soc/qcom/smem.h> 12 #include <linux/soc/qcom/smem_state.h> 13 14 #include "ipa_smp2p.h" 15 #include "ipa.h" 16 #include "ipa_uc.h" 17 #include "ipa_clock.h" 18 19 /** 20 * DOC: IPA SMP2P communication with the modem 21 * 22 * SMP2P is a primitive communication mechanism available between the AP and 23 * the modem. The IPA driver uses this for two purposes: to enable the modem 24 * to state that the GSI hardware is ready to use; and to communicate the 25 * state of the IPA clock in the event of a crash. 26 * 27 * GSI needs to have early initialization completed before it can be used. 28 * This initialization is done either by Trust Zone or by the modem. In the 29 * latter case, the modem uses an SMP2P interrupt to tell the AP IPA driver 30 * when the GSI is ready to use. 31 * 32 * The modem is also able to inquire about the current state of the IPA 33 * clock by trigging another SMP2P interrupt to the AP. We communicate 34 * whether the clock is enabled using two SMP2P state bits--one to 35 * indicate the clock state (on or off), and a second to indicate the 36 * clock state bit is valid. The modem will poll the valid bit until it 37 * is set, and at that time records whether the AP has the IPA clock enabled. 38 * 39 * Finally, if the AP kernel panics, we update the SMP2P state bits even if 40 * we never receive an interrupt from the modem requesting this. 41 */ 42 43 /** 44 * struct ipa_smp2p - IPA SMP2P information 45 * @ipa: IPA pointer 46 * @valid_state: SMEM state indicating enabled state is valid 47 * @enabled_state: SMEM state to indicate clock is enabled 48 * @valid_bit: Valid bit in 32-bit SMEM state mask 49 * @enabled_bit: Enabled bit in 32-bit SMEM state mask 50 * @enabled_bit: Enabled bit in 32-bit SMEM state mask 51 * @clock_query_irq: IPA interrupt triggered by modem for clock query 52 * @setup_ready_irq: IPA interrupt triggered by modem to signal GSI ready 53 * @clock_on: Whether IPA clock is on 54 * @notified: Whether modem has been notified of clock state 55 * @disabled: Whether setup ready interrupt handling is disabled 56 * @mutex: Mutex protecting ready-interrupt/shutdown interlock 57 * @panic_notifier: Panic notifier structure 58 */ 59 struct ipa_smp2p { 60 struct ipa *ipa; 61 struct qcom_smem_state *valid_state; 62 struct qcom_smem_state *enabled_state; 63 u32 valid_bit; 64 u32 enabled_bit; 65 u32 clock_query_irq; 66 u32 setup_ready_irq; 67 bool clock_on; 68 bool notified; 69 bool disabled; 70 struct mutex mutex; 71 struct notifier_block panic_notifier; 72 }; 73 74 /** 75 * ipa_smp2p_notify() - use SMP2P to tell modem about IPA clock state 76 * @smp2p: SMP2P information 77 * 78 * This is called either when the modem has requested it (by triggering 79 * the modem clock query IPA interrupt) or whenever the AP is shutting down 80 * (via a panic notifier). It sets the two SMP2P state bits--one saying 81 * whether the IPA clock is running, and the other indicating the first bit 82 * is valid. 83 */ 84 static void ipa_smp2p_notify(struct ipa_smp2p *smp2p) 85 { 86 u32 value; 87 u32 mask; 88 89 if (smp2p->notified) 90 return; 91 92 smp2p->clock_on = ipa_clock_get_additional(smp2p->ipa); 93 94 /* Signal whether the clock is enabled */ 95 mask = BIT(smp2p->enabled_bit); 96 value = smp2p->clock_on ? mask : 0; 97 qcom_smem_state_update_bits(smp2p->enabled_state, mask, value); 98 99 /* Now indicate that the enabled flag is valid */ 100 mask = BIT(smp2p->valid_bit); 101 value = mask; 102 qcom_smem_state_update_bits(smp2p->valid_state, mask, value); 103 104 smp2p->notified = true; 105 } 106 107 /* Threaded IRQ handler for modem "ipa-clock-query" SMP2P interrupt */ 108 static irqreturn_t ipa_smp2p_modem_clk_query_isr(int irq, void *dev_id) 109 { 110 struct ipa_smp2p *smp2p = dev_id; 111 112 ipa_smp2p_notify(smp2p); 113 114 return IRQ_HANDLED; 115 } 116 117 static int ipa_smp2p_panic_notifier(struct notifier_block *nb, 118 unsigned long action, void *data) 119 { 120 struct ipa_smp2p *smp2p; 121 122 smp2p = container_of(nb, struct ipa_smp2p, panic_notifier); 123 124 ipa_smp2p_notify(smp2p); 125 126 if (smp2p->clock_on) 127 ipa_uc_panic_notifier(smp2p->ipa); 128 129 return NOTIFY_DONE; 130 } 131 132 static int ipa_smp2p_panic_notifier_register(struct ipa_smp2p *smp2p) 133 { 134 /* IPA panic handler needs to run before modem shuts down */ 135 smp2p->panic_notifier.notifier_call = ipa_smp2p_panic_notifier; 136 smp2p->panic_notifier.priority = INT_MAX; /* Do it early */ 137 138 return atomic_notifier_chain_register(&panic_notifier_list, 139 &smp2p->panic_notifier); 140 } 141 142 static void ipa_smp2p_panic_notifier_unregister(struct ipa_smp2p *smp2p) 143 { 144 atomic_notifier_chain_unregister(&panic_notifier_list, 145 &smp2p->panic_notifier); 146 } 147 148 /* Threaded IRQ handler for modem "ipa-setup-ready" SMP2P interrupt */ 149 static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id) 150 { 151 struct ipa_smp2p *smp2p = dev_id; 152 153 mutex_lock(&smp2p->mutex); 154 155 if (!smp2p->disabled) { 156 int ret; 157 158 ret = ipa_setup(smp2p->ipa); 159 if (ret) 160 dev_err(&smp2p->ipa->pdev->dev, 161 "error %d from ipa_setup()\n", ret); 162 smp2p->disabled = true; 163 } 164 165 mutex_unlock(&smp2p->mutex); 166 167 return IRQ_HANDLED; 168 } 169 170 /* Initialize SMP2P interrupts */ 171 static int ipa_smp2p_irq_init(struct ipa_smp2p *smp2p, const char *name, 172 irq_handler_t handler) 173 { 174 struct device *dev = &smp2p->ipa->pdev->dev; 175 unsigned int irq; 176 int ret; 177 178 ret = platform_get_irq_byname(smp2p->ipa->pdev, name); 179 if (ret <= 0) 180 return ret ? : -EINVAL; 181 irq = ret; 182 183 ret = request_threaded_irq(irq, NULL, handler, 0, name, smp2p); 184 if (ret) { 185 dev_err(dev, "error %d requesting \"%s\" IRQ\n", ret, name); 186 return ret; 187 } 188 189 return irq; 190 } 191 192 static void ipa_smp2p_irq_exit(struct ipa_smp2p *smp2p, u32 irq) 193 { 194 free_irq(irq, smp2p); 195 } 196 197 /* Drop the clock reference if it was taken in ipa_smp2p_notify() */ 198 static void ipa_smp2p_clock_release(struct ipa *ipa) 199 { 200 if (!ipa->smp2p->clock_on) 201 return; 202 203 ipa_clock_put(ipa); 204 ipa->smp2p->clock_on = false; 205 } 206 207 /* Initialize the IPA SMP2P subsystem */ 208 int ipa_smp2p_init(struct ipa *ipa, bool modem_init) 209 { 210 struct qcom_smem_state *enabled_state; 211 struct device *dev = &ipa->pdev->dev; 212 struct qcom_smem_state *valid_state; 213 struct ipa_smp2p *smp2p; 214 u32 enabled_bit; 215 u32 valid_bit; 216 int ret; 217 218 valid_state = qcom_smem_state_get(dev, "ipa-clock-enabled-valid", 219 &valid_bit); 220 if (IS_ERR(valid_state)) 221 return PTR_ERR(valid_state); 222 if (valid_bit >= 32) /* BITS_PER_U32 */ 223 return -EINVAL; 224 225 enabled_state = qcom_smem_state_get(dev, "ipa-clock-enabled", 226 &enabled_bit); 227 if (IS_ERR(enabled_state)) 228 return PTR_ERR(enabled_state); 229 if (enabled_bit >= 32) /* BITS_PER_U32 */ 230 return -EINVAL; 231 232 smp2p = kzalloc(sizeof(*smp2p), GFP_KERNEL); 233 if (!smp2p) 234 return -ENOMEM; 235 236 smp2p->ipa = ipa; 237 238 /* These fields are needed by the clock query interrupt 239 * handler, so initialize them now. 240 */ 241 mutex_init(&smp2p->mutex); 242 smp2p->valid_state = valid_state; 243 smp2p->valid_bit = valid_bit; 244 smp2p->enabled_state = enabled_state; 245 smp2p->enabled_bit = enabled_bit; 246 247 /* We have enough information saved to handle notifications */ 248 ipa->smp2p = smp2p; 249 250 ret = ipa_smp2p_irq_init(smp2p, "ipa-clock-query", 251 ipa_smp2p_modem_clk_query_isr); 252 if (ret < 0) 253 goto err_null_smp2p; 254 smp2p->clock_query_irq = ret; 255 256 ret = ipa_smp2p_panic_notifier_register(smp2p); 257 if (ret) 258 goto err_irq_exit; 259 260 if (modem_init) { 261 /* Result will be non-zero (negative for error) */ 262 ret = ipa_smp2p_irq_init(smp2p, "ipa-setup-ready", 263 ipa_smp2p_modem_setup_ready_isr); 264 if (ret < 0) 265 goto err_notifier_unregister; 266 smp2p->setup_ready_irq = ret; 267 } 268 269 return 0; 270 271 err_notifier_unregister: 272 ipa_smp2p_panic_notifier_unregister(smp2p); 273 err_irq_exit: 274 ipa_smp2p_irq_exit(smp2p, smp2p->clock_query_irq); 275 err_null_smp2p: 276 ipa->smp2p = NULL; 277 mutex_destroy(&smp2p->mutex); 278 kfree(smp2p); 279 280 return ret; 281 } 282 283 void ipa_smp2p_exit(struct ipa *ipa) 284 { 285 struct ipa_smp2p *smp2p = ipa->smp2p; 286 287 if (smp2p->setup_ready_irq) 288 ipa_smp2p_irq_exit(smp2p, smp2p->setup_ready_irq); 289 ipa_smp2p_panic_notifier_unregister(smp2p); 290 ipa_smp2p_irq_exit(smp2p, smp2p->clock_query_irq); 291 /* We won't get notified any more; drop clock reference (if any) */ 292 ipa_smp2p_clock_release(ipa); 293 ipa->smp2p = NULL; 294 mutex_destroy(&smp2p->mutex); 295 kfree(smp2p); 296 } 297 298 void ipa_smp2p_disable(struct ipa *ipa) 299 { 300 struct ipa_smp2p *smp2p = ipa->smp2p; 301 302 if (!smp2p->setup_ready_irq) 303 return; 304 305 mutex_lock(&smp2p->mutex); 306 307 smp2p->disabled = true; 308 309 mutex_unlock(&smp2p->mutex); 310 } 311 312 /* Reset state tracking whether we have notified the modem */ 313 void ipa_smp2p_notify_reset(struct ipa *ipa) 314 { 315 struct ipa_smp2p *smp2p = ipa->smp2p; 316 u32 mask; 317 318 if (!smp2p->notified) 319 return; 320 321 ipa_smp2p_clock_release(ipa); 322 323 /* Reset the clock enabled valid flag */ 324 mask = BIT(smp2p->valid_bit); 325 qcom_smem_state_update_bits(smp2p->valid_state, mask, 0); 326 327 /* Mark the clock disabled for good measure... */ 328 mask = BIT(smp2p->enabled_bit); 329 qcom_smem_state_update_bits(smp2p->enabled_state, mask, 0); 330 331 smp2p->notified = false; 332 } 333