~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/tile/kernel/sysfs.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2011 Tilera Corporation. All Rights Reserved.
 
3
 *
 
4
 *   This program is free software; you can redistribute it and/or
 
5
 *   modify it under the terms of the GNU General Public License
 
6
 *   as published by the Free Software Foundation, version 2.
 
7
 *
 
8
 *   This program is distributed in the hope that it will be useful, but
 
9
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 
11
 *   NON INFRINGEMENT.  See the GNU General Public License for
 
12
 *   more details.
 
13
 *
 
14
 * /sys entry support.
 
15
 */
 
16
 
 
17
#include <linux/sysdev.h>
 
18
#include <linux/cpu.h>
 
19
#include <linux/slab.h>
 
20
#include <linux/smp.h>
 
21
#include <hv/hypervisor.h>
 
22
 
 
23
/* Return a string queried from the hypervisor, truncated to page size. */
 
24
static ssize_t get_hv_confstr(char *page, int query)
 
25
{
 
26
        ssize_t n = hv_confstr(query, (unsigned long)page, PAGE_SIZE - 1);
 
27
        n = n < 0 ? 0 : min(n, (ssize_t)PAGE_SIZE - 1) - 1;
 
28
        if (n)
 
29
                page[n++] = '\n';
 
30
        page[n] = '\0';
 
31
        return n;
 
32
}
 
33
 
 
34
static ssize_t chip_width_show(struct sysdev_class *dev,
 
35
                               struct sysdev_class_attribute *attr,
 
36
                               char *page)
 
37
{
 
38
        return sprintf(page, "%u\n", smp_width);
 
39
}
 
40
static SYSDEV_CLASS_ATTR(chip_width, 0444, chip_width_show, NULL);
 
41
 
 
42
static ssize_t chip_height_show(struct sysdev_class *dev,
 
43
                                struct sysdev_class_attribute *attr,
 
44
                                char *page)
 
45
{
 
46
        return sprintf(page, "%u\n", smp_height);
 
47
}
 
48
static SYSDEV_CLASS_ATTR(chip_height, 0444, chip_height_show, NULL);
 
49
 
 
50
static ssize_t chip_serial_show(struct sysdev_class *dev,
 
51
                                struct sysdev_class_attribute *attr,
 
52
                                char *page)
 
53
{
 
54
        return get_hv_confstr(page, HV_CONFSTR_CHIP_SERIAL_NUM);
 
55
}
 
56
static SYSDEV_CLASS_ATTR(chip_serial, 0444, chip_serial_show, NULL);
 
57
 
 
58
static ssize_t chip_revision_show(struct sysdev_class *dev,
 
59
                                  struct sysdev_class_attribute *attr,
 
60
                                  char *page)
 
61
{
 
62
        return get_hv_confstr(page, HV_CONFSTR_CHIP_REV);
 
63
}
 
64
static SYSDEV_CLASS_ATTR(chip_revision, 0444, chip_revision_show, NULL);
 
65
 
 
66
 
 
67
static ssize_t type_show(struct sysdev_class *dev,
 
68
                            struct sysdev_class_attribute *attr,
 
69
                            char *page)
 
70
{
 
71
        return sprintf(page, "tilera\n");
 
72
}
 
73
static SYSDEV_CLASS_ATTR(type, 0444, type_show, NULL);
 
74
 
 
75
#define HV_CONF_ATTR(name, conf)                                        \
 
76
        static ssize_t name ## _show(struct sysdev_class *dev,          \
 
77
                                     struct sysdev_class_attribute *attr, \
 
78
                                     char *page)                        \
 
79
        {                                                               \
 
80
                return get_hv_confstr(page, conf);                      \
 
81
        }                                                               \
 
