码迷,mamicode.com
首页 > 其他好文 > 详细

kernel syscore

时间:2015-05-10 22:25:13      阅读:541      评论:0      收藏:0      [点我收藏+]

标签:

syscore作为低功耗流程的一部分,其涉及的文件主要有syscore_ops.h和syscore.c,这一级别的回调函数是在完全屏蔽中断的场景下进行的。

1、主要结构体struct syscore_ops,该结构体是syscore操作的对象类型。

struct syscore_ops {
	struct list_head node;//用于链表控制,注册和删除syscore对象时操作此链表完成
	int (*suspend)(void);//睡眠流程时回调函数
	void (*resume)(void);//唤醒流程时回调函数
	void (*shutdown)(void);//这一级别的回调函数主要用于系统级的重启、停止或者掉电时才会使用
};

2、主要接口:

extern void register_syscore_ops(struct syscore_ops *ops);//注册syscore回调函数
extern void unregister_syscore_ops(struct syscore_ops *ops);//取消注册的回调函数
#ifdef CONFIG_PM_SLEEP
extern int syscore_suspend(void);//回调注册的syscore对象的suspend回调函数
extern void syscore_resume(void);//回调注册的syscore对象的resume回调函数
#endif
extern void syscore_shutdown(void);//回调注册的syscore对象的shutdown回调函数

3、具体实现,syscore.c

1)全局变量

static LIST_HEAD(syscore_ops_list);//初始化控制链表头结点,统一管理注册的syscore对象
static DEFINE_MUTEX(syscore_ops_lock);//访问上述链表时,通过此互斥信号量来互斥访问

2)register_syscore_ops:其他组件主要通过此接口来注册回调函数,我们可以看到,把注册的对象存放在了syscore_ops_list链表中。

/**
 * register_syscore_ops - Register a set of system core operations.
 * @ops: System core operations to register.
 */
void register_syscore_ops(struct syscore_ops *ops)
{
	mutex_lock(&syscore_ops_lock);
	list_add_tail(&ops->node, &syscore_ops_list);
	mutex_unlock(&syscore_ops_lock);
}

3)unregister_syscore_ops:与register_syscore_ops功能相反,取消注册,从控制链表中删除。

/**
 * unregister_syscore_ops - Unregister a set of system core operations.
 * @ops: System core operations to unregister.
 */
void unregister_syscore_ops(struct syscore_ops *ops)
{
	mutex_lock(&syscore_ops_lock);
	list_del(&ops->node);
	mutex_unlock(&syscore_ops_lock);
}

4)syscore_suspend:该接口回调所有注册对象的suspend接口,该接口在suspend.c的suspend_enter函数中被调用,执行cpu掉电前的最后阶段操作。

/**
 * syscore_suspend - Execute all the registered system core suspend callbacks.
 *
 * This function is executed with one CPU on-line and disabled interrupts.
 */
int syscore_suspend(void)
{
	struct syscore_ops *ops;
	int ret = 0;

	pr_debug("Checking wakeup interrupts\n");

	/* Return error code if there are any wakeup interrupts pending. */
	ret = check_wakeup_irqs();
	if (ret)
		return ret;

	WARN_ONCE(!irqs_disabled(),
		"Interrupts enabled before system core suspend.\n");//我们可以看到,如果此时中断没有屏蔽掉,会有警告产生

	list_for_each_entry_reverse(ops, &syscore_ops_list, node)//按照链表逆序执行各个注册对象的suspend回调函数
		if (ops->suspend) {
			if (initcall_debug)
				pr_info("PM: Calling %pF\n", ops->suspend);
			ret = ops->suspend();
			if (ret)
				goto err_out;
			WARN_ONCE(!irqs_disabled(),
				"Interrupts enabled after %pF\n", ops->suspend);
		}

	return 0;

 err_out:
	pr_err("PM: System core suspend callback %pF failed.\n", ops->suspend);

	list_for_each_entry_continue(ops, &syscore_ops_list, node)//如果有失败的,则执行已经执行过suspend回调的对象的resume回调
		if (ops->resume)
			ops->resume();

	return ret;
}
EXPORT_SYMBOL_GPL(syscore_suspend);

5)syscore_resume:执行注册对象的resume回调,在suspend.c的唤醒流程中被调用

/**
 * syscore_resume - Execute all the registered system core resume callbacks.
 *
 * This function is executed with one CPU on-line and disabled interrupts.
 */
void syscore_resume(void)
{
	struct syscore_ops *ops;

	WARN_ONCE(!irqs_disabled(),
		"Interrupts enabled before system core resume.\n");

	list_for_each_entry(ops, &syscore_ops_list, node)
		if (ops->resume) {
			if (initcall_debug)
				pr_info("PM: Calling %pF\n", ops->resume);
			ops->resume();
			WARN_ONCE(!irqs_disabled(),
				"Interrupts enabled after %pF\n", ops->resume);
		}
}


6)syscore_shutdown:该接口正常睡眠流程中不涉及调用,主要在sys.c中调用,涉及系统重启、halt等流程。

/**
 * syscore_shutdown - Execute all the registered system core shutdown callbacks.
 */
void syscore_shutdown(void)
{
	struct syscore_ops *ops;

	mutex_lock(&syscore_ops_lock);

	list_for_each_entry_reverse(ops, &syscore_ops_list, node)
		if (ops->shutdown) {
			if (initcall_debug)
				pr_info("PM: Calling %pF\n", ops->shutdown);
			ops->shutdown();
		}

	mutex_unlock(&syscore_ops_lock);
}








 

kernel syscore

标签:

原文地址:http://blog.csdn.net/lixiaojie1012/article/details/45625699

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!