/*
 *  PS3 flash memory os area.
 *
 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
 *  Copyright 2006 Sony Corp.
 *
 *  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; version 2 of the License.
 *
 *  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/kernel.h>
#include <linux/io.h>
#include <linux/workqueue.h>
#include <linux/fs.h>
#include <linux/syscalls.h>

#include <asm/lmb.h>

#include "platform.h"

enum {
	OS_AREA_SEGMENT_SIZE = 0X200,
};

enum os_area_ldr_format {
	HEADER_LDR_FORMAT_RAW = 0,
	HEADER_LDR_FORMAT_GZIP = 1,
};

/**
 * struct os_area_header - os area header segment.
 * @magic_num: Always 'cell_ext_os_area'.
 * @hdr_version: Header format version number.
 * @db_area_offset: Starting segment number of other os database area.
 * @ldr_area_offset: Starting segment number of bootloader image area.
 * @ldr_format: HEADER_LDR_FORMAT flag.
 * @ldr_size: Size of bootloader image in bytes.
 *
 * Note that the docs refer to area offsets.  These are offsets in units of
 * segments from the start of the os area (top of the header).  These are
 * better thought of as segment numbers.  The os area of the os area is
 * reserved for the os image.
 */

struct os_area_header {
	u8 magic_num[16];
	u32 hdr_version;
	u32 db_area_offset;
	u32 ldr_area_offset;
	u32 _reserved_1;
	u32 ldr_format;
	u32 ldr_size;
	u32 _reserved_2[6];
};

enum os_area_boot_flag {
	PARAM_BOOT_FLAG_GAME_OS = 0,
	PARAM_BOOT_FLAG_OTHER_OS = 1,
};

enum os_area_ctrl_button {
	PARAM_CTRL_BUTTON_O_IS_YES = 0,
	PARAM_CTRL_BUTTON_X_IS_YES = 1,
};

/**
 * struct os_area_params - os area params segment.
 * @boot_flag: User preference of operating system, PARAM_BOOT_FLAG flag.
 * @num_params: Number of params in this (params) segment.
 * @rtc_diff: Difference in seconds between 1970 and the ps3 rtc value.
 * @av_multi_out: User preference of AV output, PARAM_AV_MULTI_OUT flag.
 * @ctrl_button: User preference of controller button config, PARAM_CTRL_BUTTON
 *	flag.
 * @static_ip_addr: User preference of static IP address.
 * @network_mask: User preference of static network mask.
 * @default_gateway: User preference of static default gateway.
 * @dns_primary: User preference of static primary dns server.
 * @dns_secondary: User preference of static secondary dns server.
 *
 * The ps3 rtc maintains a read-only value that approximates seconds since
 * 2000-01-01 00:00:00 UTC.
 *
 * User preference of zero for static_ip_addr means use dhcp.
 */

struct os_area_params {
	u32 boot_flag;
	u32 _reserved_1[3];
	u32 num_params;
	u32 _reserved_2[3];
	/* param 0 */
	s64 rtc_diff;
	u8 av_multi_out;
	u8 ctrl_button;
	u8 _reserved_3[6];
	/* param 1 */
	u8 static_ip_addr[4];
	u8 network_mask[4];
	u8 default_gateway[4];
	u8 _reserved_4[4];
	/* param 2 */
	u8 dns_primary[4];
	u8 dns_secondary[4];
	u8 _reserved_5[8];
};

enum {
	OS_AREA_DB_MAGIC_NUM = 0x2d64622dU,
};

/**
 * struct os_area_db - Shared flash memory database.
 * @magic_num: Always '-db-' = 0x2d64622d.
 * @version: os_area_db format version number.
 * @index_64: byte offset of the database id index for 64 bit variables.
 * @count_64: number of usable 64 bit index entries
 * @index_32: byte offset of the database id index for 32 bit variables.
 * @count_32: number of usable 32 bit index entries
 * @index_16: byte offset of the database id index for 16 bit variables.
 * @count_16: number of usable 16 bit index entries
 *
 * Flash rom storage for exclusive use by guests running in the other os lpar.
 * The current system configuration allocates 1K (two segments) for other os
 * use.
 */

struct os_area_db {
	u32 magic_num;
	u16 version;
	u16 _reserved_1;
	u16 index_64;
	u16 count_64;
	u16 index_32;
	u16 count_32;
	u16 index_16;
	u16 count_16;
	u32 _reserved_2;
	u8 _db_data[1000];
};

