static int device_resume_noirq()

in power/main.c [590:659]


static int device_resume_noirq(struct device *dev, pm_message_t state, bool async)
{
	pm_callback_t callback = NULL;
	const char *info = NULL;
	bool skip_resume;
	int error = 0;

	TRACE_DEVICE(dev);
	TRACE_RESUME(0);

	if (dev->power.syscore || dev->power.direct_complete)
		goto Out;

	if (!dev->power.is_noirq_suspended)
		goto Out;

	if (!dpm_wait_for_superior(dev, async))
		goto Out;

	skip_resume = dev_pm_skip_resume(dev);
	/*
	 * If the driver callback is skipped below or by the middle layer
	 * callback and device_resume_early() also skips the driver callback for
	 * this device later, it needs to appear as "suspended" to PM-runtime,
	 * so change its status accordingly.
	 *
	 * Otherwise, the device is going to be resumed, so set its PM-runtime
	 * status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
	 * to avoid confusing drivers that don't use it.
	 */
	if (skip_resume)
		pm_runtime_set_suspended(dev);
	else if (dev_pm_skip_suspend(dev))
		pm_runtime_set_active(dev);

	if (dev->pm_domain) {
		info = "noirq power domain ";
		callback = pm_noirq_op(&dev->pm_domain->ops, state);
	} else if (dev->type && dev->type->pm) {
		info = "noirq type ";
		callback = pm_noirq_op(dev->type->pm, state);
	} else if (dev->class && dev->class->pm) {
		info = "noirq class ";
		callback = pm_noirq_op(dev->class->pm, state);
	} else if (dev->bus && dev->bus->pm) {
		info = "noirq bus ";
		callback = pm_noirq_op(dev->bus->pm, state);
	}
	if (callback)
		goto Run;

	if (skip_resume)
		goto Skip;

	if (dev->driver && dev->driver->pm) {
		info = "noirq driver ";
		callback = pm_noirq_op(dev->driver->pm, state);
	}

Run:
	error = dpm_run_callback(callback, dev, state, info);

Skip:
	dev->power.is_noirq_suspended = false;

Out:
	complete_all(&dev->power.completion);
	TRACE_RESUME(error);
	return error;
}