1d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge/*
2e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * Copyright (c) International Business Machines  Corp., 2001
3e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
4d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge *
5e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * This program is free software;  you can redistribute it and/or modify
6e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * it under the terms of the GNU General Public License as published by
7e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * the Free Software Foundation; either version 2 of the License, or
8e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * (at your option) any later version.
9d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge *
10e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * This program is distributed in the hope that it will be useful,
11e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * but WITHOUT ANY WARRANTY;  without even the implied warranty of
12e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * the GNU General Public License for more details.
14d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge *
15e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * You should have received a copy of the GNU General Public License
16e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * along with this program;  if not, write to the Free Software
17e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge */
19d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge
20d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge/*
21d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge *  HISTORY:
22d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge *    06/09/2003 Initial creation mridge@us.ibm.com
23d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge *      -Ported
24d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge *  updated - 01/09/2005 Updates from Intel to add functionality
25d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge *
2690619d17f707e000c81a8aa6844b5e75474d89absubrata_modak *  01/03/2009 Márton Németh <nm127@freemail.hu>
2790619d17f707e000c81a8aa6844b5e75474d89absubrata_modak *   - Updated for Linux kernel 2.6.28
28d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge */
296e52dbe593c870abf76eb7fab952cdae738ffb52mridge
306e52dbe593c870abf76eb7fab952cdae738ffb52mridge#include <linux/kernel.h>
316e52dbe593c870abf76eb7fab952cdae738ffb52mridge#include <linux/module.h>
326e52dbe593c870abf76eb7fab952cdae738ffb52mridge#include <linux/init.h>
336e52dbe593c870abf76eb7fab952cdae738ffb52mridge#include <linux/types.h>
3490619d17f707e000c81a8aa6844b5e75474d89absubrata_modak#include <linux/fs.h>
3590619d17f707e000c81a8aa6844b5e75474d89absubrata_modak#include <linux/blkdev.h>
366e52dbe593c870abf76eb7fab952cdae738ffb52mridge#include <linux/ioctl.h>
3790619d17f707e000c81a8aa6844b5e75474d89absubrata_modak#include <linux/pm.h>
386e52dbe593c870abf76eb7fab952cdae738ffb52mridge#include <linux/acpi.h>
396e52dbe593c870abf76eb7fab952cdae738ffb52mridge#include <linux/genhd.h>
40e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#include <linux/dmi.h>
41e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#include <linux/nls.h>
426e52dbe593c870abf76eb7fab952cdae738ffb52mridge
43e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#include "ltp_acpi.h"
446e52dbe593c870abf76eb7fab952cdae738ffb52mridge
456e52dbe593c870abf76eb7fab952cdae738ffb52mridgeMODULE_AUTHOR("Martin Ridgeway <mridge@us.ibm.com>");
46e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey KodanevMODULE_AUTHOR("Alexey Kodanev <alexey.kodanev@oracle.com>");
47e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey KodanevMODULE_DESCRIPTION("ACPI LTP Test Driver");
486e52dbe593c870abf76eb7fab952cdae738ffb52mridgeMODULE_LICENSE("GPL");
49e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey KodanevACPI_MODULE_NAME("LTP_ACPI")
506e52dbe593c870abf76eb7fab952cdae738ffb52mridge
51e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#define prk_err(fmt, ...) \
52e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	pr_err(ACPI_TEST_NAME ": " fmt "\n", ##__VA_ARGS__)
53e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#define prk_alert(fmt, ...) \
54e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	pr_alert(ACPI_TEST_NAME ": " fmt "\n", ##__VA_ARGS__)
55e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#define prk_info(fmt, ...) \
56e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	pr_info(ACPI_TEST_NAME ": " fmt "\n", ##__VA_ARGS__)
576e52dbe593c870abf76eb7fab952cdae738ffb52mridge
58e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_failure(acpi_status status, const char *name)
596e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
60e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (ACPI_FAILURE(status)) {
61e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		ACPI_EXCEPTION((AE_INFO, status, name));
62e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 1;
63e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return 0;
656e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
666e52dbe593c870abf76eb7fab952cdae738ffb52mridge
67e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/* points to the string of the last found object _STR */
68e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic char *str_obj_result;
696e52dbe593c870abf76eb7fab952cdae738ffb52mridge
70e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/* sysfs device path of the last found device */
71e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic char *sysfs_path;
72d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge
73e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/* first found device with _CRS */
74e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic acpi_handle res_handle;
75d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge
76e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic acpi_status get_str_object(acpi_handle handle)
776e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
78e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	int res;
79354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	acpi_status status;
80e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_handle temp = 0;
81e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	union acpi_object *str_obj;
82e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	char *buf = NULL;
8390619d17f707e000c81a8aa6844b5e75474d89absubrata_modak
84e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
856e52dbe593c870abf76eb7fab952cdae738ffb52mridge
86e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_get_handle(handle, "_STR", &temp);
876e52dbe593c870abf76eb7fab952cdae738ffb52mridge
88e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (ACPI_SUCCESS(status) &&
89e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	    !acpi_evaluate_object(handle, "_STR", NULL, &buffer)) {
906e52dbe593c870abf76eb7fab952cdae738ffb52mridge
91e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		str_obj = buffer.pointer;
926e52dbe593c870abf76eb7fab952cdae738ffb52mridge
93e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		buf = kmalloc(str_obj->buffer.length / 2, GFP_KERNEL);
94e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (!buf) {
95e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			kfree(str_obj);
96e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			return AE_NO_MEMORY;
97e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		}
986e52dbe593c870abf76eb7fab952cdae738ffb52mridge
99e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		res = utf16s_to_utf8s((wchar_t *)str_obj->buffer.pointer,
100e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			str_obj->buffer.length, UTF16_LITTLE_ENDIAN, buf,
101e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			str_obj->buffer.length / 2);
1026e52dbe593c870abf76eb7fab952cdae738ffb52mridge
103e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		buf[res] = '\0';
1046e52dbe593c870abf76eb7fab952cdae738ffb52mridge
105e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		kfree(str_obj_result);
106e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		str_obj_result = buf;
107e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		kfree(str_obj);
108e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
1096e52dbe593c870abf76eb7fab952cdae738ffb52mridge
110e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return status;
111e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
112d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge
113e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic void get_crs_object(acpi_handle handle)
114e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
115e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
116e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_handle temp;
117e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (!res_handle) {
118e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_get_handle(handle, METHOD_NAME__CRS, &temp);
119e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (ACPI_SUCCESS(status))
120e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			res_handle = handle;
121e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
122e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
123d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge
124e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic void get_sysfs_path(acpi_handle handle)
125e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
126e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
127e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct acpi_device *device;
1286e52dbe593c870abf76eb7fab952cdae738ffb52mridge
129e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	kfree(sysfs_path);
130e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	sysfs_path = NULL;
1316e52dbe593c870abf76eb7fab952cdae738ffb52mridge
132e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_bus_get_device(handle, &device);
133e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (ACPI_SUCCESS(status))
134e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		sysfs_path = kobject_get_path(&device->dev.kobj, GFP_KERNEL);
135e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
1366e52dbe593c870abf76eb7fab952cdae738ffb52mridge
137e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/* acpi handle of the last visited device */
138e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic acpi_handle start_parent;
1396e52dbe593c870abf76eb7fab952cdae738ffb52mridge
140e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_traverse(acpi_handle parent, acpi_handle child)
141e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
142e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	static char indent[64];
143e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	const char * const ind_end = indent + 63;
144e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	static const char *ind = ind_end;
145e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
146e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct acpi_device_info *dev_info;
147e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_handle new_child;
1486e52dbe593c870abf76eb7fab952cdae738ffb52mridge
149e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (!indent[0])
150e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		memset(indent, 0x20, 63);
1516e52dbe593c870abf76eb7fab952cdae738ffb52mridge
152e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	while (parent) {
153e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_get_next_object(ACPI_TYPE_DEVICE,
154e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			parent, child, &new_child);
1556e52dbe593c870abf76eb7fab952cdae738ffb52mridge
156e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (ACPI_FAILURE(status)) {
157e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ind += 4;
1586e52dbe593c870abf76eb7fab952cdae738ffb52mridge
159e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			child = parent;
160e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			status = acpi_get_parent(child, &parent);
1616e52dbe593c870abf76eb7fab952cdae738ffb52mridge
162e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			/* no more devices */
163e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			if (ACPI_FAILURE(status)) {
164e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev				start_parent = 0;
165e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev				kfree(str_obj_result);
166e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev				str_obj_result = NULL;
167e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev				return 0;
168e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			}
169e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			continue;
170e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		}
1716e52dbe593c870abf76eb7fab952cdae738ffb52mridge
172e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_get_object_info(new_child, &dev_info);
173e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (acpi_failure(status, "acpi_object_info failed"))
174e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			return 1;
175e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
176e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		get_sysfs_path(new_child);
177e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
178e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		get_crs_object(new_child);
179e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
180e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (ind < indent)
181e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ind = indent;
182e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		else if (ind > ind_end)
183e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ind = ind_end;
184e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
185e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		/*
186e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		 * if we find _STR object we will stop here
187e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		 * and save last visited child
188e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		 */
189e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (ACPI_SUCCESS(get_str_object(new_child))) {
190e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			prk_info("%s%4.4s: has '_STR' '%s' path '%s'",
191e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev				ind, (char *)&dev_info->name, str_obj_result,
192e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev				(sysfs_path) ? sysfs_path : "no path");
193e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ind -= 4;
194e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			start_parent = new_child;
195e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			kfree(dev_info);
196e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			return 0;
197e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		}
198e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_info("%s%4.4s: path '%s'", ind, (char *)&dev_info->name,
199e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			(sysfs_path) ? sysfs_path : "no path");
200d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge
201e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		ind -= 4;
202e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		parent = new_child;
203e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		child = 0;
204e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		kfree(dev_info);
205e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
206d9300c4abebcbc7975fee059e8f8f178cd8b19a1mridge
207e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return 0;
208e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
2096e52dbe593c870abf76eb7fab952cdae738ffb52mridge
210e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_traverse_from_root(void)
211e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
212e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
213e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct acpi_device_info *dev_info;
214e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_handle parent = 0, child = 0;
215e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
216e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (!start_parent) {
217e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_get_handle(NULL, ACPI_NS_ROOT_PATH, &parent);
218e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (acpi_failure(status, "acpi_get_handle"))
219e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			return 1;
220e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_get_object_info(parent, &dev_info);
221e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (acpi_failure(status, "acpi_object_info failed"))
222e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			return 1;
223e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_info("start from %4.4s", (char *)&dev_info->name);
224e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	} else {
225e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		/* continue with the last visited child */
226e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		parent = start_parent;
227e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
2286e52dbe593c870abf76eb7fab952cdae738ffb52mridge
229e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return acpi_traverse(parent, child);
230e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
2316e52dbe593c870abf76eb7fab952cdae738ffb52mridge
232e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/* first found device with _STR */
233e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic acpi_handle dev_handle;
234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
235e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_init(void)
236e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
237e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
238e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_handle parent_handle;
239354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
240e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct acpi_device_info *dev_info;
241354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
242e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_get_handle ");
243e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_get_handle(NULL, "\\_SB", &parent_handle);
244e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (acpi_failure(status, "acpi_get_handle"))
245e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 1;
2466e52dbe593c870abf76eb7fab952cdae738ffb52mridge
247e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	/* get first device on SYS bus, it will be used in other tests */
248e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	while (acpi_get_next_object(ACPI_TYPE_DEVICE,
249e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		parent_handle, 0, &dev_handle) == 0) {
250e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		parent_handle = dev_handle;
251e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
2526e52dbe593c870abf76eb7fab952cdae738ffb52mridge
253e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_get_object_info(dev_handle, &dev_info);
254e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (acpi_failure(status, "acpi_object_info failed"))
255e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 1;
2566e52dbe593c870abf76eb7fab952cdae738ffb52mridge
257e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("ACPI object name %4.4s, type %d", (char *)&dev_info->name,
258e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		dev_info->type);
259e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	kfree(dev_info);
260354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
261e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_get_parent ");
262e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_get_parent(dev_handle, &parent_handle);
263e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return acpi_failure(status, "acpi_get_parent failed");
264e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
265354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
266e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/*
267e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * acpi_bus_notify
268e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * ---------------
269e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev * Callback for all 'system-level' device notifications (values 0x00-0x7F).
270e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev */
271e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
272e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
273e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("Register ACPI Bus Notify callback function");
274e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
275354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
276e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_test_notify_handler(void)
277e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
278e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
2796e52dbe593c870abf76eb7fab952cdae738ffb52mridge
280e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_install_notify_handler");
2816e52dbe593c870abf76eb7fab952cdae738ffb52mridge
282e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_install_notify_handler(dev_handle,
283e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		ACPI_SYSTEM_NOTIFY, &acpi_bus_notify, NULL);
28490619d17f707e000c81a8aa6844b5e75474d89absubrata_modak
285e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (ACPI_SUCCESS(status)) {
286e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_alert("TEST -- acpi_remove_notify_handler");
287e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_remove_notify_handler(dev_handle,
288e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ACPI_SYSTEM_NOTIFY, &acpi_bus_notify);
289e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return acpi_failure(status, "acpi_remove_notify_handler");
290e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	} else if (status != AE_ALREADY_EXISTS) {
291e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return acpi_failure(status, "acpi_install_notify_handler");
292e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
2936e52dbe593c870abf76eb7fab952cdae738ffb52mridge
294e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return 0;
295e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
296e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
297e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic u32 ltp_test_power_button_ev_handler(void *context)
298e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
299e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("ltp_test_power_button_ev_handler");
300e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return 1;
301e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
3026e52dbe593c870abf76eb7fab952cdae738ffb52mridge
303e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic u32 ltp_test_sleep_button_ev_handler(void *context)
304e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
305e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("ltp_test_sleep_button_ev_handler");
306e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return 1;
307e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
308e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
309e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_test_event_handler(void)
310e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
311e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	int err = 0;
312e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
3136e52dbe593c870abf76eb7fab952cdae738ffb52mridge
314e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_install_fixed_event_handler");
315e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
316e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		ltp_test_power_button_ev_handler, NULL);
317e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
318e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (ACPI_SUCCESS(status)) {
319e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_alert("TEST -- acpi_remove_fixed_event_handler");
320e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_remove_fixed_event_handler(
321e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ACPI_EVENT_POWER_BUTTON,
322e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ltp_test_power_button_ev_handler);
323e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		err = acpi_failure(status, "remove fixed event handler");
324e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	} else if (status != AE_ALREADY_EXISTS) {
325e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		err = acpi_failure(status, "install fixed event handler");
326e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
327354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
328e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_install_fixed_event_handler");
329e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
330e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		ltp_test_sleep_button_ev_handler, NULL);
331e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
332e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (ACPI_SUCCESS(status)) {
333e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_alert("TEST -- acpi_remove_fixed_event_handler");
334e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_remove_fixed_event_handler(
335e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ACPI_EVENT_RTC,
336e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			ltp_test_sleep_button_ev_handler);
337e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		err |= acpi_failure(status, "remove fixed event handler");
338e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	} else if (status != AE_ALREADY_EXISTS) {
339e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		err |= acpi_failure(status, "install fixed event handler");
340e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
341354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
342e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return err;
343e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
344354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
345e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#ifndef ACPI_EC_UDELAY_GLK
346e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
34790619d17f707e000c81a8aa6844b5e75474d89absubrata_modak#endif
3486e52dbe593c870abf76eb7fab952cdae738ffb52mridge
349e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_global_lock(void)
350e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
351e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
352e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	u32 global_lock = 0;
3536e52dbe593c870abf76eb7fab952cdae738ffb52mridge
354e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_acquire_global_lock ");
355e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &global_lock);
356e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (acpi_failure(status, "acpi_acquire_global_lock"))
357e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 1;
3586e52dbe593c870abf76eb7fab952cdae738ffb52mridge
359e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_release_global_lock ");
360e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_release_global_lock(global_lock);
361e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return acpi_failure(status, "acpi_release_global_lock");
362e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
3636e52dbe593c870abf76eb7fab952cdae738ffb52mridge
364e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_test_bus(void)
365e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
366e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	int state = 0;
367e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
368e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_handle bus_handle;
369e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct acpi_device *device;
3706e52dbe593c870abf76eb7fab952cdae738ffb52mridge
371e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_get_handle(NULL, "\\_SB", &bus_handle);
372e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (acpi_failure(status, "acpi_get_handle"))
373e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 1;
3746e52dbe593c870abf76eb7fab952cdae738ffb52mridge
375e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_bus_get_device");
376e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_bus_get_device(bus_handle, &device);
377e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (acpi_failure(status, "acpi_bus_get_device"))
378e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 1;
3796e52dbe593c870abf76eb7fab952cdae738ffb52mridge
380e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_bus_update_power ");
381e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_bus_update_power(device->handle, &state);
382e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (acpi_failure(status, "error reading power state"))
383e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 1;
384e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
385e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_info("acpi bus power state is %d", state);
386e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return 0;
387e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
388e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
389e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic acpi_status acpi_ec_io_ports(struct acpi_resource *resource,
390e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	void *context)
391e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
392e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return 0;
393e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
3946e52dbe593c870abf76eb7fab952cdae738ffb52mridge
395e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_test_resources(void)
396e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
397e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	int err = 0;
398e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
399e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
4006e52dbe593c870abf76eb7fab952cdae738ffb52mridge
401e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	/* skip if we don't find device with _CRC */
402e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (res_handle == 0)
403e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 0;
4046e52dbe593c870abf76eb7fab952cdae738ffb52mridge
405e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_get_current_resources");
406e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_get_current_resources(res_handle, &buffer);
407e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	err = acpi_failure(status, "failed get_current_resources");
4086e52dbe593c870abf76eb7fab952cdae738ffb52mridge
409e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#ifdef ACPI_FUTURE_USAGE
410e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_get_possible_resources");
411e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_get_possible_resources(res_handle, &buffer);
412e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	err |= acpi_failure(status, "get_possible_resources");
413e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev#endif
4146e52dbe593c870abf76eb7fab952cdae738ffb52mridge
415e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_walk_resources ");
416e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_walk_resources(res_handle, METHOD_NAME__CRS,
417e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		acpi_ec_io_ports, NULL);
418e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	err |= acpi_failure(status, "Failed walk_resources");
4196e52dbe593c870abf76eb7fab952cdae738ffb52mridge
420e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return err;
421e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
4226e52dbe593c870abf76eb7fab952cdae738ffb52mridge
423e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_sleep_test(void)
424e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
425e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	int err = 0;
426e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
427e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	u32 i;
428e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	u8 type_a, type_b;
429e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_get_sleep_type_data ");
430e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
431e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	for (i = 0; i < ACPI_S_STATE_COUNT; ++i) {
432e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
433e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (ACPI_SUCCESS(status)) {
434e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			prk_info("get_sleep_type_data S%d a:%d b:%d",
435e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev				i, type_a, type_b);
436e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		} else if (status != AE_NOT_FOUND) {
437e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			err |= 1;
438354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
439e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
4406e52dbe593c870abf76eb7fab952cdae738ffb52mridge
441e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return err;
442e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
443e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
444e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_test_register(void)
445e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
446e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	int i, err = 0;
447e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	u32 val;
448e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
4496e52dbe593c870abf76eb7fab952cdae738ffb52mridge
450e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_read_bit_register");
451e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	/*
452e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	 * ACPICA: Remove obsolete Flags parameter.
453e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	 * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;
454e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	 * a=commitdiff;h=d8c71b6d3b21cf21ad775e1cf6da95bf87bd5ad4
455e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	 *
456e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	 * ACPICA: Rename ACPI bit register access functions
457e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	 * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
458e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	 * commit/?id=50ffba1bd3120b069617455545bc27bcf3cf7579
459e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	 */
460e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	for (i = 0; i < ACPI_NUM_BITREG; ++i) {
461e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		status = acpi_read_bit_register(i, &val);
462e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		err |= acpi_failure(status, "acpi_read_bit_register");
463e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		if (ACPI_SUCCESS(status))
464e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev			prk_alert("get register: %02x val: %04x", i, val);
465354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
4666e52dbe593c870abf76eb7fab952cdae738ffb52mridge
467e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return err;
4686e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
4696e52dbe593c870abf76eb7fab952cdae738ffb52mridge
470354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic acpi_status ltp_get_dev_callback(acpi_handle obj, u32 depth,
471e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	void *context, void **ret)
4726e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
4736e52dbe593c870abf76eb7fab952cdae738ffb52mridge	char *name = context;
4746e52dbe593c870abf76eb7fab952cdae738ffb52mridge	char fullname[20];
4756e52dbe593c870abf76eb7fab952cdae738ffb52mridge
4766e52dbe593c870abf76eb7fab952cdae738ffb52mridge	/*
4776e52dbe593c870abf76eb7fab952cdae738ffb52mridge	 * Only SBA shows up in ACPI namespace, so its CSR space
4786e52dbe593c870abf76eb7fab952cdae738ffb52mridge	 * includes both SBA and IOC.  Make SBA and IOC show up
4796e52dbe593c870abf76eb7fab952cdae738ffb52mridge	 * separately in PCI space.
4806e52dbe593c870abf76eb7fab952cdae738ffb52mridge	 */
4816e52dbe593c870abf76eb7fab952cdae738ffb52mridge	sprintf(fullname, "%s SBA", name);
482e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_info("get_dev_callback SBA name %s", fullname);
4836e52dbe593c870abf76eb7fab952cdae738ffb52mridge	sprintf(fullname, "%s IOC", name);
484e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_info("get_dev_callback IOC name %s", fullname);
4856e52dbe593c870abf76eb7fab952cdae738ffb52mridge
4866e52dbe593c870abf76eb7fab952cdae738ffb52mridge	return 0;
4876e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
4886e52dbe593c870abf76eb7fab952cdae738ffb52mridge
489e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int acpi_test_dev_callback(void)
4906e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
491e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	acpi_status status;
492e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_alert("TEST -- acpi_get_devices ");
493e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	status = acpi_get_devices(NULL, ltp_get_dev_callback, "LTP0001", NULL);
494e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return acpi_failure(status, "acpi_get_devices");
495e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev}
4966e52dbe593c870abf76eb7fab952cdae738ffb52mridge
497e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int current_test_case;
498e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic int test_result;
4996e52dbe593c870abf76eb7fab952cdae738ffb52mridge
500e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic void device_release(struct device *dev)
501e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev{
502e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_info("device released");
5036e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
5046e52dbe593c870abf76eb7fab952cdae738ffb52mridge
505e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic struct device tdev = {
506e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	.init_name	= ACPI_TEST_NAME,
507e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	.release	= device_release,
508e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev};
509e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
510e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/* print test result to sysfs file */
511e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic ssize_t sys_result(struct device *dev,
512e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct device_attribute *attr, char *buf)
5136e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
514e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return scnprintf(buf, PAGE_SIZE, "%d\n", test_result);
5156e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
516e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic DEVICE_ATTR(result, S_IRUSR, sys_result, NULL);
5176e52dbe593c870abf76eb7fab952cdae738ffb52mridge
518e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/* print found device description */
519e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic ssize_t sys_str(struct device *dev,
520e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct device_attribute *attr, char *buf)
5216e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
522e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (str_obj_result)
523e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return scnprintf(buf, PAGE_SIZE, "%s", str_obj_result);
524e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	else
525e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 0;
5266e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
527e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic DEVICE_ATTR(str, S_IRUSR, sys_str, NULL);
5286e52dbe593c870abf76eb7fab952cdae738ffb52mridge
529e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev/* print found device's sysfs path */
530e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic ssize_t sys_path(struct device *dev,
531e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct device_attribute *attr, char *buf)
5326e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
533e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (sysfs_path)
534e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return scnprintf(buf, PAGE_SIZE, "%s", sysfs_path);
535e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	else
536e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		return 0;
5376e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
538e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic DEVICE_ATTR(path, S_IRUSR, sys_path, NULL);
53990619d17f707e000c81a8aa6844b5e75474d89absubrata_modak
540e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic ssize_t sys_tcase(struct device *dev,
541e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	struct device_attribute *attr,  const char *buf, size_t count)
5426e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
543e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	sscanf(buf, "%d", &current_test_case);
544e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_info("test-case %d", current_test_case);
545e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
546e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	switch (current_test_case) {
547e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_INIT:
548e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_init();
549e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
550e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_TRAVERSE:
551e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_traverse_from_root();
552e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
553e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_NOTIFY_HANDLER:
554e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_test_notify_handler();
555e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
556e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_EVENT_HANDLER:
557e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_test_event_handler();
558e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
559e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_GLOBAL_LOCK:
560e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_global_lock();
561e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
562e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_TEST_BUS:
563e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_test_bus();
564e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
565e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_TEST_RESOURCES:
566e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_test_resources();
567e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
568e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_SLEEP_TEST:
569e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_sleep_test();
570e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
571e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_TEST_REGISTER:
572e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_test_register();
573e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
574e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	case ACPI_TEST_DEV_CALLBACK:
575e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		test_result = acpi_test_dev_callback();
576e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	break;
577e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
5786e52dbe593c870abf76eb7fab952cdae738ffb52mridge
579e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return count;
5806e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
581e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanevstatic DEVICE_ATTR(tcase, S_IWUSR, NULL, sys_tcase);
5826e52dbe593c870abf76eb7fab952cdae738ffb52mridge
5836e52dbe593c870abf76eb7fab952cdae738ffb52mridgeint init_module(void)
5846e52dbe593c870abf76eb7fab952cdae738ffb52mridge{
585e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	int err = 0;
586e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_info("Starting module");
5876e52dbe593c870abf76eb7fab952cdae738ffb52mridge
588e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	err = device_register(&tdev);
589e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (err) {
590e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_err("Unable to register device");
591e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		goto err0;
592354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
593e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_info("device registered");
5946e52dbe593c870abf76eb7fab952cdae738ffb52mridge
595e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	err = device_create_file(&tdev, &dev_attr_result);
596e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (err) {
597e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_err("Can't create sysfs file 'result'");
598e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		goto err1;
599354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
6006e52dbe593c870abf76eb7fab952cdae738ffb52mridge
601e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	err = device_create_file(&tdev, &dev_attr_str);
602e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (err) {
603e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_err("Can't create sysfs file 'str'");
604e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		goto err2;
605e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
6066e52dbe593c870abf76eb7fab952cdae738ffb52mridge
607e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	err = device_create_file(&tdev, &dev_attr_tcase);
608e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (err) {
609e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_err(": Can't create sysfs file 'tc'");
610e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		goto err3;
611e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
6126e52dbe593c870abf76eb7fab952cdae738ffb52mridge
613e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	err = device_create_file(&tdev, &dev_attr_path);
614e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	if (err) {
615e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		prk_err(": Can't create sysfs file 'path'");
616e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev		goto err4;
617e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	}
6186e52dbe593c870abf76eb7fab952cdae738ffb52mridge
619354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return 0;
620e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev
621e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodaneverr4:
622e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_remove_file(&tdev, &dev_attr_tcase);
623e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodaneverr3:
624e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_remove_file(&tdev, &dev_attr_str);
625e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodaneverr2:
626e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_remove_file(&tdev, &dev_attr_result);
627e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodaneverr1:
628e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_unregister(&tdev);
629e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodaneverr0:
630e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	return err;
6316e52dbe593c870abf76eb7fab952cdae738ffb52mridge}
6326e52dbe593c870abf76eb7fab952cdae738ffb52mridge
6334bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modakvoid cleanup_module(void)
6344bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak{
635e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	prk_info("Unloading module\n");
6366e52dbe593c870abf76eb7fab952cdae738ffb52mridge
637e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	kfree(str_obj_result);
638e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	kfree(sysfs_path);
6396e52dbe593c870abf76eb7fab952cdae738ffb52mridge
640e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_remove_file(&tdev, &dev_attr_result);
641e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_remove_file(&tdev, &dev_attr_str);
642e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_remove_file(&tdev, &dev_attr_tcase);
643e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_remove_file(&tdev, &dev_attr_path);
644e23db9881f12a4cdbbb9a97d21130d1543a4ba48Alexey Kodanev	device_unregister(&tdev);
645ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
646