/**
 * enum os_area_db_owner - Data owners.
 */

enum os_area_db_owner {
	OS_AREA_DB_OWNER_ANY = -1,
	OS_AREA_DB_OWNER_NONE = 0,
	OS_AREA_DB_OWNER_PROTOTYPE = 1,
	OS_AREA_DB_OWNER_LINUX = 2,
	OS_AREA_DB_OWNER_PETITBOOT = 3,
	OS_AREA_DB_OWNER_MAX = 32,
};

enum os_area_db_key {
	OS_AREA_DB_KEY_ANY = -1,
	OS_AREA_DB_KEY_NONE = 0,
	OS_AREA_DB_KEY_RTC_DIFF = 1,
	OS_AREA_DB_KEY_VIDEO_MODE = 2,
	OS_AREA_DB_KEY_MAX = 8,
};

struct os_area_db_id {
	int owner;
	int key;
};

static const struct os_area_db_id os_area_db_id_empty = {
	.owner = OS_AREA_DB_OWNER_NONE,
	.key = OS_AREA_DB_KEY_NONE
};

static const struct os_area_db_id os_area_db_id_any = {
	.owner = OS_AREA_DB_OWNER_ANY,
	.key = OS_AREA_DB_KEY_ANY
};

static const struct os_area_db_id os_area_db_id_rtc_diff = {
	.owner = OS_AREA_DB_OWNER_LINUX,
	.key = OS_AREA_DB_KEY_RTC_DIFF
};

static const struct os_area_db_id os_area_db_id_video_mode = {
	.owner = OS_AREA_DB_OWNER_LINUX,
	.key = OS_AREA_DB_KEY_VIDEO_MODE
};

#define SECONDS_FROM_1970_TO_2000 946684800LL

/**
 * struct saved_params - Static working copies of data from the PS3 'os area'.
 *
 * The order of preference we use for the rtc_diff source:
 *  1) The database value.
 *  2) The game os value.
 *  3) The number of seconds from 1970 to 2000.
 */

struct saved_params {
	unsigned int valid;
	s64 rtc_diff;
	unsigned int av_multi_out;
} static saved_params;

static struct property property_rtc_diff = {
	.name = "linux,rtc_diff",
	.length = sizeof(saved_params.rtc_diff),
	.value = &saved_params.rtc_diff,
};

static struct property property_av_multi_out = {
	.name = "linux,av_multi_out",
	.length = sizeof(saved_params.av_multi_out),
	.value = &saved_params.av_multi_out,
};

/**
 * os_area_set_property - Add or overwrite a saved_params value to the device tree.
 *
 * Overwrites an existing property.
 */

static void os_area_set_property(struct device_node *node,
	struct property *prop)
{
	int result;
	struct property *tmp = of_find_property(node, prop->name, NULL);

	if (tmp) {
		pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name);
		prom_remove_property(node, tmp);
	}

	result = prom_add_property(node, prop);

	if (result)
		pr_debug("%s:%d prom_set_property failed\n", __func__,
			__LINE__);
}

/**
 * os_area_get_property - Get a saved_params value from the device tree.
 *
 */

static void __init os_area_get_property(struct device_node *node,
	struct property *prop)
{
	const struct property *tmp = of_find_property(node, prop->name, NULL);

	if (tmp) {
		BUG_ON(prop->length != tmp->length);
		memcpy(prop->value, tmp->value, prop->length);
	} else
		pr_debug("%s:%d not found %s\n", __func__, __LINE__,
			prop->name);
}

#define dump_header(_a) _dump_header(_a, __func__, __LINE__)
static void _dump_header(const struct os_area_header *h, const char *func,
	int line)
{
	pr_debug("%s:%d: h.magic_num:       '%s'\n", func, line,
		h->magic_num);
	pr_debug("%s:%d: h.hdr_version:     %u\n", func, line,
		h->hdr_version);
	pr_debug("%s:%d: h.db_area_offset:  %u\n", func, line,
		h->db_area_offset);
	pr_debug("%s:%d: h.ldr_area_offset: %u\n", func, line,
		h->ldr_area_offset);
	pr_debug("%s:%d: h.ldr_format:      %u\n", func, line,
		h->ldr_format);
	pr_debug("%s:%d: h.ldr_size:        %xh\n", func, line,
		h->ldr_size);
}

