1 From 8330651863c4b554961204475073b7af1cdf10bc Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Fri, 25 Jul 2008 23:06:11 +0100
4 Subject: [PATCH] introduce-resume-dependency.patch
6 Defines a way for drivers to defer execution of resume callbacks
7 until one or more other driver they are dependent on has itself
10 Signed-off-by: Andy Green <andy@openmoko.com>
12 include/linux/resume-dependency.h | 78 +++++++++++++++++++++++++++++++++++++
13 1 files changed, 78 insertions(+), 0 deletions(-)
14 create mode 100644 include/linux/resume-dependency.h
16 diff --git a/include/linux/resume-dependency.h b/include/linux/resume-dependency.h
18 index 0000000..b13aa3e
20 +++ b/include/linux/resume-dependency.h
22 +#ifndef __RESUME_DEPENDENCY_H__
23 +#define __RESUME_DEPENDENCY_H__
25 +/* Resume dependency framework
27 + * (C) 2008 Openmoko, Inc.
28 + * Author: Andy Green <andy@openmoko.com>
30 + * This program is free software; you can redistribute it and/or
31 + * modify it under the terms of the GNU General Public License as
32 + * published by the Free Software Foundation; version 2.1.
34 + * This program is distributed in the hope that it will be useful,
35 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 + * GNU General Public License for more details.
39 + * You should have received a copy of the GNU General Public License
40 + * along with this program; if not, write to the Free Software
41 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
46 +#include <linux/list.h>
48 +struct resume_dependency {
49 + struct list_head list;
51 + void (*callback)(void *); /* called with context as arg */
53 + int called_flag; /* set to 1 after called, use for multi dep */
56 +/* if you are a driver accept to have other drivers as dependencies, you need to
57 + * instantiate a struct resume_dependency above, then initialize it by invoking
58 + * init_resume_dependency_list() on it
61 +#define init_resume_dependency_list(_head) \
62 + INIT_LIST_HEAD(&_head.list);
65 +/* if your resume function depends on something else being resumed first, you
66 + * can register the dependency by calling this in your suspend function with
67 + * head being the list held by the thing you are dependent on, and dep being
68 + * your struct resume_dependency
71 +#define register_resume_dependency(_head, _dep) { \
72 + _dep->called_flag = 0; \
73 + list_add(&_dep->list, &_head->list); \
76 +/* In the resume function that things can be dependent on, at the end you
77 + * invoke this macro. This calls back the dependent resumes now it is safe to
78 + * use the resumed thing they were dependent on.
81 +#define callback_all_resume_dependencies(_head) { \
82 + struct list_head *_pos, *_q; \
83 + struct resume_dependency *_dep; \
85 + list_for_each_safe(pos, _q, &_head.list) { \
86 + _dep = list_entry(_pos, struct resume_dependency, list); \
87 + _dep->called_flag = 1; \
88 + (_dep->callback)(dep->context); \
93 +/* if your resume action is dependent on multiple drivers being resumed already,
94 + * register the same callback with each driver you are dependent on, and check
95 + * .called_flag for all of the struct resume_dependency. When they are all 1
96 + * you know it is the last callback and you can resume, otherwise just return