82
        static SYSDEV_CLASS_ATTR(name, 0444, name ## _show, NULL);
 
83
 
 
84
HV_CONF_ATTR(version,           HV_CONFSTR_HV_SW_VER)
 
85
HV_CONF_ATTR(config_version,    HV_CONFSTR_HV_CONFIG_VER)
 
86
 
 
87
HV_CONF_ATTR(board_part,        HV_CONFSTR_BOARD_PART_NUM)
 
88
HV_CONF_ATTR(board_serial,      HV_CONFSTR_BOARD_SERIAL_NUM)
 
89
HV_CONF_ATTR(board_revision,    HV_CONFSTR_BOARD_REV)
 
90
HV_CONF_ATTR(board_description, HV_CONFSTR_BOARD_DESC)
 
91
HV_CONF_ATTR(mezz_part,         HV_CONFSTR_MEZZ_PART_NUM)
 
92
HV_CONF_ATTR(mezz_serial,       HV_CONFSTR_MEZZ_SERIAL_NUM)
 
93
HV_CONF_ATTR(mezz_revision,     HV_CONFSTR_MEZZ_REV)
 
94
HV_CONF_ATTR(mezz_description,  HV_CONFSTR_MEZZ_DESC)
 
95
HV_CONF_ATTR(switch_control,    HV_CONFSTR_SWITCH_CONTROL)
 
96
 
 
97
static struct attribute *board_attrs[] = {
 
98
        &attr_board_part.attr,
 
99
        &attr_board_serial.attr,
 
100
        &attr_board_revision.attr,
 
101
        &attr_board_description.attr,
 
102
        &attr_mezz_part.attr,
 
103
        &attr_mezz_serial.attr,
 
104
        &attr_mezz_revision.attr,
 
105
        &attr_mezz_description.attr,
 
106
        &attr_switch_control.attr,
 
107
        NULL
 
108
};
 
109
 
 
110
static struct attribute_group board_attr_group = {
 
111
        .name   = "board",
 
112
        .attrs  = board_attrs,
 
113
};
 
114
 
 
115
 
 
116
static struct bin_attribute hvconfig_bin;
 
117
 
 
118
static ssize_t
 
119
hvconfig_bin_read(struct file *filp, struct kobject *kobj,
 
120
                  struct bin_attribute *bin_attr,
 
121
                  char *buf, loff_t off, size_t count)
 
122
{
 
123
        static size_t size;
 
124
 
 
125
        /* Lazily learn the true size (minus the trailing NUL). */
 
126
        if (size == 0)
 
127
                size = hv_confstr(HV_CONFSTR_HV_CONFIG, 0, 0) - 1;
 
128
 
 
129
        /* Check and adjust input parameters. */
 
130
        if (off > size)
 
131
                return -EINVAL;
 
132
        if (count > size - off)
 
133
                count = size - off;
 
134
 
 
135
        if (count) {
 
136
                /* Get a copy of the hvc and copy out the relevant portion. */
 
137
                char *hvc;
 
138
 
 
139
                size = off + count;
 
140
                hvc = kmalloc(size, GFP_KERNEL);
 
141
                if (hvc == NULL)
 
142
                        return -ENOMEM;
 
143
                hv_confstr(HV_CONFSTR_HV_CONFIG, (unsigned long)hvc, size);
 
144
                memcpy(buf, hvc + off, count);
 
145
                kfree(hvc);
 
146
        }
 
147
 
 
148
        return count;
 
149
}
 
150
 
 
151
static int __init create_sysfs_entries(void)
 
152
{
 
153
        struct sysdev_class *cls = &cpu_sysdev_class;
 
154
        int err = 0;
 
155
 
 
156
#define create_cpu_attr(name)                                           \
 
157
        if (!err)                                                       \
 
158
                err = sysfs_create_file(&cls->kset.kobj, &attr_##name.attr);
 
159
        create_cpu_attr(chip_width);
 
160
        create_cpu_attr(chip_height);
 
161
        create_cpu_attr(chip_serial);
 
162
        create_cpu_attr(chip_revision);
 
163
 
 
164
#define create_hv_attr(name)                                            \
 
165
        if (!err)                                                       \
 
166
                err = sysfs_create_file(hypervisor_kobj, &attr_##name.attr);
 
167
        create_hv_attr(type);
 
168
        create_hv_attr(version);
 
169
        create_hv_attr(config_version);
 
170
 
 
171
        if (!err)
 
172
                err = sysfs_create_group(hypervisor_kobj, &board_attr_group);
 
173
 
 
174
        if (!err) {
 
175
                sysfs_bin_attr_init(&hvconfig_bin);
 
176
                hvconfig_bin.attr.name = "hvconfig";
 
177
                hvconfig_bin.attr.mode = S_IRUGO;
 
178
                hvconfig_bin.read = hvconfig_bin_read;
 
179
                hvconfig_bin.size = PAGE_SIZE;
 
180
                err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin);
 
181
        }
 
182
 
 
183
        return err;
 
184
}
 
185
subsys_initcall(create_sysfs_entries);