linux/drivers/acpi/bgrt.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8
   9#include <linux/kernel.h>
  10#include <linux/module.h>
  11#include <linux/init.h>
  12#include <linux/device.h>
  13#include <linux/sysfs.h>
  14#include <linux/io.h>
  15#include <acpi/acpi.h>
  16#include <acpi/acpi_bus.h>
  17
  18static struct acpi_table_bgrt *bgrt_tab;
  19static struct kobject *bgrt_kobj;
  20
  21struct bmp_header {
  22        u16 id;
  23        u32 size;
  24} __attribute ((packed));
  25
  26static struct bmp_header bmp_header;
  27
  28static ssize_t show_version(struct device *dev,
  29                            struct device_attribute *attr, char *buf)
  30{
  31        return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->version);
  32}
  33static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
  34
  35static ssize_t show_status(struct device *dev,
  36                           struct device_attribute *attr, char *buf)
  37{
  38        return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->status);
  39}
  40static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
  41
  42static ssize_t show_type(struct device *dev,
  43                         struct device_attribute *attr, char *buf)
  44{
  45        return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_type);
  46}
  47static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
  48
  49static ssize_t show_xoffset(struct device *dev,
  50                            struct device_attribute *attr, char *buf)
  51{
  52        return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_x);
  53}
  54static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL);
  55
  56static ssize_t show_yoffset(struct device *dev,
  57                            struct device_attribute *attr, char *buf)
  58{
  59        return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_y);
  60}
  61static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);
  62
  63static ssize_t show_image(struct file *file, struct kobject *kobj,
  64               struct bin_attribute *attr, char *buf, loff_t off, size_t count)
  65{
  66        int size = attr->size;
  67        void __iomem *image = attr->private;
  68
  69        if (off >= size) {
  70                count = 0;
  71        } else {
  72                if (off + count > size)
  73                        count = size - off;
  74
  75                memcpy_fromio(buf, image+off, count);
  76        }
  77
  78        return count;
  79}
  80
  81static struct bin_attribute image_attr = {
  82        .attr = {
  83                .name = "image",
  84                .mode = S_IRUGO,
  85        },
  86        .read = show_image,
  87};
  88
  89static struct attribute *bgrt_attributes[] = {
  90        &dev_attr_version.attr,
  91        &dev_attr_status.attr,
  92        &dev_attr_type.attr,
  93        &dev_attr_xoffset.attr,
  94        &dev_attr_yoffset.attr,
  95        NULL,
  96};
  97
  98static struct attribute_group bgrt_attribute_group = {
  99        .attrs = bgrt_attributes,
 100};
 101
 102static int __init bgrt_init(void)
 103{
 104        acpi_status status;
 105        int ret;
 106        void __iomem *bgrt;
 107
 108        if (acpi_disabled)
 109                return -ENODEV;
 110
 111        status = acpi_get_table("BGRT", 0,
 112                                (struct acpi_table_header **)&bgrt_tab);
 113
 114        if (ACPI_FAILURE(status))
 115                return -ENODEV;
 116
 117        sysfs_bin_attr_init(&image_attr);
 118
 119        bgrt = ioremap(bgrt_tab->image_address, sizeof(struct bmp_header));
 120
 121        if (!bgrt) {
 122                ret = -EINVAL;
 123                goto out_err;
 124        }
 125
 126        memcpy_fromio(&bmp_header, bgrt, sizeof(bmp_header));
 127        image_attr.size = bmp_header.size;
 128        iounmap(bgrt);
 129
 130        image_attr.private = ioremap(bgrt_tab->image_address, image_attr.size);
 131
 132        if (!image_attr.private) {
 133                ret = -EINVAL;
 134                goto out_err;
 135        }
 136
 137
 138        bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
 139        if (!bgrt_kobj) {
 140                ret = -EINVAL;
 141                goto out_iounmap;
 142        }
 143
 144        ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
 145        if (ret)
 146                goto out_kobject;
 147
 148        ret = sysfs_create_bin_file(bgrt_kobj, &image_attr);
 149        if (ret)
 150                goto out_group;
 151
 152        return 0;
 153
 154out_group:
 155        sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
 156out_kobject:
 157        kobject_put(bgrt_kobj);
 158out_iounmap:
 159        iounmap(image_attr.private);
 160out_err:
 161        return ret;
 162}
 163
 164static void __exit bgrt_exit(void)
 165{
 166        iounmap(image_attr.private);
 167        sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
 168        sysfs_remove_bin_file(bgrt_kobj, &image_attr);
 169}
 170
 171module_init(bgrt_init);
 172module_exit(bgrt_exit);
 173
 174MODULE_AUTHOR("Matthew Garrett");
 175MODULE_DESCRIPTION("BGRT boot graphic support");
 176MODULE_LICENSE("GPL");
 177
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.