#define dump_params(_a) _dump_params(_a, __func__, __LINE__)
static void _dump_params(const struct os_area_params *p, const char *func,
	int line)
{
	pr_debug("%s:%d: p.boot_flag:       %u\n", func, line, p->boot_flag);
	pr_debug("%s:%d: p.num_params:      %u\n", func, line, p->num_params);
	pr_debug("%s:%d: p.rtc_diff         %ld\n", func, line, p->rtc_diff);
	pr_debug("%s:%d: p.av_multi_out     %u\n", func, line, p->av_multi_out);
	pr_debug("%s:%d: p.ctrl_button:     %u\n", func, line, p->ctrl_button);
	pr_debug("%s:%d: p.static_ip_addr:  %u.%u.%u.%u\n", func, line,
		p->static_ip_addr[0], p->static_ip_addr[1],
		p->static_ip_addr[2], p->static_ip_addr[3]);
	pr_debug("%s:%d: p.network_mask:    %u.%u.%u.%u\n", func, line,
		p->network_mask[0], p->network_mask[1],
		p->network_mask[2], p->network_mask[3]);
	pr_debug("%s:%d: p.default_gateway: %u.%u.%u.%u\n", func, line,
		p->default_gateway[0], p->default_gateway[1],
		p->default_gateway[2], p->default_gateway[3]);
	pr_debug("%s:%d: p.dns_primary:     %u.%u.%u.%u\n", func, line,
		p->dns_primary[0], p->dns_primary[1],
		p->dns_primary[2], p->dns_primary[3]);
	pr_debug("%s:%d: p.dns_secondary:   %u.%u.%u.%u\n", func, line,
		p->dns_secondary[0], p->dns_secondary[1],
		p->dns_secondary[2], p->dns_secondary[3]);
}

static int verify_header(const struct os_area_header *header)
{
	if (memcmp(header->magic_num, "cell_ext_os_area", 16)) {
		pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
		return -1;
	}

	if (header->hdr_version < 1) {
		pr_debug("%s:%d hdr_version failed\n", __func__, __LINE__);
		return -1;
	}

	if (header->db_area_offset > header->ldr_area_offset) {
		pr_debug("%s:%d offsets failed\n", __func__, __LINE__);
		return -1;
	}

	return 0;
}

static int db_verify(const struct os_area_db *db)
{
	if (db->magic_num != OS_AREA_DB_MAGIC_NUM) {
		pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
		return -1;
	}

	if (db->version != 1) {
		pr_debug("%s:%d version failed\n", __func__, __LINE__);
		return -1;
	}

	return 0;
}

struct db_index {
       uint8_t owner:5;
       uint8_t key:3;
};

struct db_iterator {
	const struct os_area_db *db;
	struct os_area_db_id match_id;
	struct db_index *idx;
	struct db_index *last_idx;
	union {
		uint64_t *value_64;
		uint32_t *value_32;
		uint16_t *value_16;
	};
};

static unsigned int db_align_up(unsigned int val, unsigned int size)
{
	return (val + (size - 1)) & (~(size - 1));
}

/**
 * db_for_each_64 - Iterator for 64 bit entries.
 *
 * A NULL value for id can be used to match all entries.
 * OS_AREA_DB_OWNER_ANY and OS_AREA_DB_KEY_ANY can be used to match all.
 */

static int db_for_each_64(const struct os_area_db *db,
	const struct os_area_db_id *match_id, struct db_iterator *i)
{
next:
	if (!i->db) {
		i->db = db;
		i->match_id = match_id ? *match_id : os_area_db_id_any;
		i->idx = (void *)db + db->index_64;
		i->last_idx = i->idx + db->count_64;
		i->value_64 = (void *)db + db->index_64
			+ db_align_up(db->count_64, 8);
	} else {
		i->idx++;
		i->value_64++;
	}

	if (i->idx >= i->last_idx) {
		pr_debug("%s:%d: reached end\n", __func__, __LINE__);
		return 0;
	}

	if (i->match_id.owner != OS_AREA_DB_OWNER_ANY
		&& i->match_id.owner != (int)i->idx->owner)
		goto next;
	if (i->match_id.key != OS_AREA_DB_KEY_ANY
		&& i->match_id.key != (int)i->idx->key)
		goto next;

	return 1;
}

