/*
 * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/sysfs.h>
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>

static struct acpi_table_bgrt *bgrt_tab;
static struct kobject *bgrt_kobj;

struct bmp_header {
	u16 id;
	u32 size;
} __attribute ((packed));

static struct bmp_header bmp_header;

static ssize_t show_version(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->version);
}
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);

static ssize_t show_status(struct device *dev,
			   struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->status);
}
static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);

static ssize_t show_type(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_type);
}
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);

static ssize_t show_xoffset(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_x);
}
static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL);

static ssize_t show_yoffset(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_y);
}
static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);

static ssize_t show_image(struct file *file, struct kobject *kobj,
	       struct bin_attribute *attr, char *buf, loff_t off, size_t count)
{
	int size = attr->size;
	void __iomem *image = attr->private;

	if (off >= size) {
		count = 0;
	} else {
		if (off + count > size)
			count = size - off;

		memcpy_fromio(buf, image+off, count);
	}

	return count;
}

static struct bin_attribute image_attr = {
	.attr = {
		.name = "image",
		.mode = S_IRUGO,
	},
	.read = show_image,
};

static struct attribute *bgrt_attributes[] = {
	&dev_attr_version.attr,
	&dev_attr_status.attr,
	&dev_attr_type.attr,
	&dev_attr_xoffset.attr,
	&dev_attr_yoffset.attr,
	NULL,
};

static struct attribute_group bgrt_attribute_group = {
	.attrs = bgrt_attributes,
};

static int __init bgrt_init(void)
{
	acpi_status status;
	int ret;
	void __iomem *bgrt;

	if (acpi_disabled)
		return -ENODEV;

	status = acpi_get_table("BGRT", 0,
				(struct acpi_table_header **)&bgrt_tab);

	if (ACPI_FAILURE(status))
		return -ENODEV;

	sysfs_bin_attr_init(&image_attr);

	bgrt = ioremap(bgrt_tab->image_address, sizeof(struct bmp_header));

	if (!bgrt) {
		ret = -EINVAL;
		goto out_err;
	}

	memcpy_fromio(&bmp_header, bgrt, sizeof(bmp_header));
	image_attr.size = bmp_header.size;
	iounmap(bgrt);

	image_attr.private = ioremap(bgrt_tab->image_address, image_attr.size);

	if (!image_attr.private) {
		ret = -EINVAL;
		goto out_err;
	}


	bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
	if (!bgrt_kobj) {
		ret = -EINVAL;
		goto out_iounmap;
	}

	ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
	if (ret)
		goto out_kobject;

	ret = sysfs_create_bin_file(bgrt_kobj, &image_attr);
	if (ret)
		goto out_group;

	return 0;

out_group:
	sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
out_kobject:
	kobject_put(bgrt_kobj);
out_iounmap:
	iounmap(image_attr.private);
out_err:
	return ret;
}

static void __exit bgrt_exit(void)
{
	iounmap(image_attr.private);
	sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
	sysfs_remove_bin_file(bgrt_kobj, &image_attr);
}

module_init(bgrt_init);
module_exit(bgrt_exit);

MODULE_AUTHOR("Matthew Garrett");
MODULE_DESCRIPTION("BGRT boot graphic support");
MODULE_LICENSE("GPL");
