blob: b30a74de19bd13c03dc0d75fd0bdb7774b543a89 [file] [log] [blame]
/*
* idme.c
*
* Copyright 2013 Amazon Technologies, Inc. All Rights Reserved.
*
* The code contained herein is licensed under the GNU General Public
* License Version 2. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#define PRODUCT_FEATURES_DIR "product_features"
#define PRODUCT_FEATURE_NAME_GPS "gps"
#define PRODUCT_FEATURE_NAME_WAN "wan"
#define PRODUCT_FEATURE_STRING_GPS " "
#define PRODUCT_FEATURE_STRING_WAN " "
static int idme_proc_show(struct seq_file *seq, void *v)
{
struct property *pp = (struct property *)seq->private;
BUG_ON(!pp);
seq_write(seq, pp->value, pp->length);
return 0;
}
static int idme_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, idme_proc_show, PDE_DATA(inode));
}
static const struct file_operations idme_fops = {
.owner = THIS_MODULE,
.open = idme_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#if 0
static int proc_pfeature_wan_name_func(char *buffer, char **start, off_t off,
int count, int *eof, void *data)
{
char str[] = PRODUCT_FEATURE_STRING_WAN;
if (strlen(str) < PAGE_SIZE){
memcpy(buffer, str, strlen(str));
*eof = 1;
return strlen(str);
}
return 0;
}
#endif
bool board_has_wan(void)
{
struct device_node *ap;
int len;
ap = of_find_node_by_path("/idme/board_id");
if (ap) {
const char *boardid = of_get_property(ap, "value", &len);
if (len >= 2) {
if (boardid[0] == '0' && boardid[5] == '1')
return true;
}
}
return false;
}
static int __init idme_init(void)
{
struct proc_dir_entry *proc_idme = NULL;
struct device_node *root = NULL, *child = NULL;
struct property *pp_value = NULL;
int perm = 0;
/*static struct proc_dir_entry *proc_product_features_dir;*/
root = of_find_node_by_path("/idme");
if (!root)
return -EINVAL;
/* Create the root IDME procfs node */
proc_idme = proc_mkdir("idme", NULL);
if (!proc_idme) {
of_node_put(root);
return -ENOMEM;
}
/* Populate each IDME field */
for (child = NULL; (child = of_get_next_child(root, child)); ) {
pp_value = of_find_property(child, "value", NULL);
if (!pp_value)
continue;
if (of_property_read_u32(child, "permission", &perm))
continue;
/* These values aren't writable anyways */
perm &= ~(S_IWUGO);
proc_create_data(child->name, perm, proc_idme,
&idme_fops, pp_value);
}
of_node_put(child);
of_node_put(root);
/*proc_product_features_dir = proc_mkdir("product_features", NULL);
if (proc_product_features_dir) {
if (board_has_wan()) {
struct proc_dir_entry *proc_wan_name =
create_proc_entry(PRODUCT_FEATURE_NAME_WAN,
S_IRUGO,
proc_product_features_dir);
if (proc_wan_name != NULL) {
proc_wan_name->data = NULL;
proc_wan_name->read_proc =
proc_pfeature_wan_name_func;
proc_wan_name->write_proc = NULL;
}
}
}*/
return 0;
}
fs_initcall(idme_init);