/*
 *  acpi_system.c - ACPI System Driver ($Revision: 63 $)
 *
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <asm/uaccess.h>

#include <acpi/acpi_drivers.h>

#define _COMPONENT		ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("acpi_system")
#define ACPI_SYSTEM_CLASS		"system"
#define ACPI_SYSTEM_DRIVER_NAME		"ACPI System Driver"
#define ACPI_SYSTEM_DEVICE_NAME		"System"
#define ACPI_SYSTEM_FILE_INFO		"info"
#define ACPI_SYSTEM_FILE_EVENT		"event"
#define ACPI_SYSTEM_FILE_DSDT		"dsdt"
#define ACPI_SYSTEM_FILE_FADT		"fadt"
extern struct fadt_descriptor acpi_fadt;

/* --------------------------------------------------------------------------
                              FS Interface (/proc)
   -------------------------------------------------------------------------- */

static int acpi_system_read_info(struct seq_file *seq, void *offset)
{
	ACPI_FUNCTION_TRACE("acpi_system_read_info");

	seq_printf(seq, "version:                 %x\n", ACPI_CA_VERSION);
	return_VALUE(0);
}

static int acpi_system_info_open_fs(struct inode *inode, struct file *file)
{
	return single_open(file, acpi_system_read_info, PDE(inode)->data);
}

static struct file_operations acpi_system_info_ops = {
	.open = acpi_system_info_open_fs,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
				     loff_t *);

static struct file_operations acpi_system_dsdt_ops = {
	.read = acpi_system_read_dsdt,
};

static ssize_t
acpi_system_read_dsdt(struct file *file,
		      char __user * buffer, size_t count, loff_t * ppos)
{
	acpi_status status = AE_OK;
	struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
	ssize_t res;

	ACPI_FUNCTION_TRACE("acpi_system_read_dsdt");

	status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt);
	if (ACPI_FAILURE(status))
		return_VALUE(-ENODEV);

	res = simple_read_from_buffer(buffer, count, ppos,
				      dsdt.pointer, dsdt.length);
	acpi_os_free(dsdt.pointer);

	return_VALUE(res);
}

static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
				     loff_t *);

static struct file_operations acpi_system_fadt_ops = {
	.read = acpi_system_read_fadt,
};

static ssize_t
acpi_system_read_fadt(struct file *file,
		      char __user * buffer, size_t count, loff_t * ppos)
{
	acpi_status status = AE_OK;
	struct acpi_buffer fadt = { ACPI_ALLOCATE_BUFFER, NULL };
	ssize_t res;

	ACPI_FUNCTION_TRACE("acpi_system_read_fadt");

	status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt);
	if (ACPI_FAILURE(status))
		return_VALUE(-ENODEV);

	res = simple_read_from_buffer(buffer, count, ppos,
				      fadt.pointer, fadt.length);
	acpi_os_free(fadt.pointer);

	return_VALUE(res);
}

static int __init acpi_system_init(void)
{
	struct proc_dir_entry *entry;
	int error = 0;
	char *name;

	ACPI_FUNCTION_TRACE("acpi_system_init");

	if (acpi_disabled)
		return_VALUE(0);

	/* 'info' [R] */
	name = ACPI_SYSTEM_FILE_INFO;
	entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
	if (!entry)
		goto Error;
	else {
		entry->proc_fops = &acpi_system_info_ops;
	}

	/* 'dsdt' [R] */
	name = ACPI_SYSTEM_FILE_DSDT;
	entry = create_proc_entry(name, S_IRUSR, acpi_root_dir);
	if (entry)
		entry->proc_fops = &acpi_system_dsdt_ops;
	else
		goto Error;

	/* 'fadt' [R] */
	name = ACPI_SYSTEM_FILE_FADT;
	entry = create_proc_entry(name, S_IRUSR, acpi_root_dir);
	if (entry)
		entry->proc_fops = &acpi_system_fadt_ops;
	else
		goto Error;

      Done:
	return_VALUE(error);

      Error:
	ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
			  "Unable to create '%s' proc fs entry\n", name));

	remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
	remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
	remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);

	error = -EFAULT;
	goto Done;
}

subsys_initcall(acpi_system_init);
