forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-09 244b2c5ca8b14627e4a17755e5922221e121c771
kernel/drivers/base/power/wakeirq.c
....@@ -1,16 +1,5 @@
1
-/*
2
- * wakeirq.c - Device wakeirq helper functions
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
7
- *
8
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9
- * kind, whether express or implied; without even the implied warranty
10
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
12
- */
13
-
1
+// SPDX-License-Identifier: GPL-2.0
2
+/* Device wakeirq helper functions */
143 #include <linux/device.h>
154 #include <linux/interrupt.h>
165 #include <linux/irq.h>
....@@ -156,24 +145,7 @@
156145 return IRQ_HANDLED;
157146 }
158147
159
-/**
160
- * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
161
- * @dev: Device entry
162
- * @irq: Device wake-up interrupt
163
- *
164
- * Unless your hardware has separate wake-up interrupts in addition
165
- * to the device IO interrupts, you don't need this.
166
- *
167
- * Sets up a threaded interrupt handler for a device that has
168
- * a dedicated wake-up interrupt in addition to the device IO
169
- * interrupt.
170
- *
171
- * The interrupt starts disabled, and needs to be managed for
172
- * the device by the bus code or the device driver using
173
- * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq()
174
- * functions.
175
- */
176
-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)
177149 {
178150 struct wake_irq *wirq;
179151 int err;
....@@ -211,7 +183,7 @@
211183 if (err)
212184 goto err_free_irq;
213185
214
- wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED;
186
+ wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag;
215187
216188 return err;
217189
....@@ -224,7 +196,56 @@
224196
225197 return err;
226198 }
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
+}
227222 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);
228249
229250 /**
230251 * dev_pm_enable_wake_irq - Enable device wake-up interrupt
....@@ -283,7 +304,7 @@
283304 {
284305 struct wake_irq *wirq = dev->power.wakeirq;
285306
286
- if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK)))
307
+ if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
287308 return;
288309
289310 if (likely(wirq->status & WAKE_IRQ_DEDICATED_MANAGED)) {
....@@ -296,25 +317,56 @@
296317 return;
297318
298319 enable:
299
- 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
+ }
300324 }
301325
302326 /**
303327 * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
304328 * @dev: Device
329
+ * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE
305330 *
306331 * Disables wake-up interrupt conditionally based on status.
307332 * Should be only called from rpm_suspend() and rpm_resume() path.
308333 */
309
-void dev_pm_disable_wake_irq_check(struct device *dev)
334
+void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable)
310335 {
311336 struct wake_irq *wirq = dev->power.wakeirq;
312337
313
- if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK)))
338
+ if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
314339 return;
315340
316
- 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;
317346 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);
318370 }
319371
320372 /**
....@@ -331,7 +383,7 @@
331383
332384 if (device_may_wakeup(wirq->dev)) {
333385 if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
334
- !pm_runtime_status_suspended(wirq->dev))
386
+ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
335387 enable_irq(wirq->irq);
336388
337389 enable_irq_wake(wirq->irq);
....@@ -354,7 +406,7 @@
354406 disable_irq_wake(wirq->irq);
355407
356408 if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
357
- !pm_runtime_status_suspended(wirq->dev))
409
+ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
358410 disable_irq_nosync(wirq->irq);
359411 }
360412 }