113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/* sfi_acpi.c Simple Firmware Interface - ACPI extensions */
213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/*
413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  This file is provided under a dual BSD/GPLv2 license.  When using or
613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  redistributing this file, you may do so under either license.
713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  GPL LICENSE SUMMARY
913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
1013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  Copyright(c) 2009 Intel Corporation. All rights reserved.
1113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
1213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  This program is free software; you can redistribute it and/or modify
1313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  it under the terms of version 2 of the GNU General Public License as
1413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  published by the Free Software Foundation.
1513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
1613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  This program is distributed in the hope that it will be useful, but
1713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  WITHOUT ANY WARRANTY; without even the implied warranty of
1813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  General Public License for more details.
2013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
2113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  You should have received a copy of the GNU General Public License
2213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  along with this program; if not, write to the Free Software
2313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
2413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  The full GNU General Public License is included in this distribution
2513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  in the file called LICENSE.GPL.
2613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
2713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  BSD LICENSE
2813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
2913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  Copyright(c) 2009 Intel Corporation. All rights reserved.
3013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
3113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  Redistribution and use in source and binary forms, with or without
3213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  modification, are permitted provided that the following conditions
3313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  are met:
3413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
3513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang    * Redistributions of source code must retain the above copyright
3613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang      notice, this list of conditions and the following disclaimer.
3713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang    * Redistributions in binary form must reproduce the above copyright
3813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang      notice, this list of conditions and the following disclaimer in
3913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang      the documentation and/or other materials provided with the
4013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang      distribution.
4113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang    * Neither the name of Intel Corporation nor the names of its
4213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang      contributors may be used to endorse or promote products derived
4313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang      from this software without specific prior written permission.
4413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
4513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
4713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
4813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
4913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
5113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
5513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
5713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang*/
5813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
5913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#define KMSG_COMPONENT "SFI"
6013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
6113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
6213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#include <linux/kernel.h>
6313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#include <acpi/acpi.h>
6413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
6513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#include <linux/sfi.h>
6613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#include "sfi_core.h"
6713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
6813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/*
6913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * SFI can access ACPI-defined tables via an optional ACPI XSDT.
7013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang *
7113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * This allows re-use, and avoids re-definition, of standard tables.
7213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * For example, the "MCFG" table is defined by PCI, reserved by ACPI,
7313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * and is expected to be present many SFI-only systems.
7413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang */
7513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
7613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic struct acpi_table_xsdt *xsdt_va __read_mostly;
7713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
7813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#define XSDT_GET_NUM_ENTRIES(ptable, entry_type) \
7913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	((ptable->header.length - sizeof(struct acpi_table_header)) / \
8013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	(sizeof(entry_type)))
8113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
8213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic inline struct sfi_table_header *acpi_to_sfi_th(
8313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang				struct acpi_table_header *th)
8413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{
8513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	return (struct sfi_table_header *)th;
8613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang}
8713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
8813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic inline struct acpi_table_header *sfi_to_acpi_th(
8913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang				struct sfi_table_header *th)
9013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{
9113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	return (struct acpi_table_header *)th;
9213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang}
9313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
9413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/*
9513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * sfi_acpi_parse_xsdt()
9613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang *
9713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * Parse the ACPI XSDT for later access by sfi_acpi_table_parse().
9813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang */
9913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic int __init sfi_acpi_parse_xsdt(struct sfi_table_header *th)
10013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{
10113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	struct sfi_table_key key = SFI_ANY_KEY;
10213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	int tbl_cnt, i;
10313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	void *ret;
10413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
10513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	xsdt_va = (struct acpi_table_xsdt *)th;
10613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
10713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	for (i = 0; i < tbl_cnt; i++) {
10813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang		ret = sfi_check_table(xsdt_va->table_offset_entry[i], &key);
10913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang		if (IS_ERR(ret)) {
11013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang			disable_sfi();
11113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang			return -1;
11213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang		}
11313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	}
11413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
11513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	return 0;
11613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang}
11713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
11813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangint __init sfi_acpi_init(void)
11913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{
12013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	struct sfi_table_key xsdt_key = { .sig = SFI_SIG_XSDT };
12113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
12213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	sfi_table_parse(SFI_SIG_XSDT, NULL, NULL, sfi_acpi_parse_xsdt);
12313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
12413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	/* Only call the get_table to keep the table mapped */
12513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	xsdt_va = (struct acpi_table_xsdt *)sfi_get_table(&xsdt_key);
12613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	return 0;
12713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang}
12813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
12913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic struct acpi_table_header *sfi_acpi_get_table(struct sfi_table_key *key)
13013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{
13113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	u32 tbl_cnt, i;
13213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	void *ret;
13313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
13413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
13513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	for (i = 0; i < tbl_cnt; i++) {
13613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang		ret = sfi_check_table(xsdt_va->table_offset_entry[i], key);
13713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang		if (!IS_ERR(ret) && ret)
13813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang			return sfi_to_acpi_th(ret);
13913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	}
14013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
14113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	return NULL;
14213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang}
14313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
14413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic void sfi_acpi_put_table(struct acpi_table_header *table)
14513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{
14613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	sfi_put_table(acpi_to_sfi_th(table));
14713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang}
14813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
14913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/*
15013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * sfi_acpi_table_parse()
15113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang *
15213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * Find specified table in XSDT, run handler on it and return its return value
15313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang */
15413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangint sfi_acpi_table_parse(char *signature, char *oem_id, char *oem_table_id,
15513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang			int(*handler)(struct acpi_table_header *))
15613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{
15713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	struct acpi_table_header *table = NULL;
15813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	struct sfi_table_key key;
15913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	int ret = 0;
16013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
16113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	if (sfi_disabled)
16213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang		return -1;
16313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
16413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	key.sig = signature;
16513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	key.oem_id = oem_id;
16613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	key.oem_table_id = oem_table_id;
16713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
16813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	table = sfi_acpi_get_table(&key);
16913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	if (!table)
17013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang		return -EINVAL;
17113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang
17213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	ret = handler(table);
17313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	sfi_acpi_put_table(table);
17413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang	return ret;
17513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang}
176dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
177dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tangstatic ssize_t sfi_acpi_table_show(struct file *filp, struct kobject *kobj,
178dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang			       struct bin_attribute *bin_attr, char *buf,
179dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang			       loff_t offset, size_t count)
180dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang{
181dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	struct sfi_table_attr *tbl_attr =
182dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	    container_of(bin_attr, struct sfi_table_attr, attr);
183dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	struct acpi_table_header *th = NULL;
184dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	struct sfi_table_key key;
185dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	ssize_t cnt;
186dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
187dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	key.sig = tbl_attr->name;
188dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	key.oem_id = NULL;
189dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	key.oem_table_id = NULL;
190dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
191dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	th = sfi_acpi_get_table(&key);
192dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	if (!th)
193dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang		return 0;
194dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
195dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	cnt =  memory_read_from_buffer(buf, count, &offset,
196dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang					th, th->length);
197dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	sfi_acpi_put_table(th);
198dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
199dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	return cnt;
200dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang}
201dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
202dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
203dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tangvoid __init sfi_acpi_sysfs_init(void)
204dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang{
205dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	u32 tbl_cnt, i;
206dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	struct sfi_table_attr *tbl_attr;
207dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
208dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
209dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	for (i = 0; i < tbl_cnt; i++) {
210dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang		tbl_attr =
211dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang			sfi_sysfs_install_table(xsdt_va->table_offset_entry[i]);
212dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang		tbl_attr->attr.read = sfi_acpi_table_show;
213dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	}
214dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang
215dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang	return;
216dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang}
217