static int db_delete_64(struct os_area_db *db, const struct os_area_db_id *id)
{
	struct db_iterator i;

	for (i.db = NULL; db_for_each_64(db, id, &i); ) {

		pr_debug("%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__,
			i.idx->owner, i.idx->key,
			(unsigned long long)*i.value_64);

		i.idx->owner = 0;
		i.idx->key = 0;
		*i.value_64 = 0;
	}
	return 0;
}

static int db_set_64(struct os_area_db *db, const struct os_area_db_id *id,
	uint64_t value)
{
	struct db_iterator i;

	pr_debug("%s:%d: (%d:%d) <= %llxh\n", __func__, __LINE__,
		id->owner, id->key, (unsigned long long)value);

	if (!id->owner || id->owner == OS_AREA_DB_OWNER_ANY
		|| id->key == OS_AREA_DB_KEY_ANY) {
		pr_debug("%s:%d: bad id: (%d:%d)\n", __func__,
			__LINE__, id->owner, id->key);
		return -1;
	}

	db_delete_64(db, id);

	i.db = NULL;
	if (db_for_each_64(db, &os_area_db_id_empty, &i)) {

		pr_debug("%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__,
			i.idx->owner, i.idx->key,
			(unsigned long long)*i.value_64);

		i.idx->owner = id->owner;
		i.idx->key = id->key;
		*i.value_64 = value;

		pr_debug("%s:%d: set (%d:%d) <= %llxh\n", __func__, __LINE__,
			i.idx->owner, i.idx->key,
			(unsigned long long)*i.value_64);
		return 0;
	}
	pr_debug("%s:%d: database full.\n",
		__func__, __LINE__);
	return -1;
}

static int db_get_64(const struct os_area_db *db,
	const struct os_area_db_id *id, uint64_t *value)
{
	struct db_iterator i;

	i.db = NULL;
	if (db_for_each_64(db, id, &i)) {
		*value = *i.value_64;
		pr_debug("%s:%d: found %lld\n", __func__, __LINE__,
				(long long int)*i.value_64);
		return 0;
	}
	pr_debug("%s:%d: not found\n", __func__, __LINE__);
	return -1;
}

static int db_get_rtc_diff(const struct os_area_db *db, int64_t *rtc_diff)
{
	return db_get_64(db, &os_area_db_id_rtc_diff, (uint64_t*)rtc_diff);
}

#define dump_db(a) _dump_db(a, __func__, __LINE__)
static void _dump_db(const struct os_area_db *db, const char *func,
	int line)
{
	pr_debug("%s:%d: db.magic_num:      '%s'\n", func, line,
		(const char*)&db->magic_num);
	pr_debug("%s:%d: db.version:         %u\n", func, line,
		db->version);
	pr_debug("%s:%d: db.index_64:        %u\n", func, line,
		db->index_64);
	pr_debug("%s:%d: db.count_64:        %u\n", func, line,
		db->count_64);
	pr_debug("%s:%d: db.index_32:        %u\n", func, line,
		db->index_32);
	pr_debug("%s:%d: db.count_32:        %u\n", func, line,
		db->count_32);
	pr_debug("%s:%d: db.index_16:        %u\n", func, line,
		db->index_16);
	pr_debug("%s:%d: db.count_16:        %u\n", func, line,
		db->count_16);
}

