内核ACPI函数API之acpi_os_execute

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tiantao2012/article/details/79955842
acpi_status acpi_os_execute(acpi_execute_type type,
			    acpi_osd_exec_callback function, void *context)
这个函数主要作用是执行形参的callback函数,根据type的不同可以选择不同的queue来执行
acpi_status acpi_os_execute(acpi_execute_type type,
			    acpi_osd_exec_callback function, void *context)
{
	acpi_status status = AE_OK;
	struct acpi_os_dpc *dpc;
	struct workqueue_struct *queue;
	int ret;
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
			  "Scheduling function [%p(%p)] for deferred execution.\n",
			  function, context));
	#一般用于debug
	if (type == OSL_DEBUGGER_MAIN_THREAD) {
		ret = acpi_debugger_create_thread(function, context);
		if (ret) {
			pr_err("Call to kthread_create() failed.\n");
			status = AE_ERROR;
		}
		goto out_thread;
	}

	/*
	 * Allocate/initialize DPC structure.  Note that this memory will be
	 * freed by the callee.  The kernel handles the work_struct list  in a
	 * way that allows us to also free its memory inside the callee.
	 * Because we may want to schedule several tasks with different
	 * parameters we can't use the approach some kernel code uses of
	 * having a static work_struct.
	 */
	#申请一个acpi_os_dpc 结构,用于保存要执行的callback和参数
	dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
	if (!dpc)
		return AE_NO_MEMORY;

	dpc->function = function;
	dpc->context = context;

	/*
	 * To prevent lockdep from complaining unnecessarily, make sure that
	 * there is a different static lockdep key for each workqueue by using
	 * INIT_WORK() for each of them separately.
	 */
	 #根据不同的type,可以选择不同的queue 来执行
	if (type == OSL_NOTIFY_HANDLER) {
	#根据type给queue赋值,并初始化要执行的队列
		queue = kacpi_notify_wq;
		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
	} else if (type == OSL_GPE_HANDLER) {
		queue = kacpid_wq;
		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
	} else {
		pr_err("Unsupported os_execute type %d.\n", type);
		status = AE_ERROR;
	}

	if (ACPI_FAILURE(status))
		goto err_workqueue;

	/*
	 * On some machines, a software-initiated SMI causes corruption unless
	 * the SMI runs on CPU 0.  An SMI can be initiated by any AML, but
	 * typically it's done in GPE-related methods that are run via
	 * workqueues, so we can avoid the known corruption cases by always
	 * queueing on CPU 0.
	 */
	 #执行这个queue
	ret = queue_work_on(0, queue, &dpc->work);
	if (!ret) {
		printk(KERN_ERR PREFIX
			  "Call to queue_work() failed.\n");
		status = AE_ERROR;
	}
err_workqueue:
	if (ACPI_FAILURE(status))
		kfree(dpc);
out_thread:
	return status;
}

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页