cregit-Linux how code gets into the kernel

Release 4.15 kernel/power/autosleep.c

Directory: kernel/power
// SPDX-License-Identifier: GPL-2.0
/*
 * kernel/power/autosleep.c
 *
 * Opportunistic sleep support.
 *
 * Copyright (C) 2012 Rafael J. Wysocki <rjw@sisk.pl>
 */

#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/pm_wakeup.h>

#include "power.h"


static suspend_state_t autosleep_state;

static struct workqueue_struct *autosleep_wq;
/*
 * Note: it is only safe to mutex_lock(&autosleep_lock) if a wakeup_source
 * is active, otherwise a deadlock with try_to_suspend() is possible.
 * Alternatively mutex_lock_interruptible() can be used.  This will then fail
 * if an auto_sleep cycle tries to freeze processes.
 */
static DEFINE_MUTEX(autosleep_lock);

static struct wakeup_source *autosleep_ws;


static void try_to_suspend(struct work_struct *work) { unsigned int initial_count, final_count; if (!pm_get_wakeup_count(&initial_count, true)) goto out; mutex_lock(&autosleep_lock); if (!pm_save_wakeup_count(initial_count) || system_state != SYSTEM_RUNNING) { mutex_unlock(&autosleep_lock); goto out; } if (autosleep_state == PM_SUSPEND_ON) { mutex_unlock(&autosleep_lock); return; } if (autosleep_state >= PM_SUSPEND_MAX) hibernate(); else pm_suspend(autosleep_state); mutex_unlock(&autosleep_lock); if (!pm_get_wakeup_count(&final_count, false)) goto out; /* * If the wakeup occured for an unknown reason, wait to prevent the * system from trying to suspend and waking up in a tight loop. */ if (final_count == initial_count) schedule_timeout_uninterruptible(HZ / 2); out: queue_up_suspend_work(); }

Contributors

PersonTokensPropCommitsCommitProp
Rafael J. Wysocki12596.90%150.00%
Liu ShuoX43.10%150.00%
Total129100.00%2100.00%

static DECLARE_WORK(suspend_work, try_to_suspend);
void queue_up_suspend_work(void) { if (autosleep_state > PM_SUSPEND_ON) queue_work(autosleep_wq, &suspend_work); }

Contributors

PersonTokensPropCommitsCommitProp
Rafael J. Wysocki21100.00%1100.00%
Total21100.00%1100.00%


suspend_state_t pm_autosleep_state(void) { return autosleep_state; }

Contributors

PersonTokensPropCommitsCommitProp
Rafael J. Wysocki10100.00%1100.00%
Total10100.00%1100.00%


int pm_autosleep_lock(void) { return mutex_lock_interruptible(&autosleep_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Rafael J. Wysocki14100.00%1100.00%
Total14100.00%1100.00%


void pm_autosleep_unlock(void) { mutex_unlock(&autosleep_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Rafael J. Wysocki13100.00%1100.00%
Total13100.00%1100.00%


int pm_autosleep_set_state(suspend_state_t state) { #ifndef CONFIG_HIBERNATION if (state >= PM_SUSPEND_MAX) return -EINVAL; #endif __pm_stay_awake(autosleep_ws); mutex_lock(&autosleep_lock); autosleep_state = state; __pm_relax(autosleep_ws); if (state > PM_SUSPEND_ON) { pm_wakep_autosleep_enabled(true); queue_up_suspend_work(); } else { pm_wakep_autosleep_enabled(false); } mutex_unlock(&autosleep_lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Rafael J. Wysocki76100.00%2100.00%
Total76100.00%2100.00%


int __init pm_autosleep_init(void) { autosleep_ws = wakeup_source_register("autosleep"); if (!autosleep_ws) return -ENOMEM; autosleep_wq = alloc_ordered_workqueue("autosleep", 0); if (autosleep_wq) return 0; wakeup_source_unregister(autosleep_ws); return -ENOMEM; }

Contributors

PersonTokensPropCommitsCommitProp
Rafael J. Wysocki49100.00%1100.00%
Total49100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Rafael J. Wysocki35298.60%250.00%
Liu ShuoX41.12%125.00%
Greg Kroah-Hartman10.28%125.00%
Total357100.00%4100.00%
Directory: kernel/power
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.