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