xref: /linux/drivers/base/power/wakeirq.c (revision e814f3fd16acfb7f9966773953de8f740a1e3202)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Device wakeirq helper functions */
3 #include <linux/device.h>
4 #include <linux/interrupt.h>
5 #include <linux/irq.h>
6 #include <linux/slab.h>
7 #include <linux/pm_runtime.h>
8 #include <linux/pm_wakeirq.h>
9 
10 #include "power.h"
11 
12 /**
13  * dev_pm_attach_wake_irq - Attach device interrupt as a wake IRQ
14  * @dev: Device entry
15  * @wirq: Wake irq specific data
16  *
17  * Internal function to attach a dedicated wake-up interrupt as a wake IRQ.
18  */
19 static int dev_pm_attach_wake_irq(struct device *dev, struct wake_irq *wirq)
20 {
21 	unsigned long flags;
22 
23 	if (!dev || !wirq)
24 		return -EINVAL;
25 
26 	spin_lock_irqsave(&dev->power.lock, flags);
27 	if (dev_WARN_ONCE(dev, dev->power.wakeirq,
28 			  "wake irq already initialized\n")) {
29 		spin_unlock_irqrestore(&dev->power.lock, flags);
30 		return -EEXIST;
31 	}
32 
33 	dev->power.wakeirq = wirq;
34 	device_wakeup_attach_irq(dev, wirq);
35 
36 	spin_unlock_irqrestore(&dev->power.lock, flags);
37 	return 0;
38 }
39 
40 /**
41  * dev_pm_set_wake_irq - Attach device IO interrupt as wake IRQ
42  * @dev: Device entry
43  * @irq: Device IO interrupt
44  *
45  * Attach a device IO interrupt as a wake IRQ. The wake IRQ gets
46  * automatically configured for wake-up from suspend  based
47  * on the device specific sysfs wakeup entry. Typically called
48  * during driver probe after calling device_init_wakeup().
49  */
50 int dev_pm_set_wake_irq(struct device *dev, int irq)
51 {
52 	struct wake_irq *wirq;
53 	int err;
54 
55 	if (irq < 0)
56 		return -EINVAL;
57 
58 	wirq = kzalloc(sizeof(*wirq), GFP_KERNEL);
59 	if (!wirq)
60 		return -ENOMEM;
61 
62 	wirq->dev = dev;
63 	wirq->irq = irq;
64 
65 	err = dev_pm_attach_wake_irq(dev, wirq);
66 	if (err)
67 		kfree(wirq);
68 
69 	return err;
70 }
71 EXPORT_SYMBOL_GPL(dev_pm_set_wake_irq);
72 
73 /**
74  * dev_pm_clear_wake_irq - Detach a device IO interrupt wake IRQ
75  * @dev: Device entry
76  *
77  * Detach a device wake IRQ and free resources.
78  *
79  * Note that it's OK for drivers to call this without calling
80  * dev_pm_set_wake_irq() as all the driver instances may not have
81  * a wake IRQ configured. This avoid adding wake IRQ specific
82  * checks into the drivers.
83  */
84 void dev_pm_clear_wake_irq(struct device *dev)
85 {
86 	struct wake_irq *wirq = dev->power.wakeirq;
87 	unsigned long flags;
88 
89 	if (!wirq)
90 		return;
91 
92 	spin_lock_irqsave(&dev->power.lock, flags);
93 	device_wakeup_detach_irq(dev);
94 	dev->power.wakeirq = NULL;
95 	spin_unlock_irqrestore(&dev->power.lock, flags);
96 
97 	if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED) {
98 		free_irq(wirq->irq, wirq);
99 		wirq->status &= ~WAKE_IRQ_DEDICATED_MASK;
100 	}
101 	kfree(wirq->name);
102 	kfree(wirq);
103 }
104 EXPORT_SYMBOL_GPL(dev_pm_clear_wake_irq);
105 
106 static void devm_pm_clear_wake_irq(void *dev)
107 {
108 	dev_pm_clear_wake_irq(dev);
109 }
110 
111 /**
112  * devm_pm_set_wake_irq - device-managed variant of dev_pm_set_wake_irq
113  * @dev: Device entry
114  * @irq: Device IO interrupt
115  *
116  *
117  * Attach a device IO interrupt as a wake IRQ, same with dev_pm_set_wake_irq,
118  * but the device will be auto clear wake capability on driver detach.
119  */
120 int devm_pm_set_wake_irq(struct device *dev, int irq)
121 {
122 	int ret;
123 
124 	ret = dev_pm_set_wake_irq(dev, irq);
125 	if (ret)
126 		return ret;
127 
128 	return devm_add_action_or_reset(dev, devm_pm_clear_wake_irq, dev);
129 }
130 EXPORT_SYMBOL_GPL(devm_pm_set_wake_irq);
131 
132 /**
133  * handle_threaded_wake_irq - Handler for dedicated wake-up interrupts
134  * @irq: Device specific dedicated wake-up interrupt
135  * @_wirq: Wake IRQ data
136  *
137  * Some devices have a separate wake-up interrupt in addition to the
138  * device IO interrupt. The wake-up interrupt signals that a device
139  * should be woken up from it's idle state. This handler uses device
140  * specific pm_runtime functions to wake the device, and then it's
141  * up to the device to do whatever it needs to. Note that as the
142  * device may need to restore context and start up regulators, we
143  * use a threaded IRQ.
144  *
145  * Also note that we are not resending the lost device interrupts.
146  * We assume that the wake-up interrupt just needs to wake-up the
147  * device, and then device's pm_runtime_resume() can deal with the
148  * situation.
149  */
150 static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq)
151 {
152 	struct wake_irq *wirq = _wirq;
153 	int res;
154 
155 	/* Maybe abort suspend? */
156 	if (irqd_is_wakeup_set(irq_get_irq_data(irq))) {
157 		pm_wakeup_event(wirq->dev, 0);
158 
159 		return IRQ_HANDLED;
160 	}
161 
162 	/* We don't want RPM_ASYNC or RPM_NOWAIT here */
163 	res = pm_runtime_resume(wirq->dev);
164 	if (res < 0)
165 		dev_warn(wirq->dev,
166 			 "wake IRQ with no resume: %i\n", res);
167 
168 	return IRQ_HANDLED;
169 }
170 
171 static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag)
172 {
173 	struct wake_irq *wirq;
174 	int err;
175 
176 	if (irq < 0)
177 		return -EINVAL;
178 
179 	wirq = kzalloc(sizeof(*wirq), GFP_KERNEL);
180 	if (!wirq)
181 		return -ENOMEM;
182 
183 	wirq->name = kasprintf(GFP_KERNEL, "%s:wakeup", dev_name(dev));
184 	if (!wirq->name) {
185 		err = -ENOMEM;
186 		goto err_free;
187 	}
188 
189 	wirq->dev = dev;
190 	wirq->irq = irq;
191 
192 	/* Prevent deferred spurious wakeirqs with disable_irq_nosync() */
193 	irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
194 
195 	/*
196 	 * Consumer device may need to power up and restore state
197 	 * so we use a threaded irq.
198 	 */
199 	err = request_threaded_irq(irq, NULL, handle_threaded_wake_irq,
200 				   IRQF_ONESHOT | IRQF_NO_AUTOEN,
201 				   wirq->name, wirq);
202 	if (err)
203 		goto err_free_name;
204 
205 	err = dev_pm_attach_wake_irq(dev, wirq);
206 	if (err)
207 		goto err_free_irq;
208 
209 	wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag;
210 
211 	return err;
212 
213 err_free_irq:
214 	free_irq(irq, wirq);
215 err_free_name:
216 	kfree(wirq->name);
217 err_free:
218 	kfree(wirq);
219 
220 	return err;
221 }
222 
223 /**
224  * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
225  * @dev: Device entry
226  * @irq: Device wake-up interrupt
227  *
228  * Unless your hardware has separate wake-up interrupts in addition
229  * to the device IO interrupts, you don't need this.
230  *
231  * Sets up a threaded interrupt handler for a device that has
232  * a dedicated wake-up interrupt in addition to the device IO
233  * interrupt.
234  */
235 int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
236 {
237 	return __dev_pm_set_dedicated_wake_irq(dev, irq, 0);
238 }
239 EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
240 
241 /**
242  * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt
243  *                                         with reverse enable ordering
244  * @dev: Device entry
245  * @irq: Device wake-up interrupt
246  *
247  * Unless your hardware has separate wake-up interrupts in addition
248  * to the device IO interrupts, you don't need this.
249  *
250  * Sets up a threaded interrupt handler for a device that has a dedicated
251  * wake-up interrupt in addition to the device IO interrupt. It sets
252  * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend()
253  * to enable dedicated wake-up interrupt after running the runtime suspend
254  * callback for @dev.
255  */
256 int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq)
257 {
258 	return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE);
259 }
260 EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse);
261 
262 /**
263  * dev_pm_enable_wake_irq_check - Checks and enables wake-up interrupt
264  * @dev: Device
265  * @can_change_status: Can change wake-up interrupt status
266  *
267  * Enables wakeirq conditionally. We need to enable wake-up interrupt
268  * lazily on the first rpm_suspend(). This is needed as the consumer device
269  * starts in RPM_SUSPENDED state, and the first pm_runtime_get() would
270  * otherwise try to disable already disabled wakeirq. The wake-up interrupt
271  * starts disabled with IRQ_NOAUTOEN set.
272  *
273  * Should be only called from rpm_suspend() and rpm_resume() path.
274  * Caller must hold &dev->power.lock to change wirq->status
275  */
276 void dev_pm_enable_wake_irq_check(struct device *dev,
277 				  bool can_change_status)
278 {
279 	struct wake_irq *wirq = dev->power.wakeirq;
280 
281 	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
282 		return;
283 
284 	if (likely(wirq->status & WAKE_IRQ_DEDICATED_MANAGED)) {
285 		goto enable;
286 	} else if (can_change_status) {
287 		wirq->status |= WAKE_IRQ_DEDICATED_MANAGED;
288 		goto enable;
289 	}
290 
291 	return;
292 
293 enable:
294 	if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) {
295 		enable_irq(wirq->irq);
296 		wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
297 	}
298 }
299 
300 /**
301  * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
302  * @dev: Device
303  * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE
304  *
305  * Disables wake-up interrupt conditionally based on status.
306  * Should be only called from rpm_suspend() and rpm_resume() path.
307  */
308 void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable)
309 {
310 	struct wake_irq *wirq = dev->power.wakeirq;
311 
312 	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
313 		return;
314 
315 	if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
316 		return;
317 
318 	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) {
319 		wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED;
320 		disable_irq_nosync(wirq->irq);
321 	}
322 }
323 
324 /**
325  * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before
326  * @dev: Device using the wake IRQ
327  *
328  * Enable wake IRQ conditionally based on status, mainly used if want to
329  * enable wake IRQ after running ->runtime_suspend() which depends on
330  * WAKE_IRQ_DEDICATED_REVERSE.
331  *
332  * Should be only called from rpm_suspend() path.
333  */
334 void dev_pm_enable_wake_irq_complete(struct device *dev)
335 {
336 	struct wake_irq *wirq = dev->power.wakeirq;
337 
338 	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
339 		return;
340 
341 	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
342 	    wirq->status & WAKE_IRQ_DEDICATED_REVERSE) {
343 		enable_irq(wirq->irq);
344 		wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
345 	}
346 }
347 
348 /**
349  * dev_pm_arm_wake_irq - Arm device wake-up
350  * @wirq: Device wake-up interrupt
351  *
352  * Sets up the wake-up event conditionally based on the
353  * device_may_wake().
354  */
355 void dev_pm_arm_wake_irq(struct wake_irq *wirq)
356 {
357 	if (!wirq)
358 		return;
359 
360 	if (device_may_wakeup(wirq->dev)) {
361 		if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
362 		    !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
363 			enable_irq(wirq->irq);
364 
365 		enable_irq_wake(wirq->irq);
366 	}
367 }
368 
369 /**
370  * dev_pm_disarm_wake_irq - Disarm device wake-up
371  * @wirq: Device wake-up interrupt
372  *
373  * Clears up the wake-up event conditionally based on the
374  * device_may_wake().
375  */
376 void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
377 {
378 	if (!wirq)
379 		return;
380 
381 	if (device_may_wakeup(wirq->dev)) {
382 		disable_irq_wake(wirq->irq);
383 
384 		if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
385 		    !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
386 			disable_irq_nosync(wirq->irq);
387 	}
388 }
389