static void os_area_db_init(struct os_area_db *db)
{
	enum {
		HEADER_SIZE = offsetof(struct os_area_db, _db_data),
		INDEX_64_COUNT = 64,
		VALUES_64_COUNT = 57,
		INDEX_32_COUNT = 64,
		VALUES_32_COUNT = 57,
		INDEX_16_COUNT = 64,
		VALUES_16_COUNT = 57,
	};

	memset(db, 0, sizeof(struct os_area_db));

	db->magic_num = OS_AREA_DB_MAGIC_NUM;
	db->version = 1;
	db->index_64 = HEADER_SIZE;
	db->count_64 = VALUES_64_COUNT;
	db->index_32 = HEADER_SIZE
			+ INDEX_64_COUNT * sizeof(struct db_index)
			+ VALUES_64_COUNT * sizeof(u64);
	db->count_32 = VALUES_32_COUNT;
	db->index_16 = HEADER_SIZE
			+ INDEX_64_COUNT * sizeof(struct db_index)
			+ VALUES_64_COUNT * sizeof(u64)
			+ INDEX_32_COUNT * sizeof(struct db_index)
			+ VALUES_32_COUNT * sizeof(u32);
	db->count_16 = VALUES_16_COUNT;

	/* Rules to check db layout. */

	BUILD_BUG_ON(sizeof(struct db_index) != 1);
	BUILD_BUG_ON(sizeof(struct os_area_db) != 2 * OS_AREA_SEGMENT_SIZE);
	BUILD_BUG_ON(INDEX_64_COUNT & 0x7);
	BUILD_BUG_ON(VALUES_64_COUNT > INDEX_64_COUNT);
	BUILD_BUG_ON(INDEX_32_COUNT & 0x7);
	BUILD_BUG_ON(VALUES_32_COUNT > INDEX_32_COUNT);
	BUILD_BUG_ON(INDEX_16_COUNT & 0x7);
	BUILD_BUG_ON(VALUES_16_COUNT > INDEX_16_COUNT);
	BUILD_BUG_ON(HEADER_SIZE
			+ INDEX_64_COUNT * sizeof(struct db_index)
			+ VALUES_64_COUNT * sizeof(u64)
			+ INDEX_32_COUNT * sizeof(struct db_index)
			+ VALUES_32_COUNT * sizeof(u32)
			+ INDEX_16_COUNT * sizeof(struct db_index)
			+ VALUES_16_COUNT * sizeof(u16)
			> sizeof(struct os_area_db));
}

/**
 * update_flash_db - Helper for os_area_queue_work_handler.
 *
 */

static void update_flash_db(void)
{
	int result;
	int file;
	off_t offset;
	ssize_t count;
	static const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE;
	const struct os_area_header *header;
	struct os_area_db* db;

	/* Read in header and db from flash. */

	file = sys_open("/dev/ps3flash", O_RDWR, 0);

	if (file < 0) {
		pr_debug("%s:%d sys_open failed\n", __func__, __LINE__);
		goto fail_open;
	}

	header = kmalloc(buf_len, GFP_KERNEL);

	if (!header) {
		pr_debug("%s:%d kmalloc failed\n", __func__, __LINE__);
		goto fail_malloc;
	}

	offset = sys_lseek(file, 0, SEEK_SET);

	if (offset != 0) {
		pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
		goto fail_header_seek;
	}

	count = sys_read(file, (char __user *)header, buf_len);

	result = count < OS_AREA_SEGMENT_SIZE || verify_header(header)
		|| count < header->db_area_offset * OS_AREA_SEGMENT_SIZE;

	if (result) {
		pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
		dump_header(header);
		goto fail_header;
	}

	/* Now got a good db offset and some maybe good db data. */

	db = (void*)header + header->db_area_offset * OS_AREA_SEGMENT_SIZE;

	result = db_verify(db);

	if (result) {
		printk(KERN_NOTICE "%s:%d: Verify of flash database failed, "
			"formatting.\n", __func__, __LINE__);
		dump_db(db);
		os_area_db_init(db);
	}

	/* Now got good db data. */

	db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff);

	offset = sys_lseek(file, header->db_area_offset * OS_AREA_SEGMENT_SIZE,
		SEEK_SET);

	if (offset != header->db_area_offset * OS_AREA_SEGMENT_SIZE) {
		pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
		goto fail_db_seek;
	}

	count = sys_write(file, (const char __user *)db,
		sizeof(struct os_area_db));

	if (count < sizeof(struct os_area_db)) {
		pr_debug("%s:%d sys_write failed\n", __func__, __LINE__);
	}

fail_db_seek:
fail_header:
fail_header_seek:
	kfree(header);
fail_malloc:
	sys_close(file);
fail_open:
	return;
}

/**
 * os_area_queue_work_handler - Asynchronous write handler.
 *
 * An asynchronous write for flash memory and the device tree.  Do not
 * call directly, use os_area_queue_work().
 */

static void os_area_queue_work_handler(struct work_struct *work)
{
	struct device_node *node;

	pr_debug(" -> %s:%d\n", __func__, __LINE__);

	node = of_find_node_by_path("/");

	if (node) {
		os_area_set_property(node, &property_rtc_diff);
		of_node_put(node);
	} else
		pr_debug("%s:%d of_find_node_by_path failed\n",
			__func__, __LINE__);

#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
	update_flash_db();
#else
	printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n",
		__func__, __LINE__);
