hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/base/power/wakeirq.c
....@@ -145,24 +145,7 @@
145145 return IRQ_HANDLED;
146146 }
147147
148
-/**
149
- * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
150
- * @dev: Device entry
151
- * @irq: Device wake-up interrupt
152
- *
153
- * Unless your hardware has separate wake-up interrupts in addition
154
- * to the device IO interrupts, you don't need this.
155
- *
156
- * Sets up a threaded interrupt handler for a device that has
157
- * a dedicated wake-up interrupt in addition to the device IO
158
- * interrupt.
159
- *
160
- * The interrupt starts disabled, and needs to be managed for
161
- * the device by the bus code or the device driver using
162
- * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq()
163
- * functions.
164
- */
165
-int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
148
+static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag)
166149 {
167150 struct wake_irq *wirq;
168151 int err;
....@@ -200,7 +183,7 @@
200183 if (err)
201184 goto err_free_irq;
202185
203
- wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED;
186
+ wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag;
204187
205188 return err;
206189
....@@ -213,7 +196,56 @@
213196
214197 return err;
215198 }
199
+
200
+
201
+/**
202
+ * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
203
+ * @dev: Device entry
204
+ * @irq: Device wake-up interrupt
205
+ *
206
+ * Unless your hardware has separate wake-up interrupts in addition
207
+ * to the device IO interrupts, you don't need this.
208
+ *
209
+ * Sets up a threaded interrupt handler for a device that has
210
+ * a dedicated wake-up interrupt in addition to the device IO
211
+ * interrupt.
212
+ *
213
+ * The interrupt starts disabled, and needs to be managed for
214
+ * the device by the bus code or the device driver using
215
+ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*()
216
+ * functions.
217
+ */
218
+int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
219
+{
220
+ return __dev_pm_set_dedicated_wake_irq(dev, irq, 0);
221
+}
216222 EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
223
+
224
+/**
225
+ * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt
226
+ * with reverse enable ordering
227
+ * @dev: Device entry
228
+ * @irq: Device wake-up interrupt
229
+ *
230
+ * Unless your hardware has separate wake-up interrupts in addition
231
+ * to the device IO interrupts, you don't need this.
232
+ *
233
+ * Sets up a threaded interrupt handler for a device that has a dedicated
234
+ * wake-up interrupt in addition to the device IO interrupt. It sets
235
+ * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend()
236
+ * to enable dedicated wake-up interrupt after running the runtime suspend
237
+ * callback for @dev.
238
+ *
239
+ * The interrupt starts disabled, and needs to be managed for
240
+ * the device by the bus code or the device driver using
241
+ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*()
242
+ * functions.
243
+ */
244
+int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq)
245
+{
246
+ return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE);
247
+}
248
+EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse);
217249
218250 /**
219251 * dev_pm_enable_wake_irq - Enable device wake-up interrupt
....@@ -285,25 +317,56 @@
285317 return;
286318
287319 enable:
288
- enable_irq(wirq->irq);
320
+ if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) {
321
+ enable_irq(wirq->irq);
322
+ wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
323
+ }
289324 }
290325
291326 /**
292327 * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
293328 * @dev: Device
329
+ * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE
294330 *
295331 * Disables wake-up interrupt conditionally based on status.
296332 * Should be only called from rpm_suspend() and rpm_resume() path.
297333 */
298
-void dev_pm_disable_wake_irq_check(struct device *dev)
334
+void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable)
299335 {
300336 struct wake_irq *wirq = dev->power.wakeirq;
301337
302338 if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
303339 return;
304340
305
- if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
341
+ if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
342
+ return;
343
+
344
+ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) {
345
+ wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED;
306346 disable_irq_nosync(wirq->irq);
347
+ }
348
+}
349
+
350
+/**
351
+ * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before
352
+ * @dev: Device using the wake IRQ
353
+ *
354
+ * Enable wake IRQ conditionally based on status, mainly used if want to
355
+ * enable wake IRQ after running ->runtime_suspend() which depends on
356
+ * WAKE_IRQ_DEDICATED_REVERSE.
357
+ *
358
+ * Should be only called from rpm_suspend() path.
359
+ */
360
+void dev_pm_enable_wake_irq_complete(struct device *dev)
361
+{
362
+ struct wake_irq *wirq = dev->power.wakeirq;
363
+
364
+ if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
365
+ return;
366
+
367
+ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
368
+ wirq->status & WAKE_IRQ_DEDICATED_REVERSE)
369
+ enable_irq(wirq->irq);
307370 }
308371
309372 /**
....@@ -320,7 +383,7 @@
320383
321384 if (device_may_wakeup(wirq->dev)) {
322385 if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
323
- !pm_runtime_status_suspended(wirq->dev))
386
+ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
324387 enable_irq(wirq->irq);
325388
326389 enable_irq_wake(wirq->irq);
....@@ -343,7 +406,7 @@
343406 disable_irq_wake(wirq->irq);
344407
345408 if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
346
- !pm_runtime_status_suspended(wirq->dev))
409
+ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
347410 disable_irq_nosync(wirq->irq);
348411 }
349412 }