#endif
	pr_debug(" <- %s:%d\n", __func__, __LINE__);
}

static void os_area_queue_work(void)
{
	static DECLARE_WORK(q, os_area_queue_work_handler);

	wmb();
	schedule_work(&q);
}

/**
 * ps3_os_area_save_params - Copy data from os area mirror to @saved_params.
 *
 * For the convenience of the guest the HV makes a copy of the os area in
 * flash to a high address in the boot memory region and then puts that RAM
 * address and the byte count into the repository for retrieval by the guest.
 * We copy the data we want into a static variable and allow the memory setup
 * by the HV to be claimed by the lmb manager.
 *
 * The os area mirror will not be available to a second stage kernel, and
 * the header verify will fail.  In this case, the saved_params values will
 * be set from flash memory or the passed in device tree in ps3_os_area_init().
 */

void __init ps3_os_area_save_params(void)
{
	int result;
	u64 lpar_addr;
	unsigned int size;
	struct os_area_header *header;
	struct os_area_params *params;
	struct os_area_db *db;

	pr_debug(" -> %s:%d\n", __func__, __LINE__);

	result = ps3_repository_read_boot_dat_info(&lpar_addr, &size);

	if (result) {
		pr_debug("%s:%d ps3_repository_read_boot_dat_info failed\n",
			__func__, __LINE__);
		return;
	}

	header = (struct os_area_header *)__va(lpar_addr);
	params = (struct os_area_params *)__va(lpar_addr
		+ OS_AREA_SEGMENT_SIZE);

	result = verify_header(header);

	if (result) {
		/* Second stage kernels exit here. */
		pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
		dump_header(header);
		return;
	}

	db = (struct os_area_db *)__va(lpar_addr
		+ header->db_area_offset * OS_AREA_SEGMENT_SIZE);

	dump_header(header);
	dump_params(params);
	dump_db(db);

	result = db_verify(db) || db_get_rtc_diff(db, &saved_params.rtc_diff);
	if (result)
		saved_params.rtc_diff = params->rtc_diff ? params->rtc_diff
			: SECONDS_FROM_1970_TO_2000;
	saved_params.av_multi_out = params->av_multi_out;
	saved_params.valid = 1;

	memset(header, 0, sizeof(*header));

	pr_debug(" <- %s:%d\n", __func__, __LINE__);
}

/**
 * ps3_os_area_init - Setup os area device tree properties as needed.
 */

void __init ps3_os_area_init(void)
{
	struct device_node *node;

	pr_debug(" -> %s:%d\n", __func__, __LINE__);

	node = of_find_node_by_path("/");

	if (!saved_params.valid && node) {
		/* Second stage kernels should have a dt entry. */
		os_area_get_property(node, &property_rtc_diff);
		os_area_get_property(node, &property_av_multi_out);
	}

	if(!saved_params.rtc_diff)
		saved_params.rtc_diff = SECONDS_FROM_1970_TO_2000;

	if (node) {
		os_area_set_property(node, &property_rtc_diff);
		os_area_set_property(node, &property_av_multi_out);
		of_node_put(node);
	} else
		pr_debug("%s:%d of_find_node_by_path failed\n",
			__func__, __LINE__);

	pr_debug(" <- %s:%d\n", __func__, __LINE__);
}

/**
 * ps3_os_area_get_rtc_diff - Returns the rtc diff value.
 */

u64 ps3_os_area_get_rtc_diff(void)
{
	return saved_params.rtc_diff;
}

/**
 * ps3_os_area_set_rtc_diff - Set the rtc diff value.
 *
 * An asynchronous write is needed to support writing updates from
 * the timer interrupt context.
 */

void ps3_os_area_set_rtc_diff(u64 rtc_diff)
{
	if (saved_params.rtc_diff != rtc_diff) {
		saved_params.rtc_diff = rtc_diff;
		os_area_queue_work();
	}
}

/**
 * ps3_os_area_get_av_multi_out - Returns the default video mode.
 */

enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void)
{
    return saved_params.av_multi_out;
}
EXPORT_SYMBOL_GPL(ps3_os_area_get_av_